From 97f27f8a1690cdf32f34edd43121eeda6452676a Mon Sep 17 00:00:00 2001 From: Santa Wiryaman Date: Mon, 3 May 2021 18:48:26 -0400 Subject: [PATCH] Add support for `isolated` parameter Add the "Isolated" parameter in the *.network file, e.g., [Bridge] Isolated=true|false When the Isolated parameter is true, traffic coming out of this port will only be forward to other ports whose Isolated parameter is false. When Isolated is not specified, the port uses the kernel default setting (false). The "Isolated" parameter was introduced in Linux 4.19. See man bridge(8) for more details. But even though the kernel and bridge/iproute2 recognize the "Isolated" parameter, systemd-networkd did not have a way to set it. --- man/systemd.network.xml | 9 +++++++++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 1 + src/network/networkd-network.h | 1 + src/network/networkd-setlink.c | 6 ++++++ .../26-bridge-slave-interface-1.network | 1 + test/fuzz/fuzz-network-parser/directives.network | 1 + test/fuzz/fuzz-unit-file/directives-all.service | 1 + test/networkd-test.py | 2 ++ .../conf/26-bridge-slave-interface-1.network | 1 + test/test-network/systemd-networkd-tests.py | 1 + 11 files changed, 25 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 74f416cf396..52d017bb783 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2960,6 +2960,15 @@ Token=prefixstable:2002:da8:1:: receiving port. When unset, the kernel's default will be used. + + Isolated= + + Takes a boolean. Configures whether this port is isolated or not. Within a bridge, + isolated ports can only communicate with non-isolated ports. When set to true, this port can only + communicate with other ports whose Isolated setting is false. When set to false, this port + can communicate with any other ports. When unset, the kernel's default will be used. + + UseBPDU= diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 08e3f13f5a5..8b19ce006b6 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -308,6 +308,7 @@ DHCPServerStaticLease.MACAddress, config_parse_dhcp_static_lease_hwad Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost) Bridge.UseBPDU, config_parse_tristate, 0, offsetof(Network, use_bpdu) Bridge.HairPin, config_parse_tristate, 0, offsetof(Network, hairpin) +Bridge.Isolated, config_parse_tristate, 0, offsetof(Network, isolated) Bridge.FastLeave, config_parse_tristate, 0, offsetof(Network, fast_leave) Bridge.AllowPortToBeRoot, config_parse_tristate, 0, offsetof(Network, allow_port_to_be_root) Bridge.UnicastFlood, config_parse_tristate, 0, offsetof(Network, unicast_flood) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index edcd68d6167..96806524be8 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -437,6 +437,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .use_bpdu = -1, .hairpin = -1, + .isolated = -1, .fast_leave = -1, .allow_port_to_be_root = -1, .unicast_flood = -1, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index f7eb37aceda..f933379ac1c 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -244,6 +244,7 @@ struct Network { /* Bridge Support */ int use_bpdu; int hairpin; + int isolated; int fast_leave; int allow_port_to_be_root; int unicast_flood; diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c index 3fbc910aa2b..4292f8976f8 100644 --- a/src/network/networkd-setlink.c +++ b/src/network/networkd-setlink.c @@ -303,6 +303,12 @@ static int link_configure_fill_message( return r; } + if (link->network->isolated >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_ISOLATED, link->network->isolated); + if (r < 0) + return r; + } + if (link->network->fast_leave >= 0) { r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave); if (r < 0) diff --git a/test/fuzz/fuzz-network-parser/26-bridge-slave-interface-1.network b/test/fuzz/fuzz-network-parser/26-bridge-slave-interface-1.network index 81b372fb6d0..854ac5f44cf 100644 --- a/test/fuzz/fuzz-network-parser/26-bridge-slave-interface-1.network +++ b/test/fuzz/fuzz-network-parser/26-bridge-slave-interface-1.network @@ -7,6 +7,7 @@ Bridge=bridge99 [Bridge] Cost=400 HairPin = true +Isolated = true FastLeave = true UnicastFlood = true MulticastToUnicast = true diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 48f9ad6fba9..10a40d26649 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -2,6 +2,7 @@ Cost= UseBPDU= HairPin= +Isolated= UnicastFlood= FastLeave= Priority= diff --git a/test/fuzz/fuzz-unit-file/directives-all.service b/test/fuzz/fuzz-unit-file/directives-all.service index 186557f8a54..699a9c5ae48 100644 --- a/test/fuzz/fuzz-unit-file/directives-all.service +++ b/test/fuzz/fuzz-unit-file/directives-all.service @@ -451,6 +451,7 @@ Group= GroupForwardMask= GroupPolicyExtension= HairPin= +Isolated= MulticastToUnicast= HelloTimeSec= HomeAddress= diff --git a/test/networkd-test.py b/test/networkd-test.py index 60622077a22..b3ef7bc5dad 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -273,6 +273,7 @@ Priority=0 [Bridge] UnicastFlood=true HairPin=true +Isolated=true UseBPDU=true FastLeave=true AllowPortToBeRoot=true @@ -286,6 +287,7 @@ Priority=23 self.assertEqual(self.read_attr('port2', 'brport/priority'), '23') self.assertEqual(self.read_attr('port2', 'brport/hairpin_mode'), '1') + self.assertEqual(self.read_attr('port2', 'brport/isolated'), '1') self.assertEqual(self.read_attr('port2', 'brport/path_cost'), '555') self.assertEqual(self.read_attr('port2', 'brport/multicast_fast_leave'), '1') self.assertEqual(self.read_attr('port2', 'brport/unicast_flood'), '1') diff --git a/test/test-network/conf/26-bridge-slave-interface-1.network b/test/test-network/conf/26-bridge-slave-interface-1.network index 07c82845659..8858cbf0008 100644 --- a/test/test-network/conf/26-bridge-slave-interface-1.network +++ b/test/test-network/conf/26-bridge-slave-interface-1.network @@ -8,6 +8,7 @@ Bridge=bridge99 [Bridge] Cost=400 HairPin = true +Isolated = true FastLeave = true UnicastFlood = true MulticastFlood = false diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 5f64933cf90..4f96bca33e8 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -3864,6 +3864,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities): print(output) self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1') + self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'isolated'), '1') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1') self.assertEqual(read_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood'), '0')