diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 126accaca9b..edb15cf4aa5 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -4624,6 +4624,15 @@ ServerAddress=192.168.0.1/24
+
+ Locked=
+
+ 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.
+
+
+
+
diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c
index a85b4b16c3c..c0e820486db 100644
--- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c
+++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c
@@ -485,6 +485,7 @@ static const struct NLAPolicy rtnl_bridge_port_policies[] = {
[IFLA_BRPORT_MRP_IN_OPEN] = BUILD_POLICY(U8),
[IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = BUILD_POLICY(U32),
[IFLA_BRPORT_MCAST_EHT_HOSTS_CNT] = BUILD_POLICY(U32),
+ [IFLA_BRPORT_LOCKED] = 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 83ef927b8b5..30f71480298 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -383,6 +383,7 @@ Bridge.ProxyARP, config_parse_tristate,
Bridge.ProxyARPWiFi, config_parse_tristate, 0, offsetof(Network, bridge_proxy_arp_wifi)
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)
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 7de0027aae9..82f39e2f800 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -456,6 +456,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.bridge_proxy_arp_wifi = -1,
.priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
.multicast_router = _MULTICAST_ROUTER_INVALID,
+ .bridge_locked = -1,
.bridge_vlan_pvid = BRIDGE_VLAN_KEEP_PVID,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index b61914ea7aa..95407279e33 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -297,6 +297,7 @@ struct Network {
uint32_t cost;
uint16_t priority;
MulticastRouter multicast_router;
+ int bridge_locked;
/* Bridge VLAN */
uint16_t bridge_vlan_pvid;
diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c
index 467fadb3eab..b973ffea98e 100644
--- a/src/network/networkd-setlink.c
+++ b/src/network/networkd-setlink.c
@@ -320,6 +320,12 @@ static int link_configure_fill_message(
return r;
}
+ if (link->network->bridge_locked >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_LOCKED, link->network->bridge_locked);
+ 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 42b197eeef1..6eb955dc4bc 100644
--- a/test/test-network/conf/26-bridge-slave-interface-2.network
+++ b/test/test-network/conf/26-bridge-slave-interface-2.network
@@ -10,3 +10,4 @@ Bridge=bridge99
[Bridge]
Priority=0
+Locked=true
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index 533945ed0d7..2d1309da289 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -5790,6 +5790,7 @@ 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)
def test_bridge_property(self):
copy_network_unit('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',