summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2009-01-07 15:02:18 -0800
committerStephen Hemminger <stephen.hemminger@vyatta.com>2009-01-07 15:02:18 -0800
commit73026e8580afbbbbb18970679ff7207676b51ba6 (patch)
tree04d0aaa60de3ca48072f04dccdced9be483c674e
parentebb8b5cdec70e45d155652f759eeb3bb889410c6 (diff)
downloadvyatta-cfg-73026e8580afbbbbb18970679ff7207676b51ba6.tar.gz
vyatta-cfg-73026e8580afbbbbb18970679ff7207676b51ba6.zip
New Vyatta::Interface infrastructure
Provide generic module to map interface name to configuration and other attributes. This is first step to ripping the special case code out of DHCP, QoS, ... that all have own rules for mapping name to configuration and configuration to name.
-rw-r--r--Makefile.am3
-rw-r--r--lib/Vyatta/Interface.pm211
-rw-r--r--tests/interface.pl35
3 files changed, 248 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index f7c14b0..f05abcb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -61,6 +61,7 @@ sbin_SCRIPTS += scripts/vyatta-check-typeless-node.pl
share_perl5_DATA = lib/Vyatta/Config.pm
share_perl5_DATA += lib/Vyatta/Misc.pm
+share_perl5_DATA += lib/Vyatta/Interface.pm
share_perl5_DATA += lib/Vyatta/TypeChecker.pm
share_perl5_DATA += lib/Vyatta/ConfigDOMTree.pm
share_perl5_DATA += lib/Vyatta/ConfigOutput.pm
@@ -77,4 +78,4 @@ install-exec-hook:
mkdir -p $(DESTDIR)$(etc_shell_leveldir)
cd etc/shell/level; $(cpiop) $(DESTDIR)$(etc_shell_leveldir)
cd $(DESTDIR)/opt/vyatta/sbin; ln -s my_commit1 my_commit
- \ No newline at end of file
+
diff --git a/lib/Vyatta/Interface.pm b/lib/Vyatta/Interface.pm
new file mode 100644
index 0000000..e71aacb
--- /dev/null
+++ b/lib/Vyatta/Interface.pm
@@ -0,0 +1,211 @@
+#!/usr/bin/perl
+
+# Module Vyatta::Interface.pm
+
+# **** 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.
+# **** End License ****
+
+package Vyatta::Interface;
+
+use strict;
+use warnings;
+use Vyatta::Config;
+
+use constant {
+ IFF_UP => 0x1,
+ IFF_RUNNING => 0x40,
+};
+
+my %net_prefix = (
+ 'adsl[\d]+' => { path => 'adsl',
+ vif => 'vif', },
+ 'bond[\d]+' => { path => 'bonding',
+ vif => 'vif', },
+ 'br[\d]+' => { path => 'bridge',
+ vif => 'vif' },
+ 'eth[\d]+' => { path => 'ethernet',
+ vif => 'vif', },
+ 'lo' => { path => 'loopback' },
+ 'ml[\d]+' => { path => 'multilink',
+ vif => 'vif', },
+ 'vtun[\d]+]' => { path => 'openvpn' },
+ 'wan[\d]+' => {
+ path => 'serial',
+ vif => ( 'cisco-hdlc vif', 'ppp vif', 'frame-relay vif' ),
+ },
+ 'tun[\d]+' => { path => 'tunnel' },
+ 'wlm[\d]+' => { path => 'wireless-modem' },
+);
+
+sub new {
+ my $that = shift;
+ my $name = pop;
+ my $class = ref($that) || $that;
+ my ($dev, $vif);
+
+ # Strip off vif from name
+ if ( $name =~ m/(\w)+\.(\d)+/ ) {
+ $dev = $1;
+ $vif = $2;
+ } else {
+ $dev = $name;
+ }
+
+ foreach my $prefix (keys %net_prefix) {
+ next unless $dev =~ /$prefix/;
+ my $path = $net_prefix{$prefix}{path};
+ my $vifpath = $net_prefix{$prefix}{vif};
+
+ # Interface name has vif, but this type doesn't support vif!
+ return if ( $vif && !$vifpath );
+
+ # Check path if given
+ return if ( $#_ >= 0 && join( ' ', @_ ) ne $path );
+
+ $path = "interfaces $path $dev";
+ $path .= " $vifpath $vif" if $vif;
+
+ my $self = {
+ name => $name,
+ path => $path,
+ dev => $dev,
+ vif => $vif,
+ };
+
+ bless $self, $class;
+ return $self;
+
+ }
+
+ return; # nothing
+}
+
+## Field accessors
+sub name {
+ my $self = shift;
+ return $self->{name};
+}
+
+sub path {
+ my $self = shift;
+ return $self->{path};
+}
+
+sub vif {
+ my $self = shift;
+ return $self->{vif};
+}
+
+sub physicalDevice {
+ my $self = shift;
+ return $self->{dev};
+}
+
+## Configuration checks
+
+sub configured {
+ my $self = shift;
+ my $config = new Vyatta::Config;
+
+ return $config->exists( $self->{path} );
+}
+
+sub disabled {
+ my $self = shift;
+ my $config = new Vyatta::Config;
+
+ $config->setLevel( $self->{path} );
+ return $config->exists("disable");
+}
+
+sub mtu {
+ my $self = shift;
+ my $config = new Vyatta::Config;
+
+ $config->setLevel( $self->{path} );
+ return $config->returnValue("mtu");
+}
+
+sub dhcp {
+ my $self = shift;
+ my $config = new Vyatta::Config;
+ $config->setLevel( $self->{path} );
+
+ my @addr = grep { $_ eq 'dhcp' } $config->returnOrigValues('address');
+
+ return if ($#addr < 0);
+ return $addr[0];
+}
+
+# return array of static address (if any)
+sub address {
+ my $self = shift;
+ my $config = new Vyatta::Config;
+ $config->setLevel( $self->{path} );
+
+ my @addr = grep { $_ ne 'dhcp' } $config->returnOrigValues('address');
+
+ return @addr if (wantarray);
+ return if ($#addr < 0);
+ return $addr[0];
+}
+
+## System checks
+sub exists {
+ my $self = shift;
+
+ return ( -d "/sys/class/net/$self->{name}" );
+}
+
+sub _flags {
+ my $self = shift;
+
+ open my $flags, '<', "/sys/class/net/$self->{name}/flags"
+ or return;
+
+ my $val = <$flags>;
+ chomp $val;
+ close $flags;
+ return hex($val);
+}
+
+# device exists and is online
+sub up {
+ my $self = shift;
+ my $flags = $self->_flags();
+
+ return $flags && ( $flags & IFF_UP );
+}
+
+# device exists and is running (ie carrier present)
+sub running {
+ my $self = shift;
+ my $flags = $self->_flags();
+
+ return $flags && ( $flags & IFF_RUNNING );
+}
+
+# device description information in kernel (future use)
+sub description {
+ my $self = shift;
+
+ open my $ifalias, '<', "/sys/class/net/$self->{name}/ifalias"
+ or return;
+ my $description = <$ifalias>;
+ close $ifalias;
+ return $description;
+}
+
+1;
diff --git a/tests/interface.pl b/tests/interface.pl
new file mode 100644
index 0000000..5fe4278
--- /dev/null
+++ b/tests/interface.pl
@@ -0,0 +1,35 @@
+#! /usr/bin/perl
+
+# Standalone test for Vyatta::Interface, not intended to be used
+# directly
+
+
+use strict;
+use warnings;
+use Vyatta::Interface;
+
+foreach my $arg (@ARGV) {
+ print "$arg : ";
+ my $intf = new Vyatta::Interface($arg);
+
+ if (! $intf) {
+ print "undefined\n";
+ next;
+ }
+
+ my $vif = $intf->vif();
+ print "vif=$vif " if $vif;
+ printf "path = '%s' device=%s\n", $intf->path(), $intf->physicalDevice();
+
+ foreach my $attr (qw(exists configured disabled dhcp address up running)) {
+ my $val = $intf->$attr();
+
+ if ($val) {
+ print "\t$attr = $val\n";
+ } else {
+ print "\t$attr is not set\n";
+ }
+ }
+}
+
+exit 0;