From: Jonas Gorski Date: Fri, 24 Jan 2025 12:15:06 +0000 (+0100) Subject: network: bridge: add support for IFLA_BRPORT_MAB X-Git-Tag: v258-rc1~1460^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F36150%2Fhead;p=thirdparty%2Fsystemd.git network: bridge: add support for IFLA_BRPORT_MAB Since linux commit a35ec8e38cdd1766f29924ca391a01de20163931 ("bridge: Add MAC Authentication Bypass (MAB) support"), included since v6.2, it is possible to enable MAC Authentication Bypass for bridge ports. In this mode the locked port learns again, but the learned fdb entries are locked, allowing user space to unlock hosts based seen MAC addresses. This requires learning to be enabled on the port, and link-local learning disabled for the bridge. Add support to systemd-network for setting the new attribute for bridge ports. --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index edb15cf4aa5..f2777e640fa 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -4630,6 +4630,15 @@ ServerAddress=192.168.0.1/24 Takes a boolean. Configures whether the port is "locked" and does not allow traffic forwarded until fully authenticated, e.g. via 802.1x. When unset, the kernel's default will be used. + + + MACAuthenticationBypass= + + Takes a boolean. Configures whether a locked port has "MAC Authentication Bypass" enabled and + creates newly learned fdb entries in a "locked" state. User space can authenticate these entries by + clearing the locked flag. Requires Learning to be enabled. When unset, the kernel's default will be + used. + diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index c0e820486db..187d9b6756a 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -486,6 +486,7 @@ static const struct NLAPolicy rtnl_bridge_port_policies[] = { [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = BUILD_POLICY(U32), [IFLA_BRPORT_MCAST_EHT_HOSTS_CNT] = BUILD_POLICY(U32), [IFLA_BRPORT_LOCKED] = BUILD_POLICY(U8), + [IFLA_BRPORT_MAB] = BUILD_POLICY(U8), }; static const NLAPolicySetUnionElement rtnl_link_info_slave_data_policy_set_union_elements[] = { diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 30f71480298..bdbb3ad2c8a 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -384,6 +384,7 @@ Bridge.ProxyARPWiFi, config_parse_tristate, Bridge.Priority, config_parse_bridge_port_priority, 0, offsetof(Network, priority) Bridge.MulticastRouter, config_parse_multicast_router, 0, offsetof(Network, multicast_router) Bridge.Locked, config_parse_tristate, 0, offsetof(Network, bridge_locked) +Bridge.MACAuthenticationBypass, config_parse_tristate, 0, offsetof(Network, bridge_mac_authentication_bypass) BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0 BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 BridgeFDB.Destination, config_parse_fdb_destination, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 82f39e2f800..080e184ae14 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -457,6 +457,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID, .multicast_router = _MULTICAST_ROUTER_INVALID, .bridge_locked = -1, + .bridge_mac_authentication_bypass = -1, .bridge_vlan_pvid = BRIDGE_VLAN_KEEP_PVID, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 95407279e33..cec5f98d5bb 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -298,6 +298,7 @@ struct Network { uint16_t priority; MulticastRouter multicast_router; int bridge_locked; + int bridge_mac_authentication_bypass; /* Bridge VLAN */ uint16_t bridge_vlan_pvid; diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c index b973ffea98e..2f4a6c6e035 100644 --- a/src/network/networkd-setlink.c +++ b/src/network/networkd-setlink.c @@ -326,6 +326,12 @@ static int link_configure_fill_message( return r; } + if (link->network->bridge_mac_authentication_bypass >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MAB, link->network->bridge_mac_authentication_bypass); + if (r < 0) + return r; + } + r = sd_netlink_message_close_container(req); if (r < 0) return r; diff --git a/test/test-network/conf/26-bridge-slave-interface-2.network b/test/test-network/conf/26-bridge-slave-interface-2.network index 6eb955dc4bc..c76f17201f3 100644 --- a/test/test-network/conf/26-bridge-slave-interface-2.network +++ b/test/test-network/conf/26-bridge-slave-interface-2.network @@ -11,3 +11,4 @@ Bridge=bridge99 [Bridge] Priority=0 Locked=true +MACAuthenticationBypass=true diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 2d1309da289..d073e007af5 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -5791,6 +5791,8 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities): print(output) self.check_bridge_port_attr('bridge99', 'test1', 'priority', '0') self.assertIn('locked on', output) + if ' mab ' in output: # This is new in kernel and iproute2 v6.2 + self.assertIn('mab on', output) def test_bridge_property(self): copy_network_unit('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',