diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | debian/changelog | 38 | ||||
-rwxr-xr-x | lib/Vyatta/Interface.pm | 22 | ||||
-rwxr-xr-x | lib/Vyatta/Keepalived.pm | 442 | ||||
-rwxr-xr-x | lib/Vyatta/Misc.pm | 22 | ||||
-rw-r--r-- | lib/Vyatta/ioctl.pm | 59 |
6 files changed, 125 insertions, 460 deletions
diff --git a/Makefile.am b/Makefile.am index a26054a..8f84603 100644 --- a/Makefile.am +++ b/Makefile.am @@ -107,11 +107,11 @@ sbin_SCRIPTS += scripts/vyatta-log-commit.pl share_perl5_DATA = lib/Vyatta/Config.pm share_perl5_DATA += lib/Vyatta/File.pm share_perl5_DATA += lib/Vyatta/Misc.pm +share_perl5_DATA += lib/Vyatta/ioctl.pm share_perl5_DATA += lib/Vyatta/Interface.pm share_perl5_DATA += lib/Vyatta/TypeChecker.pm share_perl5_DATA += lib/Vyatta/ConfigOutput.pm share_perl5_DATA += lib/Vyatta/ConfigLoad.pm -share_perl5_DATA += lib/Vyatta/Keepalived.pm enum_SCRIPTS = scripts/enumeration/existing-interfaces diff --git a/debian/changelog b/debian/changelog index dfa9457..da76b65 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,41 @@ +vyatta-cfg (0.99.83) unstable; urgency=low + + * Move VRRP to its own package + * Remove vrrp files from Makefile + + -- John Southworth <john.southworth@vyatta.com> Tue, 15 May 2012 20:46:31 -0700 + +vyatta-cfg (0.99.82) unstable; urgency=low + + * Bugfix 8079: fix require sys/ioctl.ph confilcts + * Fix variable use in last commit + + -- John Southworth <john.southworth@vyatta.com> Thu, 10 May 2012 18:21:43 -0700 + +vyatta-cfg (0.99.81) unstable; urgency=low + + * Add functions to get calling terminal size to Vyatta::Misc + + -- John Southworth <john.southworth@vyatta.com> Wed, 09 May 2012 08:50:29 -0700 + +vyatta-cfg (0.99.80) unstable; urgency=low + + * Enable snmp support for vrrp + + -- John Southworth <john.southworth@vyatta.com> Mon, 07 May 2012 18:06:06 -0700 + +vyatta-cfg (0.99.79) unstable; urgency=low + + * Match from beginning of the line for multilink device + + -- John Southworth <john.southworth@vyatta.com> Mon, 30 Apr 2012 17:05:46 -0700 + +vyatta-cfg (0.99.78) unstable; urgency=low + + * Bugfix 8017: + + -- John Southworth <john.southworth@vyatta.com> Mon, 30 Apr 2012 16:41:23 -0700 + vyatta-cfg (0.99.77) unstable; urgency=low * Bugfix: 8057 fix call to commit in commit-confirm function diff --git a/lib/Vyatta/Interface.pm b/lib/Vyatta/Interface.pm index bda4d08..8449ccb 100755 --- a/lib/Vyatta/Interface.pm +++ b/lib/Vyatta/Interface.pm @@ -23,9 +23,9 @@ use strict; use warnings; use Vyatta::Config; use Vyatta::Misc; +use Vyatta::ioctl; use base 'Exporter'; use Socket; -require 'sys/ioctl.ph'; our @EXPORT = qw(IFF_UP IFF_BROADCAST IFF_DEBUG IFF_LOOPBACK IFF_POINTOPOINT IFF_RUNNING IFF_NOARP @@ -299,6 +299,9 @@ sub new { my $path = "interfaces $type $dev"; $path .= " $vifpath $vif" if $vif; + # add the vif 1 to multilink paths since they don't have vif interfaces + # denoted by <if>.<vif> and only allow 1 vif to be set + $path .= " vif 1" if ($dev =~ m/^ml[\d]+$/); $path .= " vrrp vrrp-group $vrid interface" if $vrid; $type = 'vrrp' if $vrid; @@ -409,21 +412,8 @@ sub address { # Do SIOCGIFFLAGS ioctl in perl sub flags { - my $self = shift; - - my $SIOCGIFFLAGS = &SIOCGIFFLAGS; - die "SIOCGIFFLAGS not found" - unless defined($SIOCGIFFLAGS); - - socket (my $sock, AF_INET, SOCK_DGRAM, 0) - or die "open UDP socket failed: $!"; - - my $ifreq = pack('a16', $self->{name}); - ioctl($sock, $SIOCGIFFLAGS, $ifreq) - or return; #undef - - my (undef, $flags) = unpack('a16s', $ifreq); - return $flags; + my $self = shift; + return Vyatta::ioctl::get_interface_flags($self->{name}); } sub exists { diff --git a/lib/Vyatta/Keepalived.pm b/lib/Vyatta/Keepalived.pm deleted file mode 100755 index 4986d0c..0000000 --- a/lib/Vyatta/Keepalived.pm +++ /dev/null @@ -1,442 +0,0 @@ -# -# Module: VyattaKeepalived.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) 2007-2009 Vyatta, Inc. -# All Rights Reserved. -# -# Author: Stig Thormodsrud -# Date: October 2007 -# Description: Common keepalived definitions/funcitions -# -# **** End License **** -# -package Vyatta::Keepalived; -use strict; -use warnings; - -our @EXPORT = qw(get_conf_file get_state_script get_state_file - vrrp_log vrrp_get_init_state get_changes_file - start_daemon restart_daemon stop_daemon - vrrp_get_config list_vrrp_intf list_vrrp_group - list_vrrp_sync_group list_all_vrrp_sync_grps - list_vrrp_sync_group_members - vrrp_get_primary_addr); -use base qw(Exporter); - -use Vyatta::Config; -use Vyatta::Interface; -use Vyatta::Misc; -use POSIX; - -my $daemon = '/usr/sbin/keepalived'; -my $keepalived_conf = '/etc/keepalived/keepalived.conf'; -my $sbin_dir = '/opt/vyatta/sbin'; -my $state_transition = "$sbin_dir/vyatta-vrrp-state.pl"; -my $keepalived_pid = '/var/run/keepalived.pid'; -my $state_dir = '/var/run/vrrpd'; -my $vrrp_log = "$state_dir/vrrp.log"; -my $changes_file = "$state_dir/changes"; - -sub vrrp_log { - my $timestamp = strftime("%Y%m%d-%H:%M.%S", localtime); - open my $fh, '>>', $vrrp_log - or die "Can't open $vrrp_log:$!"; - print $fh "$timestamp: ", @_ , "\n"; - close $fh; -} - -sub is_running { - if (-f $keepalived_pid) { - my $pid = `cat $keepalived_pid`; - $pid =~ s/\s+$//; # chomp doesn't remove nl - my $ps = `ps -p $pid -o comm=`; - - if (defined($ps) && $ps ne "") { - return 1; - } - } - return 0; -} - -sub start_daemon { - my ($conf) = @_; - - my $cmd = "$daemon --vrrp --log-facility 7 --log-detail --dump-conf"; - $cmd .= " --use-file $conf --vyatta-workaround"; - system($cmd); - vrrp_log("start_daemon"); -} - -sub stop_daemon { - if (is_running()) { - my $pid = `cat $keepalived_pid`; - $pid =~ s/\s+$//; # chomp doesn't remove nl - system("kill $pid"); - vrrp_log("stop_daemon"); - } else { - vrrp_log("stop daemon called while not running"); - } -} - -sub restart_daemon { - my ($conf) = @_; - - if (is_running()) { - my $pid = `cat $keepalived_pid`; - $pid =~ s/\s+$//; # chomp doesn't remove nl - system("kill -1 $pid"); - vrrp_log("restart_deamon"); - } else { - start_daemon($conf); - } -} - -sub get_conf_file { - return $keepalived_conf; -} - -sub get_state_script { - return $state_transition; -} - -sub get_changes_file { - system("mkdir $state_dir") if ! -d $state_dir; - return $changes_file; -} - -sub get_state_file { - my ($vrrp_intf, $vrrp_group) = @_; - - system("mkdir $state_dir") if ! -d $state_dir; - my $file = "$state_dir/vrrpd_" . "$vrrp_intf" . "_" . "$vrrp_group.state"; - return $file; -} - -sub get_master_file { - my ($vrrp_intf, $vrrp_group) = @_; - - my $file = "$state_dir/vrrpd_" . "$vrrp_intf" . "_" . "$vrrp_group.master"; - return $file; -} - -sub alphanum_split { - my ($str) = @_; - my @list = split m/(?=(?<=\D)\d|(?<=\d)\D)/, $str; - return @list; -} - -sub natural_order { - my ($a, $b) = @_; - my @a = alphanum_split($a); - my @b = alphanum_split($b); - - while (@a && @b) { - my $a_seg = shift @a; - my $b_seg = shift @b; - my $val; - if (($a_seg =~ /\d/) && ($b_seg =~ /\d/)) { - $val = $a_seg <=> $b_seg; - } elsif (($a_seg eq '.') && ($b_seg eq '_')) { - return 1; - } else { - $val = $a_seg cmp $b_seg; - } - if ($val != 0) { - return $val; - } - } - return @a <=> @b; -} - -sub intf_sort { - my @a = @_; - my @new_a = sort { natural_order($a,$b) } @a; - return @new_a; -} - -sub get_state_files { - my ($intf, $group) = @_; - - opendir my $sdir, $state_dir - or die "Can't open $state_dir: $!\n"; - - my @state_files; - if ($group eq "all") { - @state_files = grep { /^vrrpd_$intf.*\.state$/ } readdir($sdir); - } else { - my $intf_group = $intf . "_" . $group . ".state"; - @state_files = grep { /^vrrpd_$intf_group$/ } readdir($sdir); - } - close $sdir; - - @state_files = intf_sort(@state_files); - foreach my $i (0 .. $#state_files) { - $state_files[$i] = "$state_dir/$state_files[$i]"; - } - chomp @state_files; - return @state_files; -} - -sub vrrp_get_primary_addr { - my ($intf) = @_; - - my $path; - my $config = new Vyatta::Config; - my $interface = new Vyatta::Interface($intf); - die "Unknown interface type: $intf" unless $interface; - - $path = $interface->path(); - $config->setLevel($path); - # don't use getIP() to get IP addresses because we only - # want configured addresses, not vrrp VIP addresses. - my @addrs = (); - if ($config->inSession) { - @addrs = $config->returnValues('address'); - } else { - @addrs = $config->returnOrigValues('address'); - } - my $primary_addr = shift @addrs; - - if (defined $primary_addr and - $primary_addr =~ m/(\d+\.\d+\.\d+\.\d+)\/\d+/) { - $primary_addr = $1; # strip /mask - } - return $primary_addr; -} - -# -# this is meant to be called from op mode, so Orig functions are used. -# -sub vrrp_get_config { - my ($intf, $group) = @_; - - my $path; - my $config = new Vyatta::Config; - my $interface = new Vyatta::Interface($intf); - die "Unknown interface type: $intf" unless $interface; - - my $primary_addr = vrrp_get_primary_addr($intf); - if (!defined $primary_addr or $primary_addr eq 'dhcp') { - $primary_addr = "0.0.0.0"; - } - - $path = $interface->path(); - $config->setLevel("$path vrrp vrrp-group $group"); - my $source_addr = $config->returnOrigValue("hello-source-address"); - $primary_addr = $source_addr if defined $source_addr; - - my @vips = $config->returnOrigValues("virtual-address"); - my $priority = $config->returnOrigValue("priority"); - if (!defined $priority) { - $priority = 100; - } - my $preempt = $config->returnOrigValue("preempt"); - if (!defined $preempt) { - $preempt = "true"; - } - my $advert_int = $config->returnOrigValue("advertise-interval"); - if (!defined $advert_int) { - $advert_int = 1; - } - my $vmac_interface = $config->existsOrig("interface"); - if (!defined $vmac_interface) { - $vmac_interface = 0; - } - if ($vmac_interface && $primary_addr eq "0.0.0.0"){ - $primary_addr = $vips[0]; - $primary_addr =~ s/(.*?)\/.*/$1/; - } - - $config->setLevel("$path vrrp vrrp-group $group authentication"); - my $auth_type = $config->returnOrigValue("type"); - if (!defined $auth_type) { - $auth_type = "none"; - } - - return ($primary_addr, $priority, $preempt, $advert_int, $auth_type, - $vmac_interface, @vips); -} - -sub snoop_for_master { - my ($intf, $group, $vip, $timeout) = @_; - - my ($cap_filt, $dis_filt, $options, $cmd); - - my $file = get_master_file($intf, $group); - - # remove mask if vip has one - if ($vip =~ /([\d.]+)\/\d+/) { - $vip = $1; - } - - # - # set up common tshark parameters - # - $cap_filt = "-f \"host 224.0.0.18"; - $dis_filt = "-R \"vrrp.virt_rtr_id == $group and vrrp.ip_addr == $vip\""; - $options = "-a duration:$timeout -p -i$intf -c1 -T pdml"; - - my $auth_type = (vrrp_get_config($intf, $group))[4]; - if (lc($auth_type) ne "ah") { - # - # the vrrp group is the 2nd byte in the vrrp header - # - $cap_filt .= " and proto VRRP and vrrp[1:1] = $group\""; - $cmd = "tshark $options $cap_filt $dis_filt"; - system("$cmd > $file 2> /dev/null"); - } else { - # - # if the vrrp group is using AH authentication, then the proto will be - # AH (0x33) instead of VRRP (0x70). So try snooping for AH and - # look for the vrrp group at byte 45 (ip_header=20, ah=24) - # - $cap_filt .= " and proto 0x33 and ip[45:1] = $group\""; - $cmd = "tshark $options $cap_filt $dis_filt"; - system("$cmd > $file 2> /dev/null"); - } -} - -sub vrrp_state_parse { - my ($file) = @_; - - $file =~ s/\s+$//; # chomp doesn't remove nl - if ( -f $file) { - my $line = `cat $file`; - chomp $line; - my ($start_time, $intf, $group, $state, $ltime) = split(' ', $line); - return ($start_time, $intf, $group, $state, $ltime); - } - # else return undefined -} - -sub vrrp_get_init_state { - my ($intf, $group, $vips, $preempt) = @_; - - my $init_state; - if (is_running()) { - my @state_files = get_state_files($intf, $group); - chomp @state_files; - if (scalar(@state_files) > 0) { - my ($start_time, $f_intf, $f_group, $state, $ltime) = - vrrp_state_parse($state_files[0]); - if ($state eq "master") { - $init_state = 'MASTER'; - } else { - $init_state = 'BACKUP'; - } - return $init_state; - } - # fall through to logic below - } - - # start as backup by default - $init_state = 'BACKUP'; - - return $init_state; -} - -sub list_vrrp_intf { - my ($val_func) = @_; - my $config = new Vyatta::Config; - my @intfs = (); - - foreach my $name ( getInterfaces() ) { - my $intf = new Vyatta::Interface($name); - next unless $intf; - my $path = $intf->path(); - $config->setLevel($path); - if (defined $val_func) { - push @intfs, $name if $config->$val_func("vrrp"); - } else { - push @intfs, $name if $config->existsOrig("vrrp"); - } - } - - return @intfs; -} - -sub list_vrrp_group { - my ($name, $val_func) = @_; - my $config = new Vyatta::Config; - my $path; - - my $intf = new Vyatta::Interface($name); - next unless $intf; - $path = $intf->path(); - $path .= " vrrp vrrp-group"; - $config->setLevel($path); - my @groups = (); - if (defined $val_func) { - @groups = $config->$val_func(); - } else { - @groups = $config->listOrigNodes(); - } - return @groups; -} - -sub list_vrrp_sync_group { - my ($name, $group, $val_func) = @_; - my $config = new Vyatta::Config; - my $path; - - my $intf = new Vyatta::Interface($name); - next unless $intf; - $path = $intf->path(); - $path .= " vrrp vrrp-group $group sync-group"; - $config->setLevel($path); - my $sync_group = undef; - if (defined $val_func) { - $sync_group = $config->$val_func(); - } else { - $sync_group = $config->returnOrigValue(); - } - return $sync_group; -} - -sub list_all_vrrp_sync_grps { - my @sync_grps = (); - my @vrrp_intfs = list_vrrp_intf(); - foreach my $vrrp_intf (@vrrp_intfs) { - my @vrrp_groups = list_vrrp_group($vrrp_intf); - foreach my $vrrp_group (@vrrp_groups) { - my $sync_grp = list_vrrp_sync_group($vrrp_intf, $vrrp_group); - if (defined $sync_grp) { - # add to sync_grps if not already there - if (scalar( grep( /^$sync_grp$/, @sync_grps ) ) == 0) { - push (@sync_grps, $sync_grp); - } - } - } - } - return @sync_grps; -} - -sub list_vrrp_sync_group_members { - my ($sync_grp_match) = @_; - my @members = (); - my @vrrp_intfs = list_vrrp_intf(); - foreach my $vrrp_intf (@vrrp_intfs) { - my @vrrp_groups = list_vrrp_group($vrrp_intf); - foreach my $vrrp_group (@vrrp_groups) { - my $sync_grp = list_vrrp_sync_group($vrrp_intf, $vrrp_group); - if (defined $sync_grp and $sync_grp eq $sync_grp_match) { - push @members, 'vyatta-' . $vrrp_intf. '-' . $vrrp_group; - } - } - } - return @members; -} - -1; -#end of file diff --git a/lib/Vyatta/Misc.pm b/lib/Vyatta/Misc.pm index 6579da7..850cb2b 100755 --- a/lib/Vyatta/Misc.pm +++ b/lib/Vyatta/Misc.pm @@ -21,14 +21,17 @@ package Vyatta::Misc; use strict; +use Vyatta::ioctl; require Exporter; + our @ISA = qw(Exporter); our @EXPORT = qw(getInterfaces getIP getNetAddIP get_sysfs_value is_address_enabled is_dhcp_enabled get_ipaddr_intf_hash isIpAddress is_ip_v4_or_v6 interface_description is_local_address is_primary_address get_ipnet_intf_hash - isValidPortNumber); + isValidPortNumber get_terminal_size get_terminal_height + get_terminal_width ); our @EXPORT_OK = qw(generate_dhclient_intf_files getInterfacesIPadresses getPortRuleString @@ -522,4 +525,21 @@ sub interface_description { return $description; } +# returns (rows, columns) for terminal size +sub get_terminal_size { + return Vyatta::ioctl::get_terminal_size(); +} + +# return only terminal width +sub get_terminal_width { + my ($rows, $cols) = get_terminal_size; + return $cols; +} + +# return only terminal height +sub get_terminal_height { + my ($rows, $cols) = get_terminal_size; + return $rows; +} + 1; diff --git a/lib/Vyatta/ioctl.pm b/lib/Vyatta/ioctl.pm new file mode 100644 index 0000000..b237854 --- /dev/null +++ b/lib/Vyatta/ioctl.pm @@ -0,0 +1,59 @@ +# Author: John Southworth <john.southworth@vyatta.com> +# Date: 2012 +# Description: vyatta ioctl functions + +# **** 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::ioctl; + +use strict; +use Socket; +use Socket6; +require 'sys/ioctl.ph'; + +# returns (rows, columns) for terminal size; +sub get_terminal_size { + my $winsize = ''; + open(my $TTY, '>', '/dev/tty'); + # undefined if output not going to terminal + return unless (ioctl($TTY, &TIOCGWINSZ, $winsize)); + close($TTY); + + my ($rows, $cols, undef, undef) = unpack('S4', $winsize); + return ($rows, $cols); +} + +#Do SIOCGIFFLAGS ioctl in perl +sub get_interface_flags { + my $name = shift; + + my $SIOCGIFFLAGS = &SIOCGIFFLAGS; + die "SIOCGIFFLAGS not found" + unless defined($SIOCGIFFLAGS); + + socket (my $sock, AF_INET, SOCK_DGRAM, 0) + or die "open UDP socket failed: $!"; + + my $ifreq = pack('a16', $name); + ioctl($sock, $SIOCGIFFLAGS, $ifreq) + or return; #undef + + my (undef, $flags) = unpack('a16s', $ifreq); + return $flags; + +} + +1; |