From d872e169c7d38b741b0fd01796202a19357d622c Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 7 Jun 2023 13:17:36 +0000 Subject: [PATCH] ports: VLAN: Implement choosing a protocol Signed-off-by: Michael Tremer --- src/networkd/port-vlan.c | 49 ++++++++++++++++++++++++++++++++++++++++ src/networkd/port-vlan.h | 14 ++++++++++++ 2 files changed, 63 insertions(+) diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c index ac4a5b4a..6e13ba9a 100644 --- a/src/networkd/port-vlan.c +++ b/src/networkd/port-vlan.c @@ -18,6 +18,8 @@ # # #############################################################################*/ +#include + #include #include "config.h" @@ -28,6 +30,14 @@ #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; diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h index cffc1787..17d31340 100644 --- a/src/networkd/port-vlan.h +++ b/src/networkd/port-vlan.h @@ -21,14 +21,25 @@ #ifndef NETWORKD_PORT_VLAN_H #define NETWORKD_PORT_VLAN_H +#include +#include + #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); -- 2.39.2