]> git.ipfire.org Git - network.git/commitdiff
ports: VLAN: Implement choosing a protocol
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jun 2023 13:17:36 +0000 (13:17 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jun 2023 13:17:36 +0000 (13:17 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/networkd/port-vlan.c
src/networkd/port-vlan.h

index ac4a5b4a3b1f2817ddbf72cd7d83856e918b6c35..6e13ba9a2b76722628e8506d5c9e442f420c594e 100644 (file)
@@ -18,6 +18,8 @@
 #                                                                             #
 #############################################################################*/
 
+#include <linux/if_link.h>
+
 #include <systemd/sd-netlink.h>
 
 #include "config.h"
 #include "port-vlan.h"
 #include "string.h"
 
+const struct nw_string_table nw_port_vlan_proto[] = {
+       { NW_VLAN_PROTO_8021Q,  "802.1Q" },
+       { NW_VLAN_PROTO_8021ad, "802.1ad" },
+       { -1, NULL },
+};
+
+NW_STRING_TABLE_LOOKUP(nw_port_vlan_proto_t, nw_port_vlan_proto)
+
 static int nw_port_vlan_config_read(nw_port* port) {
        int r;
 
@@ -39,6 +49,14 @@ static int nw_port_vlan_config_read(nw_port* port) {
                        return r;
        }
 
+       // VLAN Protocol
+       const char* proto = nw_config_get(port->config, "VLAN_PROTO");
+       if (proto) {
+               r = nw_port_set_vlan_proto(port, nw_port_vlan_proto_from_string(proto));
+               if (r)
+                       return r;
+       }
+
        // Parent Port
        const char* parent = nw_config_get(port->config, "VLAN_PARENT");
        if (parent) {
@@ -58,6 +76,12 @@ static int nw_port_vlan_config_write(nw_port* port) {
        if (r)
                return r;
 
+       // VLAN Protocol
+       r = nw_config_set(port->config, "VLAN_PROTO",
+               nw_port_vlan_proto_to_string(port->vlan.proto));
+       if (r)
+               return r;
+
        // Parent Port
        r = nw_config_set(port->config, "VLAN_PARENT",
                (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name);
@@ -75,6 +99,11 @@ static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) {
        if (r < 0)
                return r;
 
+       // Set VLAN protocol
+       r = sd_netlink_message_append_u16(m, IFLA_VLAN_PROTOCOL, htobe16(port->vlan.proto));
+       if (r < 0)
+               return r;
+
        return 0;
 }
 
@@ -87,6 +116,12 @@ static int nw_port_vlan_to_json(nw_port* port, struct json_object* o) {
        if (r < 0)
                goto ERROR;
 
+       // Add the VLAN Protocol
+       r = json_object_add_string(o, "VLANProtocol",
+                       nw_port_vlan_proto_to_string(port->vlan.proto));
+       if (r < 0)
+               goto ERROR;
+
        // Fetch the parent
        parent = nw_port_get_parent_port(port);
        if (parent) {
@@ -155,6 +190,20 @@ int nw_port_set_vlan_id(nw_port* port, int id) {
        return 0;
 }
 
+int nw_port_set_vlan_proto(nw_port* port, const nw_port_vlan_proto_t proto) {
+       switch (proto) {
+               case NW_VLAN_PROTO_8021Q:
+               case NW_VLAN_PROTO_8021ad:
+                       port->vlan.proto = proto;
+                       break;
+
+               default:
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
 nw_port* nw_port_get_vlan_parent(nw_port* port) {
        int r;
 
index cffc1787558cca8d76d6a5875fe923df7150a910..17d31340a41febaca078290369307af3ebb811df 100644 (file)
 #ifndef NETWORKD_PORT_VLAN_H
 #define NETWORKD_PORT_VLAN_H
 
+#include <arpa/inet.h>
+#include <linux/if_ether.h>
+
 #include "port.h"
 
+typedef enum nw_port_vlan_proto {
+       NW_VLAN_PROTO_8021Q  = ETH_P_8021Q,
+       NW_VLAN_PROTO_8021ad = ETH_P_8021AD,
+} nw_port_vlan_proto_t;
+
 struct nw_port_vlan {
        nw_port* parent;
 
        // The VLAN ID
        int id;
 
+       // Protocol
+       nw_port_vlan_proto_t proto;
+
        // If the parent has not been read from the configuration we will
        // save the name and try to find it later.
        char __parent_name[IF_NAMESIZE];
@@ -40,6 +51,9 @@ extern const nw_port_info_t nw_port_info_vlan;
 int nw_port_get_vlan_id(nw_port* port);
 int nw_port_set_vlan_id(nw_port* port, int id);
 
+// Protocol
+int nw_port_set_vlan_proto(nw_port* port, const nw_port_vlan_proto_t proto);
+
 // Parent Port
 nw_port* nw_port_get_vlan_parent(nw_port* port);
 int nw_port_set_vlan_parent(nw_port* port, nw_port* parent);