summaryrefslogtreecommitdiff
path: root/scripts/vyatta-show-bonding.pl
blob: 68e65e278421312c4006849dd97a98f93d131576 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/perl
#
# Module: vyatta-show-interfaces.pl
#
# **** License ****
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# This code was originally developed by Vyatta, Inc.
# Portions created by Vyatta are Copyright (C) 2008 Vyatta, Inc.
# All Rights Reserved.
#
# Author: Stephen Hemminger
# Date: September 2008
# Description: Script to display bonding information
#
# **** End License ****
#
use Getopt::Long;

use strict;
use warnings;

sub usage {
    print "Usage: $0 --brief\n";
    print "       $0 interface(s)\n";
    exit 1;
}

sub get_sysfs_value {
    my ( $intf, $name ) = @_;

    open( my $statf, '<', "/sys/class/net/$intf/$name" )
      or die "Can't open file /sys/class/net/$intf/$name";

    my $value = <$statf>;
    chomp $value if defined $value;
    close $statf;
    return $value;
}

sub get_state_link {
    my $intf = shift;
    my $state;
    my $link = 'down';
    my $flags = get_sysfs_value( $intf, 'flags' );

    my $hex_flags = hex($flags);
    if ( $hex_flags & 0x1 ) {    # IFF_UP
        $state = 'up';
        my $carrier = get_sysfs_value( $intf, 'carrier' );
        if ( $carrier eq '1' ) {
            $link = "up";
        }
    }
    else {
        $state = 'down';
    }

    return ( $state, $link );
}

sub show_brief {
    my @interfaces = @_;
    my $format     = "%-12s %-10s %-8s %-6s %s\n";

    printf $format, 'Interface', 'Mode', 'State', 'Link', 'Slaves';
    foreach my $intf (@interfaces) {
        my $mode = get_sysfs_value( $intf, "bonding/mode" );
        $mode =~ s/ [0-9]+$//;
        my ( $state, $link ) = get_state_link($intf);
        my $slaves = get_sysfs_value( $intf, "bonding/slaves" );
        printf $format, $intf, $mode, $state, $link, $slaves;
    }
}

sub show {
    my @interfaces = @_;
    my $format     = "%-16s %-10s %-10s  %-10s %-10s\n";

    printf $format, "Interface", "RX: bytes", "packets", "TX: bytes", "packets";
    foreach my $intf (@interfaces) {
        my @slaves = split( / /, get_sysfs_value( $intf, "bonding/slaves" ) );
        printf $format, $intf, get_sysfs_value( $intf, "statistics/rx_bytes" ),
          get_sysfs_value( $intf, "statistics/rx_packets" ),
          get_sysfs_value( $intf, "statistics/tx_bytes" ),
          get_sysfs_value( $intf, "statistics/tx_packets" );

        foreach my $slave (@slaves) {
            printf $format, '    ' . $slave,
              get_sysfs_value( $intf, "statistics/rx_bytes" ),
              get_sysfs_value( $intf, "statistics/rx_packets" ),
              get_sysfs_value( $intf, "statistics/tx_bytes" ),
              get_sysfs_value( $intf, "statistics/tx_packets" );
        }
    }
}

my $brief;
GetOptions( 'brief' => \$brief, ) or usage();

my @bond_intf = ();

if ( $#ARGV == -1 ) {
    my $sysfs = '/sys/class/net';
    opendir( my $sysdir, $sysfs ) || die "can't opendir $sysfs";
    foreach my $intf ( readdir($sysdir) ) {
        if ( -d "$sysfs/$intf/bonding" ) {
            unshift @bond_intf, $intf;
        }
    }
    close $sysdir;
}
else {
    @bond_intf = @ARGV;
}

if ($brief) {
    show_brief(@bond_intf);
}
else {
    show(@bond_intf);
}