From 7f15b7146019cfe4aa74db17f12e1f05bea9703b Mon Sep 17 00:00:00 2001 From: Tobias Jungel Date: Sun, 10 Mar 2019 21:25:24 +0100 Subject: [PATCH] networkd: Add bridge port capabilities This PR adds the configuration switches for multicast flooding, neighbor suppression and learning of a bridge port. --- man/systemd.network.xml | 25 +++++++++++++++++++ src/network/networkd-link.c | 18 +++++++++++++ src/network/networkd-network-gperf.gperf | 3 +++ src/network/networkd-network.c | 3 +++ src/network/networkd-network.h | 3 +++ .../fuzz-network-parser/directives.network | 3 +++ .../conf/26-bridge-slave-interface-1.network | 3 +++ test/test-network/systemd-networkd-tests.py | 4 +++ 8 files changed, 62 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 0dd553adc1c..b06785046da 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1789,6 +1789,15 @@ + + MulticastFlood= + + Takes a boolean. Controls whether the bridge should flood + traffic for which an MDB entry is missing and the destination + is unknown through this port. When unset, the kernel's default will be used. + + + MulticastToUnicast= @@ -1798,6 +1807,22 @@ + + NeighborSuppression= + + Takes a boolean. Configures whether ARP and ND neighbor suppression is enabled for + this port. When unset, the kernel's default will be used. + + + + + Learning= + + Takes a boolean. Configures whether MAC address learning is enabled for + this port. When unset, the kernel's default will be used. + + + HairPin= diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index bc8c180665f..7983f448a10 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1595,12 +1595,30 @@ static int link_set_bridge(Link *link) { return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m"); } + if (link->network->multicast_flood >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_FLOOD, link->network->multicast_flood); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_FLOOD attribute: %m"); + } + if (link->network->multicast_to_unicast >= 0) { r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_TO_UCAST, link->network->multicast_to_unicast); if (r < 0) return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_TO_UCAST attribute: %m"); } + if (link->network->neighbor_suppression >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_NEIGH_SUPPRESS, link->network->neighbor_suppression); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_NEIGH_SUPPRESS attribute: %m"); + } + + if (link->network->learning >= 0) { + r = sd_netlink_message_append_u8(req, IFLA_BRPORT_LEARNING, link->network->learning); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_LEARNING attribute: %m"); + } + if (link->network->cost != 0) { r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost); if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index f7f61699e71..cff81ff2785 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -170,7 +170,10 @@ Bridge.HairPin, config_parse_tristate, 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) +Bridge.MulticastFlood, config_parse_tristate, 0, offsetof(Network, multicast_flood) Bridge.MulticastToUnicast, config_parse_tristate, 0, offsetof(Network, multicast_to_unicast) +Bridge.NeighborSuppression, config_parse_tristate, 0, offsetof(Network, neighbor_suppression) +Bridge.Learning, config_parse_tristate, 0, offsetof(Network, learning) Bridge.Priority, config_parse_bridge_port_priority, 0, offsetof(Network, priority) BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0 BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index efbbd58b929..80f7a41cadf 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -368,7 +368,10 @@ int network_load_one(Manager *manager, const char *filename) { .fast_leave = -1, .allow_port_to_be_root = -1, .unicast_flood = -1, + .multicast_flood = -1, .multicast_to_unicast = -1, + .neighbor_suppression = -1, + .learning = -1, .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID, .lldp_mode = LLDP_MODE_ROUTERS_ONLY, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index cc4ac2e0d12..e7f9a681623 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -179,7 +179,10 @@ struct Network { int fast_leave; int allow_port_to_be_root; int unicast_flood; + int multicast_flood; int multicast_to_unicast; + int neighbor_suppression; + int learning; uint32_t cost; uint16_t priority; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 9a60eb712df..7d780815044 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -7,6 +7,9 @@ FastLeave= Priority= AllowPortToBeRoot= MulticastToUnicast= +MulticastFlood= +NeighborSuppression= +Learning= [Match] KernelVersion= Type= 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 81b372fb6d0..1f8c5b56482 100644 --- a/test/test-network/conf/26-bridge-slave-interface-1.network +++ b/test/test-network/conf/26-bridge-slave-interface-1.network @@ -9,4 +9,7 @@ Cost=400 HairPin = true FastLeave = true UnicastFlood = true +MulticastFlood = false MulticastToUnicast = true +NeighborSuppression = true +Learning = false diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index f43acb1f3ce..d0e0bc0442c 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1293,7 +1293,11 @@ class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities): self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1') self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400') self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1') + self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_flood'), '0') self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1') + if (os.path.exists('/sys/devices/virtual/net/bridge99/lower_dummy98/brport/neigh_suppress')): + self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'neigh_suppress'), '1') + self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'learning'), '0') # CONFIG_BRIDGE_IGMP_SNOOPING=y if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')): -- 2.39.2