diff options
-rwxr-xr-x | lib/Vyatta/Interface.pm | 323 |
1 files changed, 170 insertions, 153 deletions
diff --git a/lib/Vyatta/Interface.pm b/lib/Vyatta/Interface.pm index 41ee57d..8451d9e 100755 --- a/lib/Vyatta/Interface.pm +++ b/lib/Vyatta/Interface.pm @@ -28,8 +28,8 @@ use Vyatta::Config; use base 'Exporter'; our @EXPORT = qw(IFF_UP IFF_BROADCAST IFF_DEBUG IFF_LOOPBACK - IFF_POINTOPOINT IFF_RUNNING IFF_NOARP - IFF_PROMISC IFF_MULTICAST); + IFF_POINTOPOINT IFF_RUNNING IFF_NOARP + IFF_PROMISC IFF_MULTICAST); use constant { IFF_UP => 0x1, # interface is up @@ -54,7 +54,7 @@ use constant { }; # Build list of known interface types -my $NETDEV = '/opt/vyatta/etc/netdevice'; +my $NETDEV = '/opt/vyatta/etc/netdevice'; # Hash of interface types # ex: $net_prefix{"eth"} = "ethernet" @@ -63,21 +63,21 @@ my %net_prefix; sub parse_netdev_file { my $filename = shift; - open (my $in, '<', $filename) - or return; + open(my $in, '<', $filename) + or return; while (<$in>) { - chomp; + chomp; - # remove text after # as comment - s/#.*$//; + # remove text after # as comment + s/#.*$//; - my ($prefix, $type) = split; + my ($prefix, $type) = split; - # ignore blank lines or missing patterns - next unless defined($prefix) && defined($type); + # ignore blank lines or missing patterns + next unless defined($prefix) && defined($type); - $net_prefix{$prefix} = $type; + $net_prefix{$prefix} = $type; } close $in; } @@ -89,12 +89,11 @@ parse_netdev_file($NETDEV); my $dirname = $NETDEV . '.d'; if (opendir(my $netd, $dirname)) { foreach my $pkg (sort readdir $netd) { - parse_netdev_file($dirname . '/' . $pkg); + parse_netdev_file($dirname . '/' . $pkg); } closedir $netd; } - # get list of interface types (only used in usage function) sub interface_types { return values %net_prefix; @@ -111,14 +110,14 @@ sub new { # remove VRRP id suffix if ($dev =~ /^(.*)v(\d+)$/) { - $dev = $1; - $vrid = $2; + $dev = $1; + $vrid = $2; } # remove VLAN suffix if ($dev =~ /^(.*)\.(\d+)/) { - $dev = $1; - $vif = $2; + $dev = $1; + $vif = $2; } return unless ($dev =~ /^(l2tpeth|[a-z]+)/); @@ -128,11 +127,11 @@ sub new { return unless $type; # unknown network interface type my $self = { - name => $name, - type => $type, - dev => $dev, - vif => $vif, - vrid => $vrid, + name => $name, + type => $type, + dev => $dev, + vif => $vif, + vrid => $vrid, }; bless $self, $class; return $self; @@ -149,40 +148,41 @@ sub path { my $config = new Vyatta::Config; if ($self->{name} =~ /^(pppo[ae])(\d+)/) { - # For ppp need to look in config file to find where used - my $type = $1; - my $id = $2; - - my $intf = _ppp_intf($self->{name}); - return unless $intf; - - if ($type eq 'pppoe') { - return "interfaces ethernet $intf pppoe $id"; - } - - my $adsl = "interfaces adsl $intf pvc"; - my $config = new Vyatta::Config; - foreach my $pvc ($config->listNodes($adsl)) { - my $path = "$adsl $pvc $type $id"; - return $path if $config->exists($path); - } - } - elsif ($self->{name} =~ /^(wan\d+)\.(\d+)/) { - # guesswork for wan devices - my $dev = $1; - my $vif = $2; - foreach my $type (qw(cisco-hdlc ppp frame-relay)) { - my $path = "interfaces serial $dev $type vif $vif"; - return $path if $config->exists($path); - } - } - else { - # normal device - my $path = "interfaces $self->{type} $self->{dev}"; - $path .= " vrrp $self->{vrid}" if $self->{vrid}; - $path .= " vif $self->{vif}" if $self->{vif}; - return $path; + # For ppp need to look in config file to find where used + my $type = $1; + my $id = $2; + + my $intf = _ppp_intf($self->{name}); + return unless $intf; + + if ($type eq 'pppoe') { + return "interfaces ethernet $intf pppoe $id"; + } + + my $adsl = "interfaces adsl $intf pvc"; + my $config = new Vyatta::Config; + foreach my $pvc ($config->listNodes($adsl)) { + my $path = "$adsl $pvc $type $id"; + return $path if $config->exists($path); + } + } elsif ($self->{name} =~ /^(wan\d+)\.(\d+)/) { + + # guesswork for wan devices + my $dev = $1; + my $vif = $2; + foreach my $type (qw(cisco-hdlc ppp frame-relay)) { + my $path = "interfaces serial $dev $type vif $vif"; + return $path if $config->exists($path); + } + } else { + + # normal device + my $path = "interfaces $self->{type} $self->{dev}"; + $path .= " vrrp $self->{vrid}" if $self->{vrid}; + $path .= " vif $self->{vif}" if $self->{vif}; + + return $path; } return; # undefined (not in config) @@ -208,21 +208,21 @@ sub physicalDevice { return $self->{dev}; } -# Read ppp config to fine associated interface for ppp device +# Read ppp config to find the associated interface for the ppp device sub _ppp_intf { my $dev = shift; my $intf; - open (my $ppp, '<', "/etc/ppp/peers/$dev") - or return; # no such device + open(my $ppp, '<', "/etc/ppp/peers/$dev") + or return; # no such device - while (<$ppp>) { - chomp; - # looking for line like: - # pty "/usr/sbin/pppoe -m 1412 -I eth1" - next unless /^pty\s.*-I\s*(\w+)"/; - $intf = $1; - last; + while (my $line = <$ppp>) { + # looking for a line like: #pty "/usr/sbin/pppoe -m 1412 -I eth1" + # and stop after the first occurence of this line + if ($line =~ /^#pty\s.*-I\s*(\w+)"/) { + $intf = $1; + last; + } } close $ppp; @@ -235,14 +235,14 @@ sub configured { my $self = shift; my $config = new Vyatta::Config; - return $config->exists( $self->{path} ); + return $config->exists($self->{path}); } sub disabled { my $self = shift; my $config = new Vyatta::Config; - $config->setLevel( $self->{path} ); + $config->setLevel($self->{path}); return $config->exists("disable"); } @@ -250,16 +250,16 @@ sub mtu { my $self = shift; my $config = new Vyatta::Config; - $config->setLevel( $self->{path} ); + $config->setLevel($self->{path}); return $config->returnValue("mtu"); } sub using_dhcp { my $self = shift; my $config = new Vyatta::Config; - $config->setLevel( $self->{path} ); + $config->setLevel($self->{path}); - my @addr = grep { $_ eq 'dhcp' } $config->returnOrigValues('address'); + my @addr = grep {$_ eq 'dhcp'} $config->returnOrigValues('address'); return if ($#addr < 0); return $addr[0]; @@ -269,7 +269,7 @@ sub bridge_grp { my $self = shift; my $config = new Vyatta::Config; - $config->setLevel( $self->{path} ); + $config->setLevel($self->{path}); return $config->returnValue("bridge-group bridge"); } @@ -278,14 +278,13 @@ sub bridge_grp { # return array of current addresses (on system) sub address { my ($self, $type) = @_; - return Vyatta::Misc::getIP($self->{name}, $type); } # Do SIOCGIFFLAGS ioctl in perl sub flags { - my $self = shift; - return Vyatta::ioctl::get_interface_flags($self->{name}); + my $self = shift; + return Vyatta::ioctl::get_interface_flags($self->{name}); } sub exists { @@ -298,7 +297,7 @@ sub hw_address { my $self = shift; open my $addrf, '<', "/sys/class/net/$self->{name}/address" - or return; + or return; my $address = <$addrf>; close $addrf; @@ -331,7 +330,7 @@ sub up { my $self = shift; my $flags = $self->flags(); - return defined($flags) && ( $flags & IFF_UP ); + return defined($flags) && ($flags & IFF_UP); } # device exists and is running (ie carrier present) @@ -339,7 +338,7 @@ sub running { my $self = shift; my $flags = $self->flags(); - return defined($flags) && ( $flags & IFF_RUNNING ); + return defined($flags) && ($flags & IFF_RUNNING); } # device description information in kernel (future use) @@ -357,13 +356,15 @@ sub get_vrrp_interfaces { my @ret_ifs; foreach my $vrid ($cfg->$vfunc("$path vrrp vrrp-group")) { - my $vrdev = $dev."v".$vrid; - my $vrpath = "$path vrrp vrrp-group $vrid interface"; - - push @ret_ifs, { name => $vrdev, - type => 'vrrp', - path => $vrpath, - }; + my $vrdev = $dev."v".$vrid; + my $vrpath = "$path vrrp vrrp-group $vrid interface"; + + push @ret_ifs, + { + name => $vrdev, + type => 'vrrp', + path => $vrpath, + }; } return @ret_ifs; @@ -375,12 +376,15 @@ sub get_vif_interfaces { my @ret_ifs; foreach my $vnum ($cfg->$vfunc("$path vif")) { - my $vifdev = "$dev.$vnum"; - my $vifpath = "$path vif $vnum"; - push @ret_ifs, { name => $vifdev, - type => $type, - path => $vifpath }; - push @ret_ifs, get_vrrp_interfaces($cfg, $vfunc, $vifdev, $vifpath); + my $vifdev = "$dev.$vnum"; + my $vifpath = "$path vif $vnum"; + push @ret_ifs, + { + name => $vifdev, + type => $type, + path => $vifpath + }; + push @ret_ifs, get_vrrp_interfaces($cfg, $vfunc, $vifdev, $vifpath); } return @ret_ifs; @@ -391,12 +395,15 @@ sub get_pppoe_interfaces { my @ret_ifs; foreach my $ep ($cfg->$vfunc("$path pppoe")) { - my $pppdev = "pppoe$ep"; - my $ppppath = "$path pppoe $ep"; - - push @ret_ifs, { name => $pppdev, - type => 'pppoe', - path => $ppppath }; + my $pppdev = "pppoe$ep"; + my $ppppath = "$path pppoe $ep"; + + push @ret_ifs, + { + name => $pppdev, + type => 'pppoe', + path => $ppppath + }; } return @ret_ifs; @@ -408,22 +415,29 @@ sub get_adsl_interfaces { my @ret_ifs; for my $p ($cfg->$vfunc("interfaces adsl $a $a pvc")) { - for my $t ($cfg->$vfunc("interfaces adsl $a $a pvc $p")) { - if ($t eq 'classical-ipoa' or $t eq 'bridged-ethernet') { - # classical-ipoa or bridged-ethernet - push @ret_ifs, { name => $a, - type => 'adsl', - path => "interfaces adsl $a $a pvc $p $t" }; - next; - } - - # pppo[ea] - for my $i ($cfg->$vfunc("interfaces adsl $a $a pvc $p $t")) { - push @ret_ifs, { name => "$t$i", - type => 'adsl-pppo[ea]', - path => "interfaces adsl $a $a pvc $p $t $i" }; - } - } + for my $t ($cfg->$vfunc("interfaces adsl $a $a pvc $p")) { + if ($t eq 'classical-ipoa' or $t eq 'bridged-ethernet') { + + # classical-ipoa or bridged-ethernet + push @ret_ifs, + { + name => $a, + type => 'adsl', + path => "interfaces adsl $a $a pvc $p $t" + }; + next; + } + + # pppo[ea] + for my $i ($cfg->$vfunc("interfaces adsl $a $a pvc $p $t")) { + push @ret_ifs, + { + name => "$t$i", + type => 'adsl-pppo[ea]', + path => "interfaces adsl $a $a pvc $p $t $i" + }; + } + } } return @ret_ifs; } @@ -443,23 +457,26 @@ sub get_config_interfaces { my @ret_ifs; foreach my $type ($cfg->$vfunc("interfaces")) { - if ($type eq 'adsl') { - push @ret_ifs, get_adsl_interfaces($cfg, $vfunc); - next; - } - - foreach my $dev ($cfg->$vfunc("interfaces $type")) { - my $path = "interfaces $type $dev"; - - push @ret_ifs, { name => $dev, - type => $type, - path => $path }; - push @ret_ifs, get_vrrp_interfaces($cfg, $vfunc, $dev, $path); - push @ret_ifs, get_vif_interfaces($cfg, $vfunc, $dev, $type, $path); - - push @ret_ifs, get_pppoe_interfaces($cfg, $vfunc, $dev, $path) - if ($type eq 'ethernet'); - } + if ($type eq 'adsl') { + push @ret_ifs, get_adsl_interfaces($cfg, $vfunc); + next; + } + + foreach my $dev ($cfg->$vfunc("interfaces $type")) { + my $path = "interfaces $type $dev"; + + push @ret_ifs, + { + name => $dev, + type => $type, + path => $path + }; + push @ret_ifs, get_vrrp_interfaces($cfg, $vfunc, $dev, $path); + push @ret_ifs, get_vif_interfaces($cfg, $vfunc, $dev, $type, $path); + + push @ret_ifs, get_pppoe_interfaces($cfg, $vfunc, $dev, $path) + if ($type eq 'ethernet'); + } } @@ -491,29 +508,29 @@ sub get_cfg_addresses { my @cfgifs = get_interfaces(); my %ahash; - foreach my $intf ( @cfgifs ) { - my $name = $intf->{'name'}; - - # workaround openvpn wart - my @addrs; - $config->setLevel($intf->{'path'}); - if ($name =~ /^vtun/) { - @addrs = $config->listNodes('local-address'); - } else { - @addrs = $config->returnValues('address'); - } - - foreach my $addr ( @addrs ){ - next if ($addr =~ /^dhcp/); - - # put interface into - my $aif = $ahash{$addr}; - if ($aif) { - push @{$aif}, $name; - } else { - $ahash{$addr} = [ $name ]; - } - } + foreach my $intf (@cfgifs) { + my $name = $intf->{'name'}; + + # workaround openvpn wart + my @addrs; + $config->setLevel($intf->{'path'}); + if ($name =~ /^vtun/) { + @addrs = $config->listNodes('local-address'); + } else { + @addrs = $config->returnValues('address'); + } + + foreach my $addr (@addrs){ + next if ($addr =~ /^dhcp/); + + # put interface into + my $aif = $ahash{$addr}; + if ($aif) { + push @{$aif}, $name; + } else { + $ahash{$addr} = [$name]; + } + } } return \%ahash; |