summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2009-07-27 12:30:10 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2009-07-27 12:37:50 -0700
commitbdbd1c9b842ad5931b33a1ccf483354a59ce8dab (patch)
tree3b15b3bf0cc65dbfae369726e1d4627a74bc1b6f
parentbe441212b4e726b37ac74f7889ea40ac29679c11 (diff)
downloadvyatta-cfg-system-bdbd1c9b842ad5931b33a1ccf483354a59ce8dab.tar.gz
vyatta-cfg-system-bdbd1c9b842ad5931b33a1ccf483354a59ce8dab.zip
Remove slaves before changing mode
Since kernel driver does not handle mode changes properly. Workaround by removing slaves (and readding) before changing mode. Bug 4758
-rwxr-xr-xscripts/vyatta-bonding.pl90
-rw-r--r--templates/interfaces/bonding/node.tag/mode/node.def2
2 files changed, 73 insertions, 19 deletions
diff --git a/scripts/vyatta-bonding.pl b/scripts/vyatta-bonding.pl
index a0bdbd6e..53e6bffa 100755
--- a/scripts/vyatta-bonding.pl
+++ b/scripts/vyatta-bonding.pl
@@ -46,45 +46,99 @@ my %modes = (
);
sub set_mode {
- my ($intf, $mode) = @_;
+ my ( $intf, $mode ) = @_;
my $val = $modes{$mode};
die "Unknown bonding mode $mode\n" unless defined($val);
open my $fm, '>', "/sys/class/net/$intf/bonding/mode"
- or die "Error: $intf is not a bonding device:$!\n";
+ or die "Error: $intf is not a bonding device:$!\n";
print {$fm} $val, "\n";
close $fm
- or die "Error: $intf can not set mode $val:$!\n";
+ or die "Error: $intf can not set mode $val:$!\n";
}
+sub get_slaves {
+ my $intf = shift;
+
+ open my $f, '<', "/sys/class/net/$intf/bonding/slaves"
+ or die "$intf is not a bonding interface";
+ my $slaves = <$f>;
+ close $f;
+ chomp $slaves;
+
+ return split( ' ', $slaves );
+}
+
+sub add_slave {
+ my ( $intf, @slaves ) = @_;
+
+ open my $f, '>', "/sys/class/net/$intf/bonding/slaves"
+ or die "$intf is not a bonding interface";
+
+ foreach my $slave (@slaves) {
+ print {$f} "+$slave\n";
+ }
+ close $f;
+}
+
+sub remove_slave {
+ my ( $intf, @slaves ) = @_;
+
+ open my $f, '>', "/sys/class/net/$intf/bonding/slaves"
+ or die "$intf is not a bonding interface";
+
+ foreach my $slave (@slaves) {
+ print {$f} "-$slave\n";
+ }
+ close $f;
+}
sub change_mode {
- my ($intf, $mode) = @_;
+ my ( $intf, $mode ) = @_;
my $interface = new Vyatta::Interface($intf);
die "$intf is not a valid interface" unless $interface;
- if ($interface->up()) {
- system "sudo ip link set $intf down"
- and die "Could not set $intf down ($!)\n";
+ my @slaves = get_slaves($intf);
+
+ remove_slave $intf, @slaves if (@slaves);
+
+ if ( $interface->up() ) {
+ system "sudo ip link set $intf down"
+ and die "Could not set $intf down ($!)\n";
- set_mode($intf, $mode);
+ set_mode( $intf, $mode );
- system "sudo ip link set $intf up"
- and die "Could not set $intf up ($!)\n";
- } else {
- set_mode($intf, $mode);
+ system "sudo ip link set $intf up"
+ and die "Could not set $intf up ($!)\n";
}
+ else {
+ set_mode( $intf, $mode );
+ }
+
+ add_slave $intf, @slaves if (@slaves);
}
sub usage {
- print "Usage: $0 --set-mode=s{2}\n";
+ print "Usage: $0 --dev=bondX --mode={mode}\n",
+ print " $0 --dev=bondX --add-port=ethX\n";
+ print " $0 --dev=bondX --remove-port=ethX\n";
+ print
+ print "modes := ", join(',', sort(keys %modes)), "\n";
+
exit 1;
}
-my @mode_change;
+my ($dev, $mode, $add_port, $remove_port);
+
+GetOptions('dev=s' => \$dev,
+ 'mode=s' => \$mode,
+ 'add-port=s' => \$add_port,
+ 'remove-port=s' => \$remove_port,
+ ) or usage();
+
+die "$0: device not specified\n" unless $dev;
-GetOptions(
- 'set-mode=s{2}' => \@mode_change,
-) or usage();
+change_mode($dev, $mode) if $mode;
+add_slave($dev, $add_port) if $add_port;
+remove_slave($dev, $add_port) if $remove_port;
-change_mode( @mode_change ) if @mode_change;
diff --git a/templates/interfaces/bonding/node.tag/mode/node.def b/templates/interfaces/bonding/node.tag/mode/node.def
index 4551ee47..bf8a1a8c 100644
--- a/templates/interfaces/bonding/node.tag/mode/node.def
+++ b/templates/interfaces/bonding/node.tag/mode/node.def
@@ -8,7 +8,7 @@ syntax:expression: $VAR(@) in \
"mode must be 802.3ad, active-backup, broadcast, round-robin, \
transmit-load-balance, adaptive-load-balance, or xor"
help: Sets the bonding mode
-update: sudo ${vyatta_sbindir}/vyatta-bonding.pl --set-mode $VAR(../@) $VAR(@)
+update: sudo ${vyatta_sbindir}/vyatta-bonding.pl --dev=$VAR(../@) --mode=$VAR(@)
comp_help: Possible bonding mode
802.3ad IEEE 802.3ad Dynamic link aggregation (Default)