diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 67ccc66dd8e..e17c1e3fbef 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -1457,6 +1457,15 @@ + + DynamicTransmitLoadBalancing= + + Takes a boolean. Specifies if dynamic shuffling of flows is enabled. Applies only + for balance-tlb mode. Defaults to unset. + + + + MinLinks= diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 64ab386df3f..cd5cdcc6e55 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -227,6 +227,7 @@ static const NLType rtnl_link_info_data_bond_types[] = { [IFLA_BOND_AD_ACTOR_SYS_PRIO] = { .type = NETLINK_TYPE_U16 }, [IFLA_BOND_AD_USER_PORT_KEY] = { .type = NETLINK_TYPE_U16 }, [IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NETLINK_TYPE_U8 }, }; static const NLType rtnl_link_info_data_iptun_types[] = { diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c index 70d314bc794..550a7f89145 100644 --- a/src/network/netdev/bond.c +++ b/src/network/netdev/bond.c @@ -307,6 +307,12 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %m"); + if (b->tlb_dynamic_lb >= 0) { + r = sd_netlink_message_append_u8(m, IFLA_BOND_TLB_DYNAMIC_LB, b->tlb_dynamic_lb); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_TLB_DYNAMIC_LB attribute: %m"); + } + if (b->arp_interval > 0) { if (b->n_arp_ip_targets > 0) { @@ -534,6 +540,7 @@ static void bond_init(NetDev *netdev) { b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID; b->all_slaves_active = false; + b->tlb_dynamic_lb = -1; b->resend_igmp = RESEND_IGMP_DEFAULT; b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT; diff --git a/src/network/netdev/bond.h b/src/network/netdev/bond.h index 99ef25d0d34..31b922b0327 100644 --- a/src/network/netdev/bond.h +++ b/src/network/netdev/bond.h @@ -99,6 +99,8 @@ typedef struct Bond { BondArpAllTargets arp_all_targets; BondPrimaryReselect primary_reselect; + int tlb_dynamic_lb; + bool all_slaves_active; unsigned resend_igmp; diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index fbc7a59e9e8..39b26b842c5 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -141,6 +141,7 @@ Bond.ResendIGMP, config_parse_unsigned, 0, Bond.PacketsPerSlave, config_parse_unsigned, 0, offsetof(Bond, packets_per_slave) Bond.GratuitousARP, config_parse_unsigned, 0, offsetof(Bond, num_grat_arp) Bond.AllSlavesActive, config_parse_unsigned, 0, offsetof(Bond, all_slaves_active) +Bond.DynamicTransmitLoadBalancing, config_parse_tristate, 0, offsetof(Bond, tlb_dynamic_lb) Bond.MinLinks, config_parse_unsigned, 0, offsetof(Bond, min_links) Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon) Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay) diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev index 5a8d41eb683..cd7c3aadedb 100644 --- a/test/fuzz/fuzz-netdev-parser/directives.netdev +++ b/test/fuzz/fuzz-netdev-parser/directives.netdev @@ -129,6 +129,7 @@ MinLinks= LACPTransmitRate= ARPIntervalSec= AllSlavesActive= +DynamicTransmitLoadBalancing= [FooOverUDP] Protocol= Port= diff --git a/test/test-network/conf/25-bond-balanced-tlb.netdev b/test/test-network/conf/25-bond-balanced-tlb.netdev new file mode 100644 index 00000000000..439ddf28096 --- /dev/null +++ b/test/test-network/conf/25-bond-balanced-tlb.netdev @@ -0,0 +1,7 @@ +[NetDev] +Name=bond99 +Kind=bond + +[Bond] +Mode=balance-tlb +DynamicTransmitLoadBalancing=true diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 65cc43e8b6b..19572be1514 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -213,6 +213,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): '21-vlan.network', '25-6rd-tunnel.netdev', '25-bond.netdev', + '25-bond-balanced-tlb.netdev', '25-bridge.netdev', '25-erspan-tunnel.netdev', '25-geneve.netdev', @@ -300,6 +301,15 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): self.assertEqual('811', self.read_link_attr('bond99', 'bonding', 'ad_user_port_key')) self.assertEqual('00:11:22:33:44:55', self.read_link_attr('bond99', 'bonding', 'ad_actor_system')) + def test_bond_balanced_tlb(self): + self.copy_unit_to_networkd_unit_path('25-bond-balanced-tlb.netdev') + self.start_networkd() + + self.assertTrue(self.link_exits('bond99')) + + self.assertEqual('balance-tlb 5', self.read_link_attr('bond99', 'bonding', 'mode')) + self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'tlb_dynamic_lb')) + def test_vlan(self): self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network') self.start_networkd()