diff options
author | Daniil Baturin <daniil@baturin.org> | 2014-07-25 18:13:39 +0200 |
---|---|---|
committer | Daniil Baturin <daniil@baturin.org> | 2014-07-25 18:13:39 +0200 |
commit | 974a522ebd298aecb4f502bab89d76a4ddbec899 (patch) | |
tree | 50a782e13bb1529a4199b621ffbf9752200ef969 /scripts | |
parent | e70d602929e3017dd2cbac99900f9d4c436d2a60 (diff) | |
download | vyatta-cfg-system-974a522ebd298aecb4f502bab89d76a4ddbec899.tar.gz vyatta-cfg-system-974a522ebd298aecb4f502bab89d76a4ddbec899.zip |
Add vyod-intfwatchd for restoring IPv6 addresses after link flaps.
As bad as it can be, it seems to sort of work.
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/vyos-intfwatchd | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/scripts/vyos-intfwatchd b/scripts/vyos-intfwatchd new file mode 100644 index 00000000..8f9842c2 --- /dev/null +++ b/scripts/vyos-intfwatchd @@ -0,0 +1,159 @@ +#!/usr/bin/perl +# +# Module: vyos-restore-static-ipv6.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. +# +# Copyright (C) 2014 VyOS Development Group +# +# **** End License **** + +use lib "/opt/vyatta/share/perl5"; +use strict; +use warnings; +use POSIX; +use Fcntl; +use Sys::Syslog; +use Vyatta::Config; +use Vyatta::Interface; +use Data::Dumper; + +use constant +{ + # Program settings + PROGRAM_NAME => "vyos-intfwatchd", + PROGRAM_VERSION => "1.0", + PID_FILE => "/var/run/vyos-intfwatchd.pid", + + # Program exit codes + SUCCESS => 0, + ERROR => 1, + + # Subroutine error codes + SUB_ERROR => 0, + SUB_SUCCESS => 1, + + # Fcntl file lock/unlock constants + SET_EXCLUSIVE_LOCK => 2, + UNLOCK => 8 +}; + +sub daemonize +{ + syslog("info", "%s", "Starting in daemon mode"); + + my $pid = fork(); + if (!defined($pid)) + { + # Fork failed + die "Could not spawn child process: $!, exiting"; + } + elsif ($pid > 0) + { + # Child has been spawned succefully, + # parent should terminate now + exit(SUCCESS); + } + chdir("/"); + umask(0); + setsid(); + + # Close standard i/o stream descriptors + open STDIN, "/dev/null" or die "Can't read /dev/null: $!"; + open STDOUT, ">>/dev/null" or die "Can't write to /dev/null: $!"; + open STDERR, ">>/dev/null" or die "Can't write to /dev/null: $!"; +} + +sub writePid +{ + my ($pid, $fh) = @_; + + unless (flock($fh, SET_EXCLUSIVE_LOCK)) + { + syslog("err", "%s", "Could not lock PID file: $!"); + exit(ERROR); + } + + print($fh $pid); +} + +sub releasePid +{ + my $fh = shift; + flock($fh, UNLOCK); + close($fh); + unlink(PID_FILE); +} + + +daemonize(); +my $pidFile = PID_FILE; +unless (open PID_HANDLE, ">$pidFile") +{ + syslog("err", "%s", "Could not create PID file: $!"); + exit(1); +} +writePid($$, \*PID_HANDLE); + +my $config = new Vyatta::Config(); + +my $ip_monitor = "ip monitor link"; +unless (open(HANDLE, "$ip_monitor|")) +{ + syslog("err", "%s", qq{Could not start IP monitor: $!\n}); + exit(1); +} + +sub terminate +{ + my $error = shift; + syslog("notice", "%s", PROGRAM_NAME." is terminating"); + releasePid(\*PID_HANDLE); + exit(0); +} + +$SIG{'INT'} = \&terminateNormally; +$SIG{'TERM'} = \&terminateNormally; +$SIG{'KILL'} = sub { exit(0); }; + +# This solution should be bad enough to be fixed immediately +# when feasible. + +while(<HANDLE>) +{ + if( $_ =~ /^[0-9]+:\s(.*)(@.*)\s<.*UP,.*>/ ) + { + print "Event event $1\n"; + my $intf_name = $1; + my $intf = new Vyatta::Interface($intf_name); + my $intf_addr_path = $intf->path() . " address"; + + # Get IPv6 addresses + my @addresses = grep /:/, $config->returnValues($intf_addr_path); + print Dumper(@addresses); + + foreach my $address (@addresses) + { + system("ip address add $address dev $intf_name"); + if( $? != 0 ) + { + syslog("err", "%s", "Could not add address $address: $!"); + } + else + { + syslog("notice", "%s", "Restoring address $address on interface $intf_name"); + } + } + + $intf = undef; + } +} + |