summaryrefslogtreecommitdiff
path: root/lib/Vyatta/Interface.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Vyatta/Interface.pm')
-rwxr-xr-xlib/Vyatta/Interface.pm521
1 files changed, 0 insertions, 521 deletions
diff --git a/lib/Vyatta/Interface.pm b/lib/Vyatta/Interface.pm
deleted file mode 100755
index 35457e4..0000000
--- a/lib/Vyatta/Interface.pm
+++ /dev/null
@@ -1,521 +0,0 @@
-# Author: Stephen Hemminger <shemminger@vyatta.com>
-# Date: 2009
-# Description: vyatta interface management
-
-# **** 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::Misc;
-use Vyatta::ioctl;
-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);
-
-use constant {
- IFF_UP => 0x1, # interface is up
- IFF_BROADCAST => 0x2, # broadcast address valid
- IFF_DEBUG => 0x4, # turn on debugging
- IFF_LOOPBACK => 0x8, # is a loopback net
- IFF_POINTOPOINT => 0x10, # interface is has p-p link
- IFF_NOTRAILERS => 0x20, # avoid use of trailers
- IFF_RUNNING => 0x40, # interface RFC2863 OPER_UP
- IFF_NOARP => 0x80, # no ARP protocol
- IFF_PROMISC => 0x100, # receive all packets
- IFF_ALLMULTI => 0x200, # receive all multicast packets
- IFF_MASTER => 0x400, # master of a load balancer
- IFF_SLAVE => 0x800, # slave of a load balancer
- IFF_MULTICAST => 0x1000, # Supports multicast
- IFF_PORTSEL => 0x2000, # can set media type
- IFF_AUTOMEDIA => 0x4000, # auto media select active
- IFF_DYNAMIC => 0x8000, # dialup device with changing addresses
- IFF_LOWER_UP => 0x10000, # driver signals L1 up
- IFF_DORMANT => 0x20000, # driver signals dormant
- IFF_ECHO => 0x40000, # echo sent packets
-};
-
-# Build list of known interface types
-my $NETDEV = '/opt/vyatta/etc/netdevice';
-
-# Hash of interface types
-# ex: $net_prefix{"eth"} = "ethernet"
-my %net_prefix;
-
-sub parse_netdev_file {
- my $filename = shift;
-
- open(my $in, '<', $filename)
- or return;
-
- while (<$in>) {
- chomp;
-
- # remove text after # as comment
- s/#.*$//;
-
- my ($prefix, $type) = split;
-
- # ignore blank lines or missing patterns
- next unless defined($prefix) && defined($type);
-
- $net_prefix{$prefix} = $type;
- }
- close $in;
-}
-
-# read /opt/vyatta/etc/netdevice
-parse_netdev_file($NETDEV);
-
-# look for optional package interfaces in /opt/vyatta/etc/netdevice.d
-my $dirname = $NETDEV . '.d';
-if (opendir(my $netd, $dirname)) {
- foreach my $pkg (sort readdir $netd) {
- parse_netdev_file($dirname . '/' . $pkg);
- }
- closedir $netd;
-}
-
-# get list of interface types (only used in usage function)
-sub interface_types {
- return values %net_prefix;
-}
-
-# new interface description object
-sub new {
- my $that = shift;
- my $name = pop;
- my $class = ref($that) || $that;
-
- my ($vif, $vif_c, $vrid);
- my $dev = $name;
-
- # remove VRRP id suffix
- if ($dev =~ /^(.*)v(\d+)$/) {
- $dev = $1;
- $vrid = $2;
- }
-
- # QinQ or usual VLAN
- if ($dev =~ /^([^\.]+)\.(\d+)\.(\d+)/) {
- $dev = $1;
- $vif = $2;
- $vif_c = $3;
- } elsif ($dev =~ /^(.*)\.(\d+)/) {
- $dev = $1;
- $vif = $2;
- }
-
- return unless ($dev =~ /^(l2tpeth|[a-z]+)/);
-
- # convert from prefix 'eth' to type 'ethernet'
- my $type = $net_prefix{$1};
- return unless $type; # unknown network interface type
-
- my $self = {
- name => $name,
- type => $type,
- dev => $dev,
- vif => $vif,
- vif_c => $vif_c,
- vrid => $vrid,
- };
- bless $self, $class;
- return $self;
-}
-
-## Field accessors
-sub name {
- my $self = shift;
- return $self->{name};
-}
-
-sub path {
- my $self = shift;
- my $config = new Vyatta::Config;
-
- if ($self->{name} =~ /^(pppo[a])(\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;
-
- 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 vrrp-group $self->{vrid}" if $self->{vrid};
- $path .= " vif $self->{vif}" if ($self->{vif} && !$self->{vif_c});
- $path .= " vif-s $self->{vif} vif-c $self->{vif_c}" if
- ($self->{vif} && $self->{vif_c});
-
-
- return $path;
- }
-
- return; # undefined (not in config)
-}
-
-sub type {
- my $self = shift;
- return $self->{type};
-}
-
-sub vif {
- my $self = shift;
- return $self->{vif};
-}
-
-sub vrid {
- my $self = shift;
- return $self->{vrid};
-}
-
-sub physicalDevice {
- my $self = shift;
- return $self->{dev};
-}
-
-# 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
-
- 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;
-
- return $intf;
-}
-
-## 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 using_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];
-}
-
-sub bridge_grp {
- my $self = shift;
- my $config = new Vyatta::Config;
-
- $config->setLevel($self->{path});
- return $config->returnValue("bridge-group bridge");
-}
-
-## System checks
-
-# 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});
-}
-
-sub exists {
- my $self = shift;
- my $flags = $self->flags();
- return defined($flags);
-}
-
-sub hw_address {
- my $self = shift;
-
- open my $addrf, '<', "/sys/class/net/$self->{name}/address"
- or return;
- my $address = <$addrf>;
- close $addrf;
-
- chomp $address if $address;
- return $address;
-}
-
-sub is_broadcast {
- my $self = shift;
- return $self->flags() & IFF_BROADCAST;
-}
-
-sub is_multicast {
- my $self = shift;
- return $self->flags() & IFF_MULTICAST;
-}
-
-sub is_pointtopoint {
- my $self = shift;
- return $self->flags() & IFF_POINTOPOINT;
-}
-
-sub is_loopback {
- my $self = shift;
- return $self->flags() & IFF_LOOPBACK;
-}
-
-# device exists and is online
-sub up {
- my $self = shift;
- my $flags = $self->flags();
-
- return defined($flags) && ($flags & IFF_UP);
-}
-
-# device exists and is running (ie carrier present)
-sub running {
- my $self = shift;
- my $flags = $self->flags();
-
- return defined($flags) && ($flags & IFF_RUNNING);
-}
-
-# device description information in kernel (future use)
-sub description {
- my $self = shift;
-
- return interface_description($self->{name});
-}
-
-## Utility functions
-
-# enumerate vrrp slave devices
-sub get_vrrp_interfaces {
- my ($cfg, $vfunc, $dev, $path) = @_;
- 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,
- };
- }
-
- return @ret_ifs;
-}
-
-# enumerate vif devies
-sub get_vif_interfaces {
- my ($cfg, $vfunc, $dev, $type, $path) = @_;
- 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);
- }
-
- return @ret_ifs;
-}
-
-# special cases for adsl
-sub get_adsl_interfaces {
- my ($cfg, $vfunc) = @_;
- 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"
- };
- }
- }
- }
- return @ret_ifs;
-}
-
-# get all configured interfaces from configuration
-# parameter is virtual function (see Config.pm)
-#
-# return a hash of:
-# name => ethX
-# type => "ethernet"
-# path => "interfaces ethernet ethX"
-#
-# Don't use this function directly, use wrappers below instead
-sub get_config_interfaces {
- my $vfunc = shift;
- my $cfg = new Vyatta::Config;
- 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);
- }
-
- }
-
- return @ret_ifs;
-}
-
-# get array of hash for interfaces in working config
-sub get_interfaces {
- return get_config_interfaces('listNodes');
-}
-
-# get array of hash for interfaces in configuration
-# when used outside of config mode.
-sub get_effective_interfaces {
- return get_config_interfaces('listEffectiveNodes');
-}
-
-# get array of hash for interfaces in original config
-# only makes sense in configuration mode
-sub get_original_interfaces {
- return get_config_interfaces('listOrigNodes');
-}
-
-# get map of current addresses on the system
-# returns reference to hash of form:
-# ( "192.168.1.1" => { 'eth0', 'eth2' } )
-sub get_cfg_addresses {
- my $config = new Vyatta::Config;
- 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];
- }
- }
- }
-
- return \%ahash;
-}
-
-1;