From 4df4df5b56917f4f66f708a83f4e1aa8b38ea922 Mon Sep 17 00:00:00 2001 From: Rubens Figueiredo Date: Fri, 20 Mar 2020 16:09:36 +0100 Subject: [PATCH] network: allow setting VLAN protocol on bridges Signed-off-by: Rubens Figueiredo --- man/systemd.netdev.xml | 9 ++++++ src/network/netdev/bridge.c | 7 ++++ src/network/netdev/bridge.h | 1 + src/network/netdev/netdev-gperf.gperf | 1 + src/shared/conf-parser.c | 32 +++++++++++++++++++ src/shared/conf-parser.h | 1 + .../fuzz/fuzz-netdev-parser/directives.netdev | 1 + 7 files changed, 52 insertions(+) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 6ad1dc9e73..026fae089f 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -408,6 +408,15 @@ + + VLANProtocol= + + Allows setting the protocol used for VLAN filtering. Takes + or, + , and defaults to unset and kernel's default is used. + + + STP= diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c index 6b8f994461..de492c5eeb 100644 --- a/src/network/netdev/bridge.c +++ b/src/network/netdev/bridge.c @@ -126,6 +126,12 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_FILTERING attribute: %m"); } + if (b->vlan_protocol >= 0) { + r = sd_netlink_message_append_u16(req, IFLA_BR_VLAN_PROTOCOL, b->vlan_protocol); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_PROTOCOL attribute: %m"); + } + if (b->stp >= 0) { r = sd_netlink_message_append_u32(req, IFLA_BR_STP_STATE, b->stp); if (r < 0) @@ -346,6 +352,7 @@ static void bridge_init(NetDev *n) { b->mcast_querier = -1; b->mcast_snooping = -1; b->vlan_filtering = -1; + b->vlan_protocol = -1; b->stp = -1; b->default_pvid = VLANID_INVALID; b->forward_delay = USEC_INFINITY; diff --git a/src/network/netdev/bridge.h b/src/network/netdev/bridge.h index b0a728e5a4..ed4f484c94 100644 --- a/src/network/netdev/bridge.h +++ b/src/network/netdev/bridge.h @@ -13,6 +13,7 @@ typedef struct Bridge { int mcast_querier; int mcast_snooping; int vlan_filtering; + int vlan_protocol; int stp; uint16_t priority; uint16_t group_fwd_mask; diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index 09a5f4822e..b14835c313 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -206,6 +206,7 @@ Bridge.DefaultPVID, config_parse_default_port_vlanid, Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier) Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping) Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering) +Bridge.VLANProtocol, config_parse_vlanprotocol, 0, offsetof(Bridge, vlan_protocol) Bridge.STP, config_parse_tristate, 0, offsetof(Bridge, stp) Bridge.MulticastIGMPVersion, config_parse_uint8, 0, offsetof(Bridge, igmp_version) VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table) /* deprecated */ diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 3ba33606fb..23cb3b65b6 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -1187,3 +1187,35 @@ int config_parse_permille(const char* unit, return 0; } + +int config_parse_vlanprotocol(const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + int *vlan_protocol = data; + assert(filename); + assert(lvalue); + + if (isempty(rvalue)) { + *vlan_protocol = -1; + return 0; + } + + if (STR_IN_SET(rvalue, "802.1ad", "802.1AD")) + *vlan_protocol = ETH_P_8021AD; + else if (STR_IN_SET(rvalue, "802.1q", "802.1Q")) + *vlan_protocol = ETH_P_8021Q; + else { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Failed to parse VLAN protocol value, ignoring: %s", rvalue); + return 0; + } + + return 0; +} diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 2f3cb4217d..59e74590ca 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -142,6 +142,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ifnames); CONFIG_PARSER_PROTOTYPE(config_parse_ip_port); CONFIG_PARSER_PROTOTYPE(config_parse_mtu); CONFIG_PARSER_PROTOTYPE(config_parse_rlimit); +CONFIG_PARSER_PROTOTYPE(config_parse_vlanprotocol); typedef enum Disabled { DISABLED_CONFIGURATION, diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev index e8391dab78..d69ac09f1f 100644 --- a/test/fuzz/fuzz-netdev-parser/directives.netdev +++ b/test/fuzz/fuzz-netdev-parser/directives.netdev @@ -45,6 +45,7 @@ AgeingTimeSec= Priority= GroupForwardMask= VLANFiltering= +VLANProtocol= MulticastIGMPVersion= [VRF] TableId=