summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/vyatta-interfaces.pl78
-rw-r--r--templates/interfaces/ethernet/node.tag/duplex/node.def18
-rw-r--r--templates/interfaces/ethernet/node.tag/speed/node.def25
3 files changed, 83 insertions, 38 deletions
diff --git a/scripts/vyatta-interfaces.pl b/scripts/vyatta-interfaces.pl
index 3e5beaa..77de148 100755
--- a/scripts/vyatta-interfaces.pl
+++ b/scripts/vyatta-interfaces.pl
@@ -50,17 +50,21 @@ my $dhcp_daemon = '/sbin/dhclient';
my ($eth_update, $eth_delete, $addr, $dev, $mac, $mac_update, $op_dhclient);
my ($check_name, $show_names, $intf_cli_path, $vif_name, $warn_name);
my ($check_up, $show_path);
+my @speed_duplex;
sub usage {
- print "Usage: $0 --dev=<interface> --check=<type>\n";
- print " $0 --dev=<interface> --warn\n";
- print " $0 --dev=<interface> --valid-mac=<aa:aa:aa:aa:aa:aa>\n";
- print " $0 --dev=<interface> --eth-addr-update=<aa:aa:aa:aa:aa:aa>\n";
- print " $0 --dev=<interface> --eth-addr-delete=<aa:aa:aa:aa:aa:aa>\n";
- print " $0 --dev=<interface> --valid-addr={<a.b.c.d>|dhcp}\n";
- print " $0 --dev=<interface> --path\n";
- print " $0 --dev=<interface> --isup\n";
- print " $0 --show=<type>\n";
+ print <<EOF;
+Usage: $0 --dev=<interface> --check=<type>
+ $0 --dev=<interface> --warn
+ $0 --dev=<interface> --valid-mac=<aa:aa:aa:aa:aa:aa>
+ $0 --dev=<interface> --eth-addr-update=<aa:aa:aa:aa:aa:aa>
+ $0 --dev=<interface> --eth-addr-delete=<aa:aa:aa:aa:aa:aa>
+ $0 --dev=<interface> --valid-addr={<a.b.c.d>|dhcp}
+ $0 --dev=<interface> --speed-duplex=speed,duplex
+ $0 --dev=<interface> --path
+ $0 --dev=<interface> --isup
+ $0 --show=<type>
+EOF
exit 1;
}
@@ -77,6 +81,7 @@ GetOptions("eth-addr-update=s" => \$eth_update,
"warn" => \$warn_name,
"path" => \$show_path,
"isup" => \$check_up,
+ "speed-duplex=s{2}" => \@speed_duplex,
) or usage();
update_eth_addrs($eth_update, $dev) if ($eth_update);
@@ -90,6 +95,7 @@ exists_name($dev) if ($warn_name);
show_interfaces($show_names) if ($show_names);
show_config_path($dev) if ($show_path);
is_up($dev) if ($check_up);
+set_speed_duplex($dev, @speed_duplex) if (@speed_duplex);
exit 0;
sub is_ip_configured {
@@ -491,3 +497,57 @@ sub show_config_path {
print "/opt/vyatta/config/active/$level\n";
}
+sub get_ethtool {
+ my $dev = shift;
+
+ open( my $ethtool, "sudo /usr/sbin/ethtool $dev 2>/dev/null |" )
+ or die "ethtool failed: $!\n";
+
+ # ethtool produces:
+ #
+ # Settings for eth1:
+ # Supported ports: [ TP ]
+ # ...
+ # Speed: 1000Mb/s
+ # Duplex: Full
+ # ...
+ # Auto-negotiation: on
+ my ($rate, $duplex, $autoneg);
+ while (<$ethtool>) {
+ chomp;
+ if ( /^\s+Speed:\s([0-9]+)Mb\/s/ ) {
+ $rate = $1;
+ } elsif ( /^\s+Duplex:\s(.*)$/ ) {
+ $duplex = lc $1;
+ } elsif ( /^\s+Auto-negotiation: on/ ) {
+ $autoneg = 1;
+ }
+ }
+ close $ethtool;
+ return ($rate, $duplex, $autoneg);
+}
+
+sub set_speed_duplex {
+ my ($intf, $nspeed, $nduplex) = @_;
+ die "Missing --dev argument\n" unless $intf;
+
+ my ($ospeed, $oduplex, $autoneg) = get_ethtool($intf);
+
+ # Don't change settings if already okay.
+ if ($autoneg) {
+ return if ($nspeed eq 'auto');
+ } else {
+ return if (defined $ospeed && defined $oduplex &&
+ $nspeed eq $ospeed && $nduplex eq $oduplex);
+ }
+
+ my @cmd = ('sudo', 'ethtool', '-s', $intf );
+ if ($nspeed eq 'auto') {
+ push @cmd, qw(autoneg on);
+ } else {
+ push @cmd, 'speed', $nspeed, 'duplex', $nduplex, 'autoneg', 'off';
+ }
+ exec @cmd;
+
+ die "Command failed: ", join(' ', @cmd);
+}
diff --git a/templates/interfaces/ethernet/node.tag/duplex/node.def b/templates/interfaces/ethernet/node.tag/duplex/node.def
index ba81cca..4600533 100644
--- a/templates/interfaces/ethernet/node.tag/duplex/node.def
+++ b/templates/interfaces/ethernet/node.tag/duplex/node.def
@@ -5,21 +5,9 @@ syntax:expression: $VAR(@) in "auto", "half", "full"; "duplex must be auto, half
commit:expression: ( $VAR(@) == "auto" && $VAR(../speed/@) == "auto" ) || \
( $VAR(@) != "auto" && $VAR(../speed/@) != "auto" ) ; \
"if duplex is hardcoded, speed must also be hardcoded"
-
-update: if [ "$VAR(@)" = "auto" ]
- then
- if ! sudo ethtool $VAR(../@) | grep -q 'Auto-negotiation: on'
- then sudo ethtool -s $VAR(../@) autoneg on
- fi
- else
- sudo ethtool -s $VAR(../@) \
- speed $VAR(../speed/@) duplex $VAR(@) autoneg off
- fi
-
-delete: if [ -d /sys/class/net/$VAR(../@) ]; then
- sudo ethtool -s $VAR(../@) autoneg on
- fi
+update: /opt/vyatta/sbin/vyatta-interfaces.pl --dev=$(../@) \
+ --speed-duplex $VAR(../speed/@) $VAR(@)
comp_help:Possible completions:
- auto\t\tAuto negotiation
+ auto\t\tAuto negotiation (default)
half\t\tHalf duplex
full\t\tFull duplex
diff --git a/templates/interfaces/ethernet/node.tag/speed/node.def b/templates/interfaces/ethernet/node.tag/speed/node.def
index b22e93c..436e481 100644
--- a/templates/interfaces/ethernet/node.tag/speed/node.def
+++ b/templates/interfaces/ethernet/node.tag/speed/node.def
@@ -2,18 +2,15 @@ type: txt
help: Set the speed for this interface
default: "auto"
syntax:expression: $VAR(@) in "auto", "10", "100", "1000", "2500", "10000"; "Speed must be auto, 10, 100, 1000, 2500, or 10000"
-commit:expression: ( $VAR(@) == "auto" && $VAR(../speed/@) == "auto" ) || \
- ( $VAR(@) != "auto" && $VAR(../speed/@) != "auto" ) ; \
+commit:expression: ( $VAR(@) == "auto" && $VAR(../duplex/@) == "auto" ) || \
+ ( $VAR(@) != "auto" && $VAR(../duplex/@) != "auto" ) ; \
"if speed is hardcoded, duplex must also be hardcoded"
-update: if [ "$VAR(@)" = "auto" ]
- then
- if ! sudo ethtool $VAR(../@) | grep -q 'Auto-negotiation: on'
- then sudo ethtool -s $VAR(../@) autoneg on
- fi
- else
- sudo ethtool -s $VAR(../@) \
- speed $VAR(../speed/@) duplex $VAR(@) autoneg off
- fi
-delete: if [ -d /sys/class/net/$VAR(../@) ]; then
- sudo ethtool -s $VAR(../@) autoneg on
- fi
+update: /opt/vyatta/sbin/vyatta-interfaces.pl --dev=$(../@) \
+ --speed-duplex $VAR(@) $VAR(../duplex/@)
+comp_help:Possible completions:
+ auto\t\tAuto negotiation (default)
+ 10 \t\t10 Mbit/sec
+ 100 \t\t100 Mbit/sec
+ 1000\t\t1 Gbit/sec
+ 2500\t\t2.5 Gbit/sec
+ 10000\t10 Gbit/sec