diff options
-rwxr-xr-x | scripts/vyatta-interfaces.pl | 78 | ||||
-rw-r--r-- | templates/interfaces/ethernet/node.tag/duplex/node.def | 18 | ||||
-rw-r--r-- | templates/interfaces/ethernet/node.tag/speed/node.def | 25 |
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 |