summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJohn Southworth <john.southworth@vyatta.com>2012-05-15 13:52:52 -0700
committerJohn Southworth <john.southworth@vyatta.com>2012-05-15 13:52:52 -0700
commitc43ac111560888ef0393aecbd54202f1a8b7b9fc (patch)
tree8ac60bc10d0963ae033eb9752601f0b8d6e2b538 /scripts
parent28bcc9d884550e630895bb65151d2d857e80478b (diff)
downloadvyatta-cfg-system-c43ac111560888ef0393aecbd54202f1a8b7b9fc.tar.gz
vyatta-cfg-system-c43ac111560888ef0393aecbd54202f1a8b7b9fc.zip
Move VRRP to its own package
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/keepalived/vyatta-clear-vrrp.pl303
-rwxr-xr-xscripts/keepalived/vyatta-keepalived.pl668
-rwxr-xr-xscripts/keepalived/vyatta-show-vrrp.pl322
-rwxr-xr-xscripts/keepalived/vyatta-vrrp-state.pl107
4 files changed, 0 insertions, 1400 deletions
diff --git a/scripts/keepalived/vyatta-clear-vrrp.pl b/scripts/keepalived/vyatta-clear-vrrp.pl
deleted file mode 100755
index 34c0327e..00000000
--- a/scripts/keepalived/vyatta-clear-vrrp.pl
+++ /dev/null
@@ -1,303 +0,0 @@
-#!/usr/bin/perl
-#
-# Module: vyatta-clear-vrrp.pl
-#
-# **** 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: May 2008
-# Description: Script to clear vrrp
-#
-# **** End License ****
-#
-
-use lib '/opt/vyatta/share/perl5/';
-use Vyatta::Keepalived;
-use Vyatta::Interface;
-use Vyatta::Misc;
-
-use Getopt::Long;
-use Sys::Syslog qw(:standard :macros);
-
-use strict;
-use warnings;
-
-my $conf_file = get_conf_file();
-
-
-sub keepalived_write_file {
- my ($file, $data) = @_;
-
- open(my $fh, '>', $file) || die "Couldn't open $file - $!";
- print $fh $data;
- close $fh;
-}
-
-sub set_instance_inital_state {
- my ($instance, $init) = @_;
-
- if ($init eq 'MASTER' and $instance =~ /state \s+ BACKUP/ix) {
- if ($instance !~ s/state \s+ BACKUP/state MASTER/ix) {
- print "Error: unable to replace BACKUP/MASTER\n";
- }
- } elsif ($init eq 'BACKUP' and $instance =~ /state \s+ MASTER/ix) {
- if ($instance !~ s/state \s+ MASTER/state BACKUP/ix) {
- print "Error: unable to replace MASTER/BACKUP\n";
- }
- }
- return $instance;
-}
-
-my $brace_block;
-
-sub vrrp_extract_instance {
- my ($conf, $instance) = @_;
-
- #
- # regex to find a balanced group of squiggly braces {{{ }}}
- #
- $brace_block = qr/
- \{ # 1st brace
- (
- [^\{\}]+ # anything but brace
- | # or
- (??{ $brace_block }) # another brace_block
- )*
- \} # matching brace
- /x;
-
- #
- # regex to match instance:
- #
- # vrrp_instance vyatta-eth1.100-15 {
- # state MASTER
- # interface eth1
- # virtual_router_id 15
- # virtual_ipaddress {
- # 1.1.1.1
- # }
- # }
- #
- my $instance_regex = qr/(vrrp_instance \s+ $instance \s+ $brace_block)/x;
-
- #
- # replace the instance with nothing
- #
- my $match_instance;
- if ($conf =~ s/($instance_regex)//) {
- $match_instance = $1;
- } else {
- return ($conf, undef);
- }
-
- return ($conf, $match_instance);
-}
-
-sub get_vrrp_intf_group {
- my @array;
-
- #
- # return an array of hashes that contains all the intf/group pairs
- #
- my $config = new Vyatta::Config;
-
- foreach my $name ( getInterfaces() ) {
- my $intf = new Vyatta::Interface($name);
- next unless $intf;
- my $path = $intf->path();
- $config->setLevel($path);
- if ($config->existsOrig('vrrp')) {
- $path = "$path vrrp vrrp-group";
- $config->setLevel($path);
- my @groups = $config->listOrigNodes();
- foreach my $group (@groups) {
- my %hash;
- $hash{'intf'} = $name;
- $hash{'group'} = $group;
- $hash{'path'} = "$path $group";
- push @array, {%hash};
- }
- }
- }
-
- return @array;
-}
-
-sub set_inital_state {
- my $conf = shift;
-
- my $new_conf = '';
-
- #
- # find all intf/groups, extract instance, set init state
- #
- my @vrrp_instances = get_vrrp_intf_group();
-
- my $tmp_conf = $conf;
- foreach my $hash (@vrrp_instances) {
- my $intf = $hash->{'intf'};
- my $group = $hash->{'group'};
- my $instance = 'vyatta-' . "$intf" . '-' . "$group";
- my $match_instance;
- ($tmp_conf, $match_instance) =
- vrrp_extract_instance($tmp_conf, $instance);
- if (defined $match_instance) {
- my $init = vrrp_get_init_state($intf, $group, '', 'false');
- $match_instance = set_instance_inital_state($match_instance, $init);
- $new_conf .= $match_instance . "\n\n";
- }
- }
- $new_conf = $tmp_conf . $new_conf;
-
- return $new_conf;
-}
-
-
-#
-# main
-#
-my ($action, $vrrp_intf, $vrrp_group);
-
-GetOptions("vrrp-action=s" => \$action,
- "intf=s" => \$vrrp_intf,
- "group=s" => \$vrrp_group);
-
-if (! defined $action) {
- print "no action\n";
- exit 1;
-}
-
-openlog($0, '', LOG_USER);
-my $login = getlogin();
-
-#
-# clear_process
-#
-if ($action eq 'clear_process') {
- syslog('warning', "clear vrrp process requested by $login");
- if (Vyatta::Keepalived::is_running()) {
- print "Restarting VRRP...\n";
- restart_daemon(get_conf_file());
- } else {
- print "Starting VRRP...\n";
- start_daemon(get_conf_file());
- }
- exit 0;
-}
-
-#
-# clear_master
-#
-if ($action eq 'clear_master') {
-
- #
- # The kludge here to force a vrrp instance to switch from master to
- # backup is to read the keepalived config, remove the instance to be
- # cleared, signal the daemon to reread it's config. This will cause
- # keepalived to see the old instance missing and send a priorty 0
- # advert to cause the backup to immediately take over master. Once
- # that is done we put back the orginal config and signal the daemon
- # again. Note: if the instance if preempt=true, then it may immediately
- # try to become master again.
- #
-
- if (! defined $vrrp_intf || ! defined $vrrp_group) {
- print "must include interface & group\n";
- exit 1;
- }
-
- my $instance = 'vyatta-' . "$vrrp_intf" . '-' . "$vrrp_group";
- my $state_file = Vyatta::Keepalived::get_state_file($vrrp_intf, $vrrp_group);
- if (! -f $state_file) {
- print "Invalid interface/group [$vrrp_intf][$vrrp_group]\n";
- exit 1;
- }
-
- my ($start_time, $intf, $group, $state, $ltime) =
- Vyatta::Keepalived::vrrp_state_parse($state_file);
- if ($state ne 'master') {
- print "vrrp group $vrrp_group on $vrrp_intf is already in backup\n";
- exit 1;
- }
-
- syslog('warning', "clear vrrp master [$instance] requested by $login");
- Vyatta::Keepalived::vrrp_log("vrrp clear_master $vrrp_intf $vrrp_group");
-
- # should add a file lock
- local($/); # slurp mode
- open my $f, '<', $conf_file or die "Couldn't open $conf_file\n";
- my $conf = <$f>;
- close $f;
-
- my $sync_group = list_vrrp_sync_group($intf, $group);
- my @instances = ();
- if (defined($sync_group)) {
- print "vrrp group $vrrp_group on $vrrp_intf is in sync-group "
- . "$sync_group\n";
- @instances = list_vrrp_sync_group_members($sync_group);
- } else {
- push @instances, $instance;
- }
-
- my $new_conf = $conf;
- my $clear_instances;
- foreach my $inst (@instances) {
- my $match_instance;
- print "Forcing $inst to BACKUP...\n";
- Vyatta::Keepalived::vrrp_log("vrrp extract $inst");
- ($new_conf, $match_instance) = vrrp_extract_instance($new_conf, $inst);
- if ($match_instance !~ /nopreempt/) {
- print "Warning: $instance is in preempt mode";
- print " and may retake master\n";
-
- }
- $match_instance = set_instance_inital_state($match_instance, 'BACKUP');
- $clear_instances .= "$match_instance\n";
- }
-
- #
- # need to set the correct initial state for the remaining instances
- #
- $new_conf = set_inital_state($new_conf);
-
- #
- # create the temporary config file
- #
- my $tmp_conf_file = $conf_file . ".$$";
- keepalived_write_file($tmp_conf_file, $new_conf);
-
- my $conf_file_bak = $conf_file . '.bak';
- system("mv $conf_file $conf_file_bak");
- system("cp $tmp_conf_file $conf_file");
-
- restart_daemon($conf_file);
-
- sleep(3);
-
- #
- # add modified instance back and restart
- #
- $new_conf .= "\n" . $clear_instances . "\n";
-
- keepalived_write_file($conf_file, $new_conf);
- Vyatta::Keepalived::restart_daemon($conf_file);
-
- system("rm $conf_file_bak $tmp_conf_file");
- exit 0;
-}
-
-exit 0;
-
-# end of file
diff --git a/scripts/keepalived/vyatta-keepalived.pl b/scripts/keepalived/vyatta-keepalived.pl
deleted file mode 100755
index 60b02608..00000000
--- a/scripts/keepalived/vyatta-keepalived.pl
+++ /dev/null
@@ -1,668 +0,0 @@
-#!/usr/bin/perl
-#
-# Module: vyatta-keepalived.pl
-#
-# **** 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: Script to glue vyatta cli to keepalived daemon
-#
-# **** End License ****
-#
-
-use lib "/opt/vyatta/share/perl5/";
-use Vyatta::Config;
-use Vyatta::Keepalived;
-use Vyatta::Interface;
-use Vyatta::ConntrackSync;
-use Vyatta::Misc;
-use Getopt::Long;
-
-use strict;
-use warnings;
-
-my ( $action, $vrrp_intf, $vrrp_group, $vrrp_vip, $ctsync );
-my ( $conf_file, $changes_file );
-my %HoA_sync_groups;
-my $ctsync_script = "/opt/vyatta/sbin/vyatta-vrrp-conntracksync.sh";
-
-sub validate_source_addr {
- my ( $ifname, $source_addr ) = @_;
-
- if ( defined $source_addr ) {
- unless (is_local_address ( $source_addr )) {
- vrrp_log("hello-source not local");
- return "hello-source-address [$source_addr] must be "
- . "configured on the interface\n";
- }
- return;
- }
-
- # if the hello-source-address wasn't configured, check that the
- # interface has an IPv4 address configured on it.
- my $primary_addr = vrrp_get_primary_addr($ifname);
- if ( ! defined $primary_addr ) {
- vrrp_log("no primary or hello-source");
- return "must configure either a primary address on [$ifname] or"
- . " a hello-source-address\n";
- }
- return;
-}
-
-sub get_ctsync_syncgrp {
- my ($origfunc) = @_;
- my $failover_sync_grp = undef;
-
- my $listnodesfunc = "listNodes";
- my $returnvalfunc = "returnValue";
- if ( defined $origfunc ) {
- $listnodesfunc = "listOrigNodes";
- $returnvalfunc = "returnOrigValue";
- }
-
- my @failover_mechanism =
- Vyatta::ConntrackSync::get_conntracksync_val( $listnodesfunc,
- "failover-mechanism" );
-
- if ( defined $failover_mechanism[0] && $failover_mechanism[0] eq 'vrrp' ) {
- $failover_sync_grp =
- Vyatta::ConntrackSync::get_conntracksync_val( $returnvalfunc,
- "failover-mechanism $failover_mechanism[0] sync-group" );
- }
- return $failover_sync_grp;
-}
-
-sub keepalived_get_values {
- my ( $intf, $path , $noerr) = @_;
-
- my @loc;
- my $err;
- my @errs = ();
- my $output = '';
- my $config = new Vyatta::Config;
-
- my $state_transition_script = get_state_script();
-
- my $on_off = "off";
- $on_off = "on" if $noerr;
- vrrp_log("keepalived_get_values [$intf][$path] noerr = $on_off");
- $config->setLevel($path);
- if ( $config->isDeleted("vrrp") ) {
- return ($output, @errs) if $noerr;
- vrrp_log("vrrp_instance [$intf] deleted");
- return ( $output, @errs );
- }
-
- $config->setLevel("$path vrrp vrrp-group");
- my @groups = $config->listNodes();
- if (scalar(@groups) < 1) {
- return ($output, @errs) if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group");
- $err = "must define a vrrp-group";
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- return ( $output, @errs );
- }
- foreach my $group (@groups) {
- my $vrrp_instance = "vyatta-$intf-$group";
- $config->setLevel("$path vrrp vrrp-group $group");
- if ( $config->exists("disable") ) {
- next if $noerr;
- vrrp_log("$vrrp_instance disabled - skipping");
- my $state_file = get_state_file( $intf, $group );
- unlink($state_file);
- next;
- }
- my @vips = $config->returnValues("virtual-address");
- my $num_vips = scalar(@vips);
- if ( $num_vips == 0 ) {
- next if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group $group");
- $err = "must define a virtual-address for vrrp-group $group";
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- next;
- }
- if ( $num_vips > 20 ) {
- next if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group $group");
- $err = "can not set more than 20 VIPs per group";
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- next;
- }
-
- my $use_vmac = 0;
- my $transition_intf = $intf;
- if ( $config->exists("interface") ) {
- $use_vmac = 1;
- $transition_intf = "$intf"."v"."$group";
- }
-
- my $priority = $config->returnValue("priority");
- if ( !defined $priority ) {
- $priority = 100; # Default backup priority is 100 from RFC.
- }
- my $address_owner = 0;
- $address_owner = 1 if ($priority == 255 && $use_vmac == 1);
- my $preempt = $config->returnValue("preempt");
- if (defined $preempt && $address_owner == 1){
- if ($preempt ne "true") { # the handling of default in configuration is odd so we need to allow it to be set to true...
- $err = "cannot define preempt if this is the address owner";
- if ( defined $err ) {
- next if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group $group");
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- next;
- }
- }
- }
- if ( !defined $preempt ) {
- $preempt = "true";
- }
- my $preempt_delay = $config->returnValue("preempt-delay");
- if ( defined $preempt_delay and $preempt eq "false" ) {
- print "Warning: preempt delay is ignored when preempt=false\n";
- }
- my $advert_int = $config->returnValue("advertise-interval");
- if ( !defined $advert_int ) {
- $advert_int = 1;
- }
- my $sync_group = $config->returnValue("sync-group");
- if ( defined $sync_group && $sync_group ne "" ) {
- push @{ $HoA_sync_groups{$sync_group} }, $vrrp_instance;
- }
- my $hello_source_addr = $config->returnValue("hello-source-address");
- $err = validate_source_addr( $intf, $hello_source_addr ) if (!$address_owner == 1);
- if ( defined $err ) {
- next if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group $group");
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- next;
- }
- if (defined $hello_source_addr && $address_owner == 1){
- $err = "cannot define hello-source-address if this is the address owner";
- if ( defined $err ) {
- next if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group $group");
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- next;
- }
- } elsif ($address_owner == 1) {
- $hello_source_addr = $vips[0];
- $hello_source_addr =~ s/(.*?)\/.*/$1/;
- }
-
- $config->setLevel("$path vrrp vrrp-group $group");
- my ($auth_type, $auth_pass) = (undef, undef);
- if ($config->exists('authentication')) {
- $config->setLevel("$path vrrp vrrp-group $group authentication");
- $auth_type = $config->returnValue("type");
- $auth_pass = $config->returnValue("password");
- if ( defined $auth_type ) {
- $auth_type = "PASS" if $auth_type eq "plaintext-password";
- $auth_type = uc($auth_type);
- if ( !defined $auth_pass ) {
- next if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group $group");
- $err = "vrrp authentication password not set";
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- next;
- }
- } else {
- next if $noerr;
- @loc = split(/ /, "$path vrrp vrrp-group $group");
- $err = "vrrp authentication type not set";
- Vyatta::Config::outputError(\@loc, $err);
- push @errs, $err;
- next;
- }
- }
-
- $config->setLevel("$path vrrp vrrp-group $group run-transition-scripts");
- my $run_backup_script = $config->returnValue("backup");
- if ( !defined $run_backup_script ) {
- $run_backup_script = "null";
- }
- my $run_fault_script = $config->returnValue("fault");
- if ( !defined $run_fault_script ) {
- $run_fault_script = "null";
- }
- my $run_master_script = $config->returnValue("master");
- if ( !defined $run_master_script ) {
- $run_master_script = "null";
- }
-
- # We now have the values and have validated them, so
- # generate the config.
-
- $output .= "vrrp_instance $vrrp_instance \{\n";
- my $init_state;
- if ( defined $ctsync ) {
-
- # check if this group is part of conntrack-sync vrrp sync-group
- my $ctsync_syncgrp = get_ctsync_syncgrp();
- my $vrrpsyncgrp =
- list_vrrp_sync_group( $intf, $group, 'returnOrigPlusComValue' );
- if ( defined $ctsync_syncgrp
- && defined $vrrpsyncgrp
- && ( $ctsync_syncgrp eq $vrrpsyncgrp ) )
- {
- $init_state = 'BACKUP';
- } else {
- $init_state = vrrp_get_init_state( $intf, $group, $vips[0], $preempt );
- }
- } else {
- $init_state = vrrp_get_init_state( $intf, $group, $vips[0], $preempt );
- }
- $output .= "\tstate $init_state\n";
- $output .= "\tinterface $intf\n";
- $output .= "\tvirtual_router_id $group\n";
- if ($use_vmac) {
- $output .= "\tuse_vmac $intf";
- $output .= "v";
- $output .= "$group\n";
- }
- $output .= "\tpriority $priority\n";
- if ( $preempt eq "false" ) {
- $output .= "\tnopreempt\n";
- }
- if ( defined $preempt_delay ) {
- $output .= "\tpreempt_delay $preempt_delay\n";
- }
- $output .= "\tadvert_int $advert_int\n";
- if ( defined $auth_type ) {
- $output .= "\tauthentication {\n";
- $output .= "\t\tauth_type $auth_type\n";
- $output .= "\t\tauth_pass $auth_pass\n\t}\n";
- }
- if ( defined $hello_source_addr ) {
- $output .= "\tmcast_src_ip $hello_source_addr\n";
- }
- $output .= "\tvirtual_ipaddress \{\n";
- foreach my $vip (@vips) {
- $output .= "\t\t$vip\n";
- }
- $output .= "\t\}\n";
- $output .= "\tnotify_master \"$state_transition_script master ";
- $output .= "$intf $group $transition_intf \'$run_master_script\' @vips\" \n";
- $output .= "\tnotify_backup \"$state_transition_script backup ";
- $output .= "$intf $group $transition_intf \'$run_backup_script\' @vips\" \n";
- $output .= "\tnotify_fault \"$state_transition_script fault ";
- $output .= "$intf $group $transition_intf \'$run_fault_script\' @vips\" \n";
- $output .= "\}\n\n";
- }
-
- return ( $output, @errs );
-}
-
-sub vrrp_get_sync_groups {
-
- my $output = "";
-
- foreach my $sync_group ( keys %HoA_sync_groups ) {
- $output .= "vrrp_sync_group $sync_group \{\n\tgroup \{\n";
- foreach my $vrrp_instance ( 0 .. $#{ $HoA_sync_groups{$sync_group} } ) {
- $output .= "\t\t$HoA_sync_groups{$sync_group}[$vrrp_instance]\n";
- }
- $output .= "\t\}\n";
-
- ## add conntrack-sync part here if configured ##
- my $origfunc = undef;
- $origfunc = 'true' if !defined $ctsync;
- my $failover_sync_grp = get_ctsync_syncgrp($origfunc);
- if ( defined $failover_sync_grp && $failover_sync_grp eq $sync_group ) {
- $output .= "\tnotify_master \"$ctsync_script master $sync_group\"\n";
- $output .= "\tnotify_backup \"$ctsync_script backup $sync_group\"\n";
- $output .= "\tnotify_fault \"$ctsync_script fault $sync_group\"\n";
- }
- $output .= "\}\n";
- }
- return $output;
-}
-
-sub vrrp_read_changes {
- my @lines = ();
- return @lines if !-e $changes_file;
- open( my $FILE, "<", $changes_file ) or die "Error: read $!";
- @lines = <$FILE>;
- close($FILE);
- chomp @lines;
- return @lines;
-}
-
-sub vrrp_save_changes {
- my @list = @_;
-
- my $num_changes = scalar(@list);
- vrrp_log("saving changes file $num_changes");
- open( my $FILE, ">", $changes_file ) or die "Error: write $!";
- print $FILE join( "\n", @list ), "\n";
- close($FILE);
-}
-
-sub vrrp_find_changes {
-
- my @list = ();
- my $config = new Vyatta::Config;
- my $vrrp_instances = 0;
-
- foreach my $name ( getInterfaces() ) {
- my $intf = new Vyatta::Interface($name);
- next unless $intf;
- my $path = $intf->path();
- $config->setLevel($path);
- if ( $config->exists("vrrp") ) {
- my %vrrp_status_hash = $config->listNodeStatus("vrrp");
- my ( $vrrp, $vrrp_status ) = each(%vrrp_status_hash);
- if ( $vrrp_status ne "static" ) {
- push @list, $name;
- vrrp_log("$vrrp_status found $name");
- }
- }
-
- #
- # Now look for deleted from the origin tree
- #
- $config->setLevel($path);
- if ( $config->isDeleted("vrrp") ) {
- push @list, $name;
- vrrp_log("Delete found $name");
- }
-
- }
-
- my $num = scalar(@list);
- vrrp_log("Start transation: $num changes");
- if ($num) {
- vrrp_save_changes(@list);
- }
- return $num;
-}
-
-sub remove_from_changes {
- my $intf = shift;
-
- my @lines = vrrp_read_changes();
- if ( scalar(@lines) < 1 ) {
-
- #
- # we shouldn't get to this point, but try to handle it if we do
- #
- vrrp_log("unexpected remove_from_changes()");
- unlink($changes_file);
- return 0;
- }
- my @new_lines = ();
- foreach my $line (@lines) {
- if ( $line =~ /$intf$/ ) {
- vrrp_log("remove_from_changes [$line]");
- } else {
- push @new_lines, $line;
- }
- }
-
- my $num_changes = scalar(@new_lines);
- if ( $num_changes > 0 ) {
- vrrp_save_changes(@new_lines);
- } else {
- unlink($changes_file);
- }
- return $num_changes;
-}
-
-sub vrrp_update_config {
-
- my @errs = ();
- my $output;
-
- my $config = new Vyatta::Config;
- my $vrrp_instances = 0;
-
- %HoA_sync_groups = ();
- foreach my $name ( getInterfaces() ) {
- my $intf = new Vyatta::Interface($name);
- next unless $intf;
- my $path = $intf->path();
- $config->setLevel($path);
- if ( $config->exists("vrrp") ) {
-
- #
- # keepalived gets real grumpy with interfaces that
- # don't exist, so skip vlans that haven't been
- # instantiated yet (typically occurs at boot up).
- #
- if ( !( -d "/sys/class/net/$name" ) ) {
- push @errs, "$name doesn't exist";
- next;
- }
- my ( $inst_output, @inst_errs ) = keepalived_get_values( $name, $path, 1 );
- if ( scalar(@inst_errs) ) {
- push @errs, @inst_errs;
- } else {
- $output .= $inst_output;
- $vrrp_instances++;
- }
- }
- }
-
- if ( $vrrp_instances > 0 ) {
- my $sync_groups = vrrp_get_sync_groups();
- if ( defined $sync_groups && $sync_groups ne "" ) {
- $output = $sync_groups . $output;
- }
- $output = "global_defs {\n\tenable_traps\n}\n" . $output;
- $output = "#\n# autogenerated by $0\n#\n\n" . $output;
- keepalived_write_file( $conf_file, $output );
- }
- return ( $vrrp_instances, @errs );
-}
-
-sub keepalived_write_file {
- my ( $file, $data ) = @_;
-
- open( my $fh, '>', $file ) || die "Couldn't open $file - $!";
- print $fh $data;
- close $fh;
-}
-
-#
-# main
-#
-GetOptions(
- "vrrp-action=s" => \$action,
- "intf=s" => \$vrrp_intf,
- "group=s" => \$vrrp_group,
- "vip=s" => \$vrrp_vip,
- "ctsync=s" => \$ctsync,
-);
-
-if ( !defined $action ) {
- print "no action\n";
- exit 1;
-}
-
-
-#
-# run op mode command first
-#
-if ( $action eq "list-vrrp-intf" ) {
- my @intfs = list_vrrp_intf();
- print join( ' ', @intfs );
- exit 0;
-}
-
-if ( $action eq "list-vrrp-group" ) {
- if ( !defined $vrrp_intf ) {
- print "must include interface\n";
- exit 1;
- }
- my @groups = list_vrrp_group($vrrp_intf);
- print join( ' ', @groups );
- exit 0;
-}
-
-#
-# end of op mode commands
-#
-
-
-#
-# This script can be called from two places :
-# 1. a vrrp node under one of the interfaces
-# 2. service conntrack-sync when conntrack-sync uses VRRP as failover-mechanism
-#
-# when called from conntrack-sync; we just need to add/remove config
-# for sync-group transition scripts and restart daemon. We do NOT
-# perform any other actions usually done in the update part of this
-# script otherwise
-#
-
-if ( !defined $ctsync ) {
-
- # make sure sync-group used by ctsync has not been deleted
-
- my $failover_sync_grp = get_ctsync_syncgrp();
- if ( defined $failover_sync_grp ) {
-
- # make sure vrrp sync-group exists
- my $sync_grp_exists = 'false';
- my @vrrp_intfs = list_vrrp_intf('exists');
- foreach my $vrrp_intf (@vrrp_intfs) {
- my @vrrp_groups = list_vrrp_group( $vrrp_intf, 'listNodes' );
- foreach my $vrrp_group (@vrrp_groups) {
- my $sync_grp =
- list_vrrp_sync_group( $vrrp_intf, $vrrp_group, 'returnValue' );
- if ( defined $sync_grp && $sync_grp eq "$failover_sync_grp" ) {
- $sync_grp_exists = 'true';
- last;
- }
- }
- last if $sync_grp_exists eq 'true';
- }
-
- if ( $sync_grp_exists eq 'false' ) {
- print "sync-group $failover_sync_grp used for conntrack-sync"
- . " is either deleted or undefined\n";
- exit 1;
- }
- }
-
-}
-
-#
-# UPDATE action: the logic for "update" is far more complex than it should
-# be due to limitations of the @&!#ing cli. Ideally we would have just one
-# end node at the top level 'interfaces' level. That way we would know that
-# all the vif's and bond interfaces have been created and we could call this
-# function once to generate the entire keepalived conf file and restart the
-# daemon 1 time. Unfortuately the cli doesn't support nested end nodes, so
-# we have to put and end node at every vrrp node and call this function for
-# every vrrp instance, but since we only want to start the daemon once we
-# need to keep track of some state. The first call checks if the "changes"
-# file exists, if not it search for all the vrrp instances that have changed
-# and adds them to the changes file. As each instance is processed it is
-# removed from changes and when there are no more changes the daemon is
-# started/restarted/stopped. Now since we need to run the script for each
-# instance, we can NOT do "commit" checks in the node.def files since that
-# prevents the end node from getting called. So all the validation needs to
-# be in this script, but why not just do all the work once when the changes
-# file is empty? Well the problem then becomes that when the validation
-# fails, the non-zero exit needs to be associated with the end node otherwise
-# the cli will assume it's good push it through to the active config. So
-# we need to do only the validation for the instance being processed and
-# then on the last instance generate the full conf file and signal the daemon
-# if any changes have been made even if the last instance has a non-zero exit.
-#
-if ( $action eq "update" ) {
- $changes_file = get_changes_file();
- $conf_file = get_conf_file();
- vrrp_log("vrrp update $vrrp_intf") if defined $vrrp_intf;
- if ( !-e $changes_file ) {
- my $num_changes = vrrp_find_changes();
- if ( $num_changes == 0 ) {
- #
- # Shouldn't happen, but ...
- # - one place were this has been know to occur is if a vif is deleted
- # that has a vrrp instance under it. Because the cli doesn't
- # reverse priorities on delete, then the vrrp under the vif
- # is gone by the time we get here.
- #
- vrrp_log("unexpected 0 changes");
- }
- }
-
- my $intf = new Vyatta::Interface($vrrp_intf);
- if (! defined $intf) {
- die "Error: invalid interface [$vrrp_intf]";
- }
- my $path = $intf->path();
- my ( $inst_output, @inst_errs ) = keepalived_get_values( $vrrp_intf, $path );
- my $more_changes = remove_from_changes($vrrp_intf);
- vrrp_log("more changes $more_changes");
-
- if ( $more_changes == 0 ) {
- my ( $vrrp_instances, @errs ) = vrrp_update_config();
- vrrp_log("instances $vrrp_instances");
- if ( $vrrp_instances > 0 ) {
- restart_daemon($conf_file);
- # The changes_file should already be gone by this point, but
- # this is the "belt & suspenders" approach.
- unlink($changes_file);
- vrrp_log("end transaction\n");
- } elsif ( $vrrp_instances == 0 ) {
- stop_daemon();
- unlink($conf_file);
- unlink($changes_file);
- vrrp_log("end transaction\n");
- }
- }
- if ( scalar(@inst_errs) ) {
- vrrp_log( join( "\n", @inst_errs ) );
- exit 1;
- }
- exit 0;
-}
-
-if ( $action eq "update-ctsync" ) {
- vrrp_log("vrrp update conntrack-sync");
- $conf_file = get_conf_file();
- my ( $vrrp_instances, @errs ) = vrrp_update_config();
- vrrp_log("instances $vrrp_instances");
- if ($vrrp_instances > 0) {
- restart_daemon($conf_file);
- }
- exit 0;
-}
-
-if ( $action eq "delete" ) {
- if ( !defined $vrrp_intf || !defined $vrrp_group ) {
- print "must include interface & group";
- exit 1;
- }
- vrrp_log("vrrp delete $vrrp_intf $vrrp_group");
- my $state_file = get_state_file( $vrrp_intf, $vrrp_group );
- unlink($state_file);
- exit 0;
-}
-
-exit 0;
-
-# end of file
diff --git a/scripts/keepalived/vyatta-show-vrrp.pl b/scripts/keepalived/vyatta-show-vrrp.pl
deleted file mode 100755
index 3eadd605..00000000
--- a/scripts/keepalived/vyatta-show-vrrp.pl
+++ /dev/null
@@ -1,322 +0,0 @@
-#!/usr/bin/perl
-#
-# Module: vyatta-show-vrrp.pl
-#
-# **** 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) 2005, 2006, 2007 Vyatta, Inc.
-# All Rights Reserved.
-#
-# Author: Stig Thormodsrud
-# Date: October 2007
-# Description: display vrrp info
-#
-# **** End License ****
-#
-use lib "/opt/vyatta/share/perl5/";
-use Vyatta::Keepalived;
-use Vyatta::Interface;
-
-use strict;
-use warnings;
-
-
-sub elapse_time {
- my ($start, $stop) = @_;
-
- my $seconds = $stop - $start;
- my $string = '';
- my $secs_min = 60;
- my $secs_hour = $secs_min * 60;
- my $secs_day = $secs_hour * 24;
- my $secs_week = $secs_day * 7;
-
- my $weeks = int($seconds / $secs_week);
- if ($weeks > 0 ) {
- $seconds = int($seconds % $secs_week);
- $string .= $weeks . "w";
- }
- my $days = int($seconds / $secs_day);
- if ($days > 0) {
- $seconds = int($seconds % $secs_day);
- $string .= $days . "d";
- }
- my $hours = int($seconds / $secs_hour);
- if ($hours > 0) {
- $seconds = int($seconds % $secs_hour);
- $string .= $hours . "h";
- }
- my $mins = int($seconds / $secs_min);
- if ($mins > 0) {
- $seconds = int($seconds % $secs_min);
- $string .= $mins . "m";
- }
- $string .= $seconds . "s";
-
- return $string;
-}
-
-sub get_state_link {
- my $intf_name = shift;
-
- my $intf = new Vyatta::Interface($intf_name);
- die "Unknown interface [$intf_name]" unless $intf;
-
- my ($state, $link);
- if ($intf->up()) {
- $state = 'up';
- } else {
- $state = 'admin down';
- }
-
- if ($intf->running() == 1) {
- $link = 'up';
- } else {
- $link = 'down';
- }
- return ($state, $link);
-}
-
-sub parse_arping {
- my $file = shift;
-
- return "" if ! -f $file;
-
- open (my $FD, '<', $file)
- or die "Can't open file $file";
-
- my @lines = <$FD>;
- close $FD;
- my $mac = undef;
- foreach my $line (@lines) {
- # regex for xx:xx:xx:xx:xx:xx
- if ($line =~ /(([0-9A-Fa-f]{1,2}:){5}[0-9A-Fa-f]{1,2})/) {
- $mac = $1;
- return uc($mac);
- }
- }
- return $mac;
-}
-
-sub get_master_info {
- my ($intf, $group, $vip) = @_;
-
- # remove mask if vip has one
- if ($vip =~ /([\d.]+)\/\d+/) {
- $vip = $1;
- }
-
- # Calling snoop_for_master() is an expensive operation, so we
- # normally only do it on vrrp state transitions by calling the
- # vyatta-vrrp-state.pl script. However if there are more than
- # 2 routers in the vrrp group when a transition occurs, then
- # only those 2 routes that transitioned will know who the current
- # master is and it's priority. So here we will arp for the VIP
- # address and compare it to our masterfile. If it doesn't match
- # then we will snoop for the new master.
-
- my $master_file = Vyatta::Keepalived::get_master_file($intf, $group);
- my $arp_file = "$master_file.arp";
- my $source_ip = (vrrp_get_config($intf, $group))[0];
-
- my $interface = new Vyatta::Interface($intf);
- my $arp_intf = $intf;
- if ($interface->vif()) {
- $arp_intf = $interface->physicalDevice();
- }
- my $cmd = "/usr/bin/arping -c1 -f -I $arp_intf -s $source_ip $vip";
- system("$cmd > $arp_file");
- my $arp_mac = parse_arping($arp_file);
-
- if ( ! -f $master_file) {
- Vyatta::Keepalived::snoop_for_master($intf, $group, $vip, 2);
- }
-
- if ( -f $master_file) {
- my $master_ip = `grep ip.src $master_file 2> /dev/null`;
- my $master_mac = `grep eth.src $master_file 2> /dev/null`;
- chomp $master_ip; chomp $master_mac;
-
- # regex for show="xx:xx:xx:xx:xx:xx
- if (defined $master_mac and
- $master_mac =~ /show=\"(([0-9A-Fa-f]{1,2}:){5}[0-9A-Fa-f]{1,2})/)
- {
- $master_mac = uc($1);
- if (defined($arp_mac) and ($arp_mac ne $master_mac)) {
- Vyatta::Keepalived::snoop_for_master($intf, $group, $vip, 2);
- $master_ip = `grep ip.src $master_file 2> /dev/null`;
- }
- }
-
- if (defined $master_ip and
- $master_ip =~ m/show=\"(\d+\.\d+\.\d+\.\d+)\"/)
- {
- $master_ip = $1;
- } else {
- $master_ip = "unknown";
- system("mv $master_file /tmp");
- }
-
- my $priority = `grep vrrp.prio $master_file 2> /dev/null`;
- chomp $priority;
- if (defined $priority and $priority =~ m/show=\"(\d+)\"/) {
- $priority = $1;
- } else {
- $priority = "unknown";
- }
-
- return ($master_ip, $priority, $master_mac);
- } else {
- return ('unknown', 'unknown', '');
- }
-}
-
-sub vrrp_showsummary {
- my ($file) = @_;
- my $owner = "no";
- my ($start_time, $intf, $group, $state, $ltime) =
- Vyatta::Keepalived::vrrp_state_parse($file);
- my ($interface_state, $link) = get_state_link($intf);
- if ($state eq "master" || $state eq "backup" || $state eq "fault") {
- my ($primary_addr, $priority, $preempt, $advert_int, $auth_type,
- $vmac_interface,
- @vips) = Vyatta::Keepalived::vrrp_get_config($intf, $group);
- my $format = "\n%-16s%-8s%-8s%-16s%-10s%-9s%-13s";
- my $vip = shift @vips;
- if ($vmac_interface) {
- $intf = "$intf" . "v" . "$group";
- $owner = "yes" if ($priority == 255);
- }
- printf($format, $intf, $group, 'vip', $vip, $link, $owner, $state);
- foreach my $vip (@vips){
- printf("\n%-24s%-8s%-16s", ' ', 'vip', $vip);
- }
- } else {
- print "Physical interface $intf, State: unknown\n";
- }
-}
-
-sub vrrp_show {
- my ($file) = @_;
- my $owner = "no";
- my $now_time = time;
- my ($start_time, $intf, $group, $state, $ltime) =
- Vyatta::Keepalived::vrrp_state_parse($file);
- my ($interface_state, $link) = get_state_link($intf);
- my $first_vip = '';
- if ($state eq "master" || $state eq "backup" || $state eq "fault") {
- my ($primary_addr, $priority, $preempt, $advert_int, $auth_type,
- $vmac_interface,
- @vips) = Vyatta::Keepalived::vrrp_get_config($intf, $group);
- my $sync = list_vrrp_sync_group($intf, $group);
- print "Physical interface: $intf, Source Address $primary_addr\n";
- if ($vmac_interface) {
- my $vma = "$intf" . "v" . "$group";
- $owner = "yes" if ($priority == 255);
- print " Virtual MAC interface: $vma\n";
- print " Address Owner: $owner\n";
- }
- print " Interface state: $link, Group $group, State: $state\n";
- print " Priority: $priority, Advertisement interval: $advert_int, ";
- print "Authentication type: $auth_type\n";
- my $vip_count = scalar(@vips);
- my $string = " Preempt: $preempt, VIP count: $vip_count, VIP: ";
- my $strlen = length($string);
- print $string;
- foreach my $vip (@vips) {
- if ($first_vip eq '') {
- $first_vip = $vip;
- }
- if ($vip_count != scalar(@vips)) {
- print " " x $strlen;
- }
- print "$vip\n";
- $vip_count--;
- }
- if ($state eq "master") {
- print " Master router: $primary_addr\n";
- } elsif ($state eq "backup") {
- my ($master_rtr, $master_prio,$master_mac) =
- get_master_info($intf, $group, $first_vip);
- print " Master router: $master_rtr";
- if ($master_mac ne '') {
- print " [$master_mac]"
- }
- print ", Master Priority: $master_prio\n";
- }
- print " Sync-group: $sync\n" if defined $sync;
- } else {
- print "Physical interface $intf, State: unknown\n";
- }
- my $elapsed = elapse_time($start_time, $now_time);
- print " Last transition: $elapsed\n\n";
- if ($state eq "backup") {
-
- }
-}
-
-#
-# main
-#
-my @intfs = ("eth", "bond");
-my $group = "all";
-my $showsummary = 0;
-
-if ($#ARGV >= 0) {
- if ($ARGV[0] eq "summary") {
- $showsummary = 1;
- } else {
- @intfs = ($ARGV[0]);
- }
-}
-
-if ($#ARGV == 1) {
- $group = $ARGV[1];
-}
-
-if (!Vyatta::Keepalived::is_running()) {
- print "VRRP isn't running\n";
- exit 1;
-}
-
-my $display_func;
-if ($showsummary == 1) {
- $display_func = \&vrrp_showsummary;
- my $format = '%-16s%-8s%-8s%-16s%-10s%-9s%-13s%s';
- printf($format, '', 'VRRP', 'Addr', '', 'Interface','Address', 'VRRP', "\n");
- printf($format, 'Interface', 'Group', 'Type', 'Address', 'State','Owner', 'State',
- "\n");
- printf($format, '-' x 9, '-' x 5, '-' x 4 , '-' x 7, '-' x 5, '-' x 5, '-' x 5, '', );
-} else {
- $display_func = \&vrrp_show;
-}
-
-foreach my $intf (@intfs) {
- my $intf_vrid;
- if ($intf =~ m/(\w+)\.(\d+)v(\d+)/){
- $intf = "$1.$2";
- $intf_vrid = $3;
- } elsif ($intf =~ m/(\w+)v(\d+)/){
- $intf = $1;
- $intf_vrid = $2;
- }
- next if ($group ne 'all' && $intf_vrid && $intf_vrid != $group);
- $group = $intf_vrid if ($group eq 'all' && $intf_vrid);
- my @state_files = Vyatta::Keepalived::get_state_files($intf, $group);
- foreach my $state_file (@state_files) {
- &$display_func($state_file);
- }
-}
-
-exit 0;
-
-#end of file
diff --git a/scripts/keepalived/vyatta-vrrp-state.pl b/scripts/keepalived/vyatta-vrrp-state.pl
deleted file mode 100755
index 83fd80b0..00000000
--- a/scripts/keepalived/vyatta-vrrp-state.pl
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/perl
-#
-# Module: vyatta-vrrp-state.pl
-#
-# **** 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 Vyatta, Inc.
-# All Rights Reserved.
-#
-# Author: Stig Thormodsrud
-# Date: October 2007
-# Description: Script called on vrrp master state transition
-#
-# **** End License ****
-#
-
-use strict;
-use warnings;
-
-use lib "/opt/vyatta/share/perl5/";
-use Vyatta::Keepalived;
-use POSIX;
-
-sub vrrp_state_log {
- my ($state, $intf, $group) = @_;
-
- my $timestamp = strftime("%Y%m%d-%H:%M.%S", localtime);
- my $file = Vyatta::Keepalived::get_state_file($intf, $group);
- my $time = time();
- my $line = "$time $intf $group $state $timestamp";
- open my $fh, ">", $file;
- print $fh $line;
- close $fh;
-}
-
-my $vrrp_state = $ARGV[0];
-my $vrrp_intf = $ARGV[1];
-my $vrrp_group = $ARGV[2];
-# transition interface will contain the vmac interface
-# when one is present and the vrrp interface when one is not
-my $transition_intf = $ARGV[3];
-my $vrrp_transitionscript = $ARGV[4];
-my @vrrp_vips;
-foreach my $arg (5 .. $#ARGV) {
- push @vrrp_vips, $ARGV[$arg];
-}
-
-my $sfile = Vyatta::Keepalived::get_state_file($vrrp_intf, $vrrp_group);
-my ($old_time, $old_intf, $old_group, $old_state, $old_ltime) =
- Vyatta::Keepalived::vrrp_state_parse($sfile);
-if (defined $old_state and $vrrp_state eq $old_state) {
- #
- # restarts call the transition script even if it really hasn't
- # changed.
- #
- Vyatta::Keepalived::vrrp_log("$vrrp_intf $vrrp_group same - $vrrp_state");
- exit 0;
-}
-
-Vyatta::Keepalived::vrrp_log("$vrrp_intf $vrrp_group transition to $vrrp_state");
-vrrp_state_log($vrrp_state, $vrrp_intf, $vrrp_group);
-if ($vrrp_state eq 'backup') {
- # comment out for now, too expensive with lots of vrrp's at boot
- # Vyatta::Keepalived::snoop_for_master($vrrp_intf, $vrrp_group,
- # $vrrp_vips[0], 60);
- # Filter traffic incoming to the vmac interface when in backup state
- # Delete the rule then add it to insure that we don't get duplicates
-} elsif ($vrrp_state eq 'master') {
- #
- # keepalived will send gratuitous arp requests on master transition
- # but some hosts do not update their arp cache for gratuitous arp
- # requests. Some of those host do respond to gratuitous arp replies
- # so here we will send 5 gratuitous arp replies also.
- #
- unless ($transition_intf =~ m/\w+v\d+/){
- foreach my $vip (@vrrp_vips) {
- system("/usr/bin/arping -A -c5 -I $vrrp_intf $vip");
- }
- }
-
- #
- # remove the old master file since we are now master
- #
- my $mfile = Vyatta::Keepalived::get_master_file($vrrp_intf, $vrrp_group);
- system("rm -f $mfile");
-}
-
-if (!($vrrp_transitionscript eq 'null')){
- exec("$vrrp_transitionscript $vrrp_state $vrrp_intf $vrrp_group");
-}
-
-exit 0;
-
-# end of file
-
-
-
-