diff options
-rw-r--r-- | lib/Vyatta/Interface.pm | 27 | ||||
-rwxr-xr-x | lib/Vyatta/Misc.pm | 213 | ||||
-rwxr-xr-x | scripts/vyatta-interfaces.pl | 63 | ||||
-rw-r--r-- | templates/interfaces/ethernet/node.tag/address/node.def | 9 | ||||
-rw-r--r-- | templates/interfaces/ethernet/node.tag/vif/node.tag/address/node.def | 9 | ||||
-rw-r--r-- | tests/interface.pl | 14 |
6 files changed, 94 insertions, 241 deletions
diff --git a/lib/Vyatta/Interface.pm b/lib/Vyatta/Interface.pm index e71aacb..cce703a 100644 --- a/lib/Vyatta/Interface.pm +++ b/lib/Vyatta/Interface.pm @@ -138,7 +138,7 @@ sub mtu { return $config->returnValue("mtu"); } -sub dhcp { +sub using_dhcp { my $self = shift; my $config = new Vyatta::Config; $config->setLevel( $self->{path} ); @@ -149,20 +149,29 @@ sub dhcp { return $addr[0]; } -# return array of static address (if any) +## System checks + +# return array of current addresses (on system) sub address { my $self = shift; - my $config = new Vyatta::Config; - $config->setLevel( $self->{path} ); - my @addr = grep { $_ ne 'dhcp' } $config->returnOrigValues('address'); + open my $ipcmd, "ip addr show dev $self->{name} |" + or die "ip addr command failed: $!"; - return @addr if (wantarray); - return if ($#addr < 0); - return $addr[0]; + my @addresses; + <$ipcmd>; + while (<$ipcmd>) { + my ($proto, $addr) = split; + next unless ($proto =~ /inet/); + push @addresses, $addr; + } + close $ipcmd; + + return @addresses; } -## System checks +# return + sub exists { my $self = shift; diff --git a/lib/Vyatta/Misc.pm b/lib/Vyatta/Misc.pm index 19257be..04a958c 100755 --- a/lib/Vyatta/Misc.pm +++ b/lib/Vyatta/Misc.pm @@ -24,13 +24,14 @@ package Vyatta::Misc; require Exporter; @ISA = qw(Exporter); -@EXPORT = qw(get_sysfs_value getNetAddIP isIpAddress is_ip_v4_or_v6); +@EXPORT = qw(get_sysfs_value getNetAddIP isIpAddress is_ip_v4_or_v6 is_dhcp_enabled is_address_enabled); @EXPORT_OK = qw(get_sysfs_value getNetAddIP isIpAddress is_ip_v4_or_v6 getPortRuleString); use strict; use Vyatta::Config; +use Vyatta::Interface; sub get_sysfs_value { my ($intf, $name) = @_; @@ -44,42 +45,35 @@ sub get_sysfs_value { return $value; } -# check if interace is configured to get an IP address using dhcp +# check if interface is configured to get an IP address using dhcp sub is_dhcp_enabled { - my ($intf, $outside_cli) = @_; + my ($name, $outside_cli) = @_; + my $intf = new Vyatta::Interface($name); + return unless $intf; my $config = new Vyatta::Config; - if (!($outside_cli eq '')) { - $config->{_active_dir_base} = "/opt/vyatta/config/active/"; - } + $config->{_active_dir_base} = "/opt/vyatta/config/active/" + if ($outside_cli); - if ($intf =~ m/^eth/) { - if ($intf =~ m/(\w+)\.(\d+)/) { - $config->setLevel("interfaces ethernet $1 vif $2"); - } else { - $config->setLevel("interfaces ethernet $intf"); - } - } elsif ($intf =~ m/^br/) { - $config->setLevel("interfaces bridge $intf"); - } elsif ($intf =~ m/^bond/) { - if ($intf =~ m/(\w+)\.(\d+)/) { - $config->setLevel("interfaces bonding $1 vif $2"); - } else { - $config->setLevel("interfaces bonding $intf"); - } - } else { - # - # add other interfaces that can be configured to use dhcp above - # - return 0; + $config->setLevel($intf->path()); + foreach my $addr ($config->returnOrigValues('address')) { + return 1 if ($addr && $addr eq "dhcp"); } - my @addrs = $config->returnOrigValues("address"); - foreach my $addr (@addrs) { - if (defined $addr && $addr eq "dhcp") { - return 1; - } + # return undef +} + +# check if any non-dhcp addresses configured +sub is_address_enabled { + my $name = shift; + my $intf = new Vyatta::Interface($name); + $intf or return; + + my $config = new Vyatta::Config; + $config->setLevel($intf->path()); + foreach my $addr ($config->returnOrigValues('address')) { + return 1 if ($addr && $addr ne 'dhcp'); } - return 0; + # return undefined (ie false) } # return dhclient related files for interface @@ -119,12 +113,10 @@ sub getInterfacesIPadresses { $is_intf_interface_type = 1; } if ($is_intf_interface_type > 0) { - my @ips = (); - @ips = + $intf_ips[$intf_ips_index] = `ip addr show $intf_system 2>/dev/null | grep inet | grep -v inet6 | awk '{print \$2}'`; - chomp @ips; - if (scalar(@ips) > 0){ - push @intf_ips, @ips; + if (!($intf_ips[$intf_ips_index] eq '')){ + $intf_ips_index++; } } } @@ -134,34 +126,17 @@ sub getInterfacesIPadresses { } - sub getNetAddrIP { - my ($interface); - ($interface) = @_; - - if ($interface eq '') { - print STDERR "Error: No interface specified.\n"; - return; # undef + my $name = shift; + my $intf = new Vyatta::Interface($name); + $intf or return; + + foreach my $addr ($intf->addresses()) { + my $ip = new NetAddr::IP->new($addr); + next unless ($ip && ip->version() == 4); + return $ip; } - - my $ifconfig_out = `ifconfig $interface`; - $ifconfig_out =~ /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/; - my $ip = $1; - if ($ip eq '') { - print STDERR "Error: Unable to determine IP address for interface \'$interface\'.\n"; - return; # undef - } - - $ifconfig_out =~ /Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/; - my $netmask = $1; - if ($netmask eq '') { - print STDERR "Error: Unable to determine netmask for interface \'$interface\'.\n"; - return; # undef - } - - use NetAddr::IP; # This library is available via libnetaddr-ip-perl.deb - my $naip = new NetAddr::IP($ip, $netmask); - return $naip; + # default return of undefined (ie false) } sub is_ip_v4_or_v6 { @@ -200,9 +175,7 @@ sub isIpAddress { sub isClusterIP { my ($vc, $ip) = @_; - if (!(defined($ip))) { - return 0; - } + return unless $ip; # undef my @cluster_groups = $vc->listNodes('cluster group'); foreach my $cluster_group (@cluster_groups) { @@ -214,7 +187,7 @@ sub isClusterIP { } } - return 0; + return; } sub remove_ip_prefix { @@ -227,118 +200,34 @@ sub remove_ip_prefix { sub is_ip_in_list { my ($ip, @list) = @_; - if (!defined($ip) || scalar(@list) == 0) { - return 0; - } - @list = remove_ip_prefix(@list); my %list_hash = map { $_ => 1 } @list; - if (defined($list_hash{$ip})) { - return 1; - } else { - return 0; - } -} - -sub get_eth_ip_addrs { - my ($vc, $eth_path) = @_; - - my @addrs = (); - my @virt_addrs = (); - $vc->setLevel("interfaces ethernet $eth_path"); - @addrs = $vc->returnValues("address"); - - # - # check for VIPs - # - $vc->setLevel("interfaces ethernet $eth_path vrrp vrrp-group"); - my @vrrp_groups = $vc->listNodes(); - foreach my $group (@vrrp_groups) { - $vc->setLevel("interfaces ethernet $eth_path vrrp vrrp-group $group"); - @virt_addrs = $vc->returnValues("virtual-address"); - } - return (@addrs, @virt_addrs); -} - -sub get_tun_ip_addrs { - my ($vc, $tun_path) = @_; - - my @addrs = (); - my @virt_addrs = (); - - $vc->setLevel("interfaces tunnel $tun_path"); - @addrs = $vc->returnValues("address"); - - # - # check for VIPs - # - $vc->setLevel("interfaces tunnel $tun_path vrrp vrrp-group"); - my @vrrp_groups = $vc->listNodes(); - foreach my $group (@vrrp_groups) { - $vc->setLevel("interfaces tunnel $tun_path vrrp vrrp-group $group"); - @virt_addrs = $vc->returnValues("virtual-address"); - } - return (@addrs, @virt_addrs); -} - -sub get_serial_ip_addrs { - # - # Todo when serial is added - # + return $list_hash{$ip}; } sub isIPinInterfaces { my ($vc, $ip_addr, @interfaces) = @_; - if (!(defined($ip_addr))) { - return 0; - } + return unless $ip_addr; # undef == false - foreach my $intf (@interfaces) { - # regular ethernet - if ($intf =~ m/^eth\d+$/) { - my @addresses = get_eth_ip_addrs($vc, $intf); - if (is_ip_in_list($ip_addr, @addresses)) { - return 1; - } - } - # ethernet vlan - if ($intf =~ m/^eth(\d+).(\d+)$/) { - my $eth = "eth$1"; - my $vif = $2; - my @addresses = get_eth_ip_addrs($vc, "$eth vif $vif"); - if (is_ip_in_list($ip_addr, @addresses)) { - return 1; - } - } - # tunnel - if ($intf =~ m/^tun\d+$/) { - my @addresses = get_tun_ip_addrs($vc, $intf); - if (is_ip_in_list($ip_addr, @addresses)) { - return 1; - } - } - # serial - if ($intf =~ m/^wan(\d+).(\d+)$/) { - my @addresses = get_serial_ip_addrs($vc, $intf); - if (is_ip_in_list($ip_addr, @addresses)) { - return 1; - } - } + foreach my $name (@interfaces) { + my $name = shift; + my $intf = new Vyatta::Interface($name); + next unless $intf; # unknown interface type + + my @addresses = $intf->address(); + + return 1 if (is_ip_in_list($ip_addr, @addresses)); } - return 0; + return; # undef == false } sub isClusteringEnabled { my ($vc) = @_; - if ($vc->exists('cluster')) { - return 1; - } else { - return 0; - } + return $vc->exists('cluster'); } # $str: string representing a port number diff --git a/scripts/vyatta-interfaces.pl b/scripts/vyatta-interfaces.pl index a39cde4..de31e5e 100755 --- a/scripts/vyatta-interfaces.pl +++ b/scripts/vyatta-interfaces.pl @@ -53,7 +53,6 @@ GetOptions("eth-addr-update=s" => \$eth_update, "valid-mac=s" => \$mac, "set-mac=s" => \$mac_update, "op-command=s" => \$op_dhclient, - "intf-cli-path=s" => \$intf_cli_path ); if (defined $eth_update) { update_eth_addrs($eth_update, $dev); } @@ -123,42 +122,6 @@ sub dhcp_conf_header { return $output; } -sub is_address_enabled { - my $intf = shift; - - my $config = new Vyatta::Config; - - ## FIXME this is name based madness find a better way - ## so we don't have to redo with each interface type! - ## POSSIBLE SOLUTION: pass the cli-path uptill 'address' node from - ## address/node.def so we don't have to determine the address type here - if ($intf =~ m/^eth/) { - if ($intf =~ m/(\w+)\.(\d+)/) { - $config->setLevel("interfaces ethernet $1 vif $2"); - } else { - $config->setLevel("interfaces ethernet $intf"); - } - } elsif ($intf =~ m/^bond/) { - if ($intf =~ m/(\w+)\.(\d+)/) { - $config->setLevel("interfaces bonding $1 vif $2"); - } else { - $config->setLevel("interfaces bonding $intf"); - } - } elsif ($intf =~ m/^br/) { - $config->setLevel("interfaces bridge $intf"); - } else { - print "unsupported dhcp interface [$intf]\n"; - exit 1; - } - my @addrs = $config->returnOrigValues("address"); - foreach my $addr (@addrs) { - if (defined $addr && $addr ne "dhcp") { - return 1; - } - } - return 0; -} - sub get_hostname { my $config = new Vyatta::Config; $config->setLevel("system"); @@ -214,29 +177,17 @@ sub dhcp_update_config { } sub is_intf_disabled { - my $intf = shift; + my $name = shift; + my $intf = new Vyatta::Interface($name); + + $intf or die "Unknown interface name/type: $name\n"; # only do this if script run from config mode if (!defined $op_dhclient) { + my $config = new Vyatta::Config; + $config->setLevel($intf->path()); - if (!defined $intf_cli_path) { - print "unable to check if interface is disabled without cli path\n"; - exit 1; - } - - my $config = new Vyatta::Config; - $config->setLevel("$intf_cli_path"); - - if ($intf =~ m/^br/) { - if ($config->returnValue("disable") eq "true") { - return 1; - } - } else { - if ($config->exists("disable")) { - return 1; - } - } - + return $config->exists("disable"); } return 0; } diff --git a/templates/interfaces/ethernet/node.tag/address/node.def b/templates/interfaces/ethernet/node.tag/address/node.def index 5277263..afbd822 100644 --- a/templates/interfaces/ethernet/node.tag/address/node.def +++ b/templates/interfaces/ethernet/node.tag/address/node.def @@ -1,11 +1,10 @@ multi: type: txt help: Set an IP address for this interface -syntax:expression: exec "/opt/vyatta/sbin/vyatta-interfaces.pl --valid-addr $VAR(@) --dev $VAR(../@)"; "Invalid IP address/prefix [$VAR(@)] for interface $VAR(../@)" -update:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $VAR(@) --dev $VAR(../@) \ ---intf-cli-path \"interfaces ethernet $VAR(../@)\""; "Error setting address $VAR(@) on interface $VAR(../@)" -delete:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../@) \ ---intf-cli-path \"interfaces ethernet $VAR(../@)\""; "Error deleting address $VAR(@) on interface $VAR(../@)" +syntax:expression: exec "/opt/vyatta/sbin/vyatta-interfaces.pl --valid-addr $VAR(@) --dev $VAR(../@)"\ + ; "Invalid IP address/prefix [$VAR(@)] for interface $VAR(../@)" +update:sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $VAR(@) --dev $VAR(../@) +delete:sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../@) allowed: echo "dhcp <>" comp_help:Possible completions: <x.x.x.x/x> Set the IP address and prefix length diff --git a/templates/interfaces/ethernet/node.tag/vif/node.tag/address/node.def b/templates/interfaces/ethernet/node.tag/vif/node.tag/address/node.def index 0ef5583..4c93905 100644 --- a/templates/interfaces/ethernet/node.tag/vif/node.tag/address/node.def +++ b/templates/interfaces/ethernet/node.tag/vif/node.tag/address/node.def @@ -1,11 +1,10 @@ multi: type: txt help: Set an IP address for this interface -syntax:expression: exec "/opt/vyatta/sbin/vyatta-interfaces.pl --valid-addr $VAR(@) --dev $VAR(../../@).$VAR(../@) "; "Invalid IP address/prefix [$VAR(@)] for interface $VAR(../../@).$VAR(../@)" -create:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $VAR(@) --dev $VAR(../../@).$VAR(../@) \ ---intf-cli-path \"interfaces ethernet $VAR(../../@) vif $VAR(../@)\""; "Error setting address $VAR(@) on dev $VAR(../../@).$VAR(../@) " -delete:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../../@).$VAR(../@) \ ---intf-cli-path \"interfaces ethernet $VAR(../../@) vif $VAR(../@)\""; "Error deleting address $VAR(@) on dev $VAR(../../@).$VAR(../@) " +syntax:expression: exec "/opt/vyatta/sbin/vyatta-interfaces.pl --valid-addr $VAR(@) --dev $VAR(../../@).$VAR(../@) "\ + ; "Invalid IP address/prefix [$VAR(@)] for interface $VAR(../../@).$VAR(../@)" +create:sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $VAR(@) --dev $VAR(../../@).$VAR(../@) +delete:sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../../@).$VAR(../@) allowed: echo "dhcp <>" comp_help:Possible completions: <x.x.x.x/x> Set the IP address and prefix length diff --git a/tests/interface.pl b/tests/interface.pl index 5fe4278..989d6c5 100644 --- a/tests/interface.pl +++ b/tests/interface.pl @@ -19,12 +19,18 @@ foreach my $arg (@ARGV) { my $vif = $intf->vif(); print "vif=$vif " if $vif; - printf "path = '%s' device=%s\n", $intf->path(), $intf->physicalDevice(); + printf "path = '%s'\ndevice=%s\n", $intf->path(), $intf->physicalDevice(); - foreach my $attr (qw(exists configured disabled dhcp address up running)) { - my $val = $intf->$attr(); + my @addresses = $intf->address(); + if ($#addresses eq -1) { + print "address is no set\n"; + } else { + print "address ", join(' ',@addresses), "\n"; + } - if ($val) { + foreach my $attr (qw(exists configured disabled using up running)) { + my $val = $intf->$attr(); + if (defined $val) { print "\t$attr = $val\n"; } else { print "\t$attr is not set\n"; |