From a08b225cf0ddddafc87bfa122cc7252c9c0c745e Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Mon, 7 Sep 2026 14:13:13 +0200 Subject: [PATCH] mxrouter: Support static (non-LACP) bonding mode --- mxrouter/mxrouterctl | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/mxrouter/mxrouterctl b/mxrouter/mxrouterctl index 28f0b539..1ef45de8 100755 --- a/mxrouter/mxrouterctl +++ b/mxrouter/mxrouterctl @@ -277,11 +277,13 @@ sub vlan { } } -our $want_bond; # { bond_device => [slave1, slave2, ...], ... } +our $want_bond; # { bond_device => { mode => 'lacp'|'static', slaves => [slave1, slave2, ...] }, ... } +our %BONDING_KERNEL_MODE = ('lacp' => '802.3ad', 'static' => 'balance-xor'); sub bonding { - my ($device, @slaves) = @_; - $want_bond->{$device} = [@slaves]; + my ($device, $mode, @slaves) = @_; + exists $BONDING_KERNEL_MODE{$mode} or die "Unknown bonding mode '$mode', expected 'lacp' or 'static'\n"; + $want_bond->{$device} = {mode => $mode, slaves => [@slaves]}; } sub read_active_vlans { @@ -312,13 +314,17 @@ sub configure_vlans { } sub read_active_bonds { - my $have_bond = {}; # { bond_device => [slave1, slave2, ...], ... } + my $have_bond = {}; # { bond_device => { mode => kernel-mode-name, slaves => [slave1, slave2, ...] }, ... } -e "/sys/class/net/bonding_masters" or sys("modprobe bonding max_bonds=0 || true"); for my $dev (network_devices()) { -d "/sys/class/net/$dev/bonding" or next; - $have_bond->{$dev} = [sort split ' ', slurpfile_chomp("/sys/class/net/$dev/bonding/slaves")]; + my ($mode) = split ' ', slurpfile_chomp("/sys/class/net/$dev/bonding/mode"); + $have_bond->{$dev} = { + mode => $mode, + slaves => [sort split ' ', slurpfile_chomp("/sys/class/net/$dev/bonding/slaves")], + }; } return $have_bond; } @@ -333,8 +339,9 @@ sub unconfigure_bonds { sub configure_bonds { my ($want_bond) = @_; for my $device (sort keys %$want_bond) { - my @slaves = @{$want_bond->{$device}}; - sys('ip', 'link', 'add', $device, 'type', 'bond', 'mode', '802.3ad', 'miimon', '100'); + my $mode = $BONDING_KERNEL_MODE{$want_bond->{$device}{mode}}; + my @slaves = @{$want_bond->{$device}{slaves}}; + sys('ip', 'link', 'add', $device, 'type', 'bond', 'mode', $mode, 'miimon', '100'); for my $slave (@slaves) { # the kernel refuses to enslave a device that is administratively up sys('ip', 'link', 'set', $slave, 'down'); @@ -567,12 +574,14 @@ sub start { for (keys %$want_bond) { $new_bond->{$_} = $want_bond->{$_} unless exists $have_bond->{$_} - && join(' ', @{$have_bond->{$_}}) eq join(' ', sort @{$want_bond->{$_}}); + && $have_bond->{$_}{mode} eq $BONDING_KERNEL_MODE{$want_bond->{$_}{mode}} + && join(' ', @{$have_bond->{$_}{slaves}}) eq join(' ', sort @{$want_bond->{$_}{slaves}}); } for (keys %$have_bond) { $del_bond->{$_} = $have_bond->{$_} unless exists $want_bond->{$_} - && join(' ', @{$have_bond->{$_}}) eq join(' ', sort @{$want_bond->{$_}}); + && $have_bond->{$_}{mode} eq $BONDING_KERNEL_MODE{$want_bond->{$_}{mode}} + && join(' ', @{$have_bond->{$_}{slaves}}) eq join(' ', sort @{$want_bond->{$_}{slaves}}); } for (keys %$ip_want_addr) {