diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 0dd553adc1..b06785046d 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 bc8c180665..7983f448a1 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 f7f61699e7..cff81ff278 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 efbbd58b92..80f7a41cad 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 cc4ac2e0d1..e7f9a68162 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 9a60eb712d..7d78081504 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 81b372fb6d..1f8c5b5648 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 f43acb1f3c..d0e0bc0442 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')):