network: bridge: add support for configuring locked ports (#36150)

"Recently" (as of 5.18) the Linux kernel gained the ability of locking
bridge ports to restrict network access to authenticated hosts only.

This is implemented by disabling automated learning and dropping
incoming traffic from unknown hosts. User space is then expected to add
fdb entries for authenticated hosts. Once a fdb entry exist, traffic for
that host will be forwarded as expected.

This was later extended with "Mac Authentication Bypass", where the
locking was extended to fdb entries. In this mode the kernel adds fdb
entries again automatically, but they are locked by default.

To properly configure this, add two network options and one netdev
option:

* `LinkLocalLearning=` to prevent the kernel from creating unlocked
entries based on link-local traffic, which would bypass any
authentication. Needed when enabling learning on a locked port.
* `Locked=` to allow setting a bridge port to locked.
* `MACAuthenticationBypass=` to allow enabling Mac Authentication
 Bypass on a port. Requires learning to be enabled on the port as well
 (and consequently `LinkLocalLearning` disabled on the bridge).

An authenticator (e.g. hostapd) is still needed to do the actual
authentication, the kernel only provides the access control.
This commit is contained in:
Yu Watanabe
2025-01-29 04:16:20 +09:00
committed by GitHub
13 changed files with 70 additions and 0 deletions
+1
View File
@@ -18,3 +18,4 @@ VLANProtocol=802.1ad
STP=true
MulticastIGMPVersion=3
FDBMaxLearned=4
LinkLocalLearning=no
@@ -10,3 +10,5 @@ Bridge=bridge99
[Bridge]
Priority=0
Locked=true
MACAuthenticationBypass=true
@@ -1804,6 +1804,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'multicast_snooping')))
self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'stp_state')))
self.assertEqual(3, int(read_link_attr('bridge99', 'bridge', 'multicast_igmp_version')))
self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'no_linklocal_learn')))
output = networkctl_status('bridge99')
print(output)
@@ -5911,6 +5912,9 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
output = check_output('bridge -d link show test1')
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',