summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2012-02-22 10:46:46 -0800
committerStephen Hemminger <shemminger@vyatta.com>2012-02-22 10:46:46 -0800
commit7bab6815704ce464a97ebbc29d12d400b443de33 (patch)
treede14a286ed1e50fbf863d589b5e9e6072f515fb3
parent800b15c6ee9d463090c571d995734c7d16f28924 (diff)
downloadvyatta-op-7bab6815704ce464a97ebbc29d12d400b443de33.tar.gz
vyatta-op-7bab6815704ce464a97ebbc29d12d400b443de33.zip
Handle 64 bit counters in show interfaces
Bug 7813 On 32 bit platform, perl truncates printf formatting if given a numeric type. (ie %10d). Change to print as string instead. Rework code to make counter wrap code clearer, and use map{} to expand list of values.
-rwxr-xr-xscripts/vyatta-show-interfaces.pl82
1 files changed, 38 insertions, 44 deletions
diff --git a/scripts/vyatta-show-interfaces.pl b/scripts/vyatta-show-interfaces.pl
index 0cfb720..5a56050 100755
--- a/scripts/vyatta-show-interfaces.pl
+++ b/scripts/vyatta-show-interfaces.pl
@@ -54,7 +54,6 @@ my @rx_stat_vars =
my @tx_stat_vars =
qw/tx_bytes tx_packets tx_errors tx_dropped tx_carrier_errors collisions/;
-
sub get_intf_description {
my $name = shift;
my $description = interface_description($name);
@@ -165,27 +164,25 @@ sub get_intf_for_type {
return @list;
}
-# This function assumes 32-bit counters.
+# This function has to deal with both 32 and 64 bit counters
sub get_counter_val {
my ($clear, $now) = @_;
return $now if $clear == 0;
- my $value;
- if ($clear > $now) {
- #
- # The counter has rolled. If the counter has rolled
- # multiple times since the clear value, then this math
- # is meaningless.
- #
- $value = (4294967296 - $clear) + $now;
- } else {
- $value = $now - $clear;
- }
+ # device is using 64 bit values assume they never wrap
+ my $value = $now - $clear;
+ return $value if ($now >> 32) != 0;
+
+ # The counter has rolled. If the counter has rolled
+ # multiple times since the clear value, then this math
+ # is meaningless.
+ $value = (4294967296 - $clear) + $now
+ if ($value < 0);
+
return $value;
}
-
#
# The "action" routines
#
@@ -197,11 +194,15 @@ sub run_show_intf {
my %clear = get_clear_stats($intf);
my $description = get_intf_description($intf);
my $timestamp = $clear{'timestamp'};
- my $line = `ip addr show $intf | sed 's/^[0-9]*: //'`; chomp $line;
- if ($line =~ /link\/tunnel6/) {
- my $estat = `ip -6 tun show $intf | sed 's/.*encap/encap/'`;
- $line =~ s% link/tunnel6% $estat$&%;
- }
+
+ my $line = `ip addr show $intf | sed 's/^[0-9]*: //'`;
+ chomp $line;
+
+ if ($line =~ /link\/tunnel6/) {
+ my $estat = `ip -6 tun show $intf | sed 's/.*encap/encap/'`;
+ $line =~ s% link/tunnel6% $estat$&%;
+ }
+
print "$line\n";
if (defined $timestamp and $timestamp ne "") {
my $time_str = strftime("%a %b %d %R:%S %Z %Y",
@@ -212,28 +213,20 @@ sub run_show_intf {
print " Description: $description\n";
}
print "\n";
+
my %stats = get_intf_stats($intf);
- printf(" %10s %10s %10s %10s %10s %10s\n", "RX: bytes", "packets",
- "errors", "dropped", "overrun", "mcast");
- printf(" %10u %10u %10u %10d %10u %10u\n",
- get_counter_val($clear{'rx_bytes'}, $stats{'rx_bytes'}),
- get_counter_val($clear{'rx_packets'}, $stats{'rx_packets'}),
- get_counter_val($clear{'rx_errors'}, $stats{'rx_errors'}),
- get_counter_val($clear{'rx_dropped'}, $stats{'rx_dropped'}),
- get_counter_val($clear{'rx_over_errors'},
- $stats{'rx_over_errors'}),
- get_counter_val($clear{'multicast'}, $stats{'multicast'}));
-
- printf(" %10s %10s %10s %10s %10s %10s\n", "TX: bytes", "packets",
- "errors", "dropped", "carrier", "collisions");
- printf(" %10u %10u %10u %10u %10u %10u\n\n",
- get_counter_val($clear{'tx_bytes'}, $stats{'tx_bytes'}),
- get_counter_val($clear{'tx_packets'}, $stats{'tx_packets'}),
- get_counter_val($clear{'tx_errors'}, $stats{'tx_errors'}),
- get_counter_val($clear{'tx_dropped'}, $stats{'tx_dropped'}),
- get_counter_val($clear{'tx_carrier_errors'},
- $stats{'tx_carrier_errors'}),
- get_counter_val($clear{'collisions'}, $stats{'collisions'}));
+
+ my $fmt = " %10s %10s %10s %10s %10s %10s\n";
+
+ printf($fmt,
+ "RX: bytes", "packets", "errors", "dropped", "overrun", "mcast");
+ printf($fmt,
+ map { get_counter_val($clear{$_}, $stats{$_}) } @rx_stat_vars);
+
+ printf($fmt,
+ "TX: bytes", "packets", "errors", "dropped", "carrier", "collisions");
+ printf($fmt,
+ map { get_counter_val($clear{$_}, $stats{$_}) } @tx_stat_vars);
}
}
@@ -331,14 +324,16 @@ sub run_show_intf_brief {
sub run_show_counters {
my @intfs = @_;
- my $format = "%-12s %10s %10s %10s %10s\n";
- printf($format, "Interface","Rx Packets","Rx Bytes","Tx Packets","Tx Bytes");
+ printf("%-12s %10s %10s %10s %10s\n",
+ "Interface","Rx Packets","Rx Bytes","Tx Packets","Tx Bytes");
+
foreach my $intf (@intfs) {
my ($state, $link) = get_state_link($intf);
next if $state ne 'up';
my %clear = get_clear_stats($intf);
my %stats = get_intf_stats($intf);
- printf($format, $intf,
+
+ printf("%-12s %10s %10s %10s %10s\n", $intf,
get_counter_val($clear{rx_packets}, $stats{rx_packets}),
get_counter_val($clear{rx_bytes}, $stats{rx_bytes}),
get_counter_val($clear{tx_packets}, $stats{tx_packets}),
@@ -459,4 +454,3 @@ if (defined $action_hash{$action}) {
#
&$func(@intf_list);
-# end of file