summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStig Thormodsrud <stig@vyatta.com>2008-07-22 18:36:45 -0700
committerStig Thormodsrud <stig@vyatta.com>2008-07-22 18:36:45 -0700
commitbdef00e75a4474a136f3bb2432c98d5ac338fcaa (patch)
tree4f4be157296b38b5e453b9d71ac7fccf1b76a39b
parent760876d8328880316720ebce2bdcc1b86372350c (diff)
downloadvyatta-cfg-vpn-bdef00e75a4474a136f3bb2432c98d5ac338fcaa.tar.gz
vyatta-cfg-vpn-bdef00e75a4474a136f3bb2432c98d5ac338fcaa.zip
Fix 3300: VPN over PPPOE completely fails on reboot
-rw-r--r--Makefile.am6
-rwxr-xr-xscripts/vpn-config.pl20
-rwxr-xr-xscripts/vpn-ppp-down35
-rwxr-xr-xscripts/vpn-ppp-up35
-rwxr-xr-xscripts/vyatta-vpn-ppp-updown.pl173
5 files changed, 265 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am
index ca00fae..a623854 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,6 +8,7 @@ curverdir = $(sysconfdir)/config-migrate/current
sbin_SCRIPTS =
sbin_SCRIPTS += scripts/vpn-config.pl
+sbin_SCRIPTS += scripts/vyatta-vpn-ppp-updown.pl
share_perl5_DATA = scripts/VyattaVPNUtil.pm
@@ -19,4 +20,7 @@ cpiop = find . ! -regex '\(.*~\|.*\.bak\|.*\.swp\|.*\#.*\#\)' -print0 | \
install-exec-hook:
mkdir -p $(DESTDIR)$(cfgdir)
cd templates; $(cpiop) $(DESTDIR)$(cfgdir)
-
+ mkdir -p $(DESTDIR)/etc/ppp/ip-up.d
+ mkdir -p $(DESTDIR)/etc/ppp/ip-down.d
+ cp scripts/vpn-ppp-up $(DESTDIR)/etc/ppp/ip-up.d/
+ cp scripts/vpn-ppp-down $(DESTDIR)/etc/ppp/ip-down.d/
diff --git a/scripts/vpn-config.pl b/scripts/vpn-config.pl
index 3a62a04..ad7cae1 100755
--- a/scripts/vpn-config.pl
+++ b/scripts/vpn-config.pl
@@ -221,6 +221,9 @@ if ($vcVPN->exists('ipsec')) {
$genout .= "\tinterfaces=\"";
my $counter = 0;
foreach my $interface (@interfaces) {
+ if (!(-d "/sys/class/net/$interface")) {
+ next;
+ }
if ($counter > 0) {
$genout .= ' ';
}
@@ -973,10 +976,21 @@ sub vpn_exec {
&& ($rval == 104 || $rval == 29)) {
print LOG "OK when bringing up VPN connection\n";
} else {
- $error = 1;
+ #
+ # We use to consider the commit failed if we got a error
+ # from the call to ipsec, but this causes the configuration
+ # to not get included in the running config. Now that
+ # we support dynamic interface/address (e.g. dhcp, pppoe)
+ # we want a valid config to get committed even if the
+ # interface doesn't exist yet. That way we can use
+ # "clear vpn ipsec-process" to bring up the tunnel once
+ # the interface is instantiated. For pppoe we will add
+ # a script to /etc/ppp/ip-up.d to bring up the vpn
+ # tunnel.
+ #
print LOG "VPN commit error. Unable to $desc, received error code $?\n";
- print STDERR "VPN commit error. Unable to $desc, received error code $?\n";
- print STDERR "$cmd_out\n";
+ print "Warning: unable to [$desc], received error code $?\n";
+ print "$cmd_out\n";
}
}
} else {
diff --git a/scripts/vpn-ppp-down b/scripts/vpn-ppp-down
new file mode 100755
index 0000000..d72681d
--- /dev/null
+++ b/scripts/vpn-ppp-down
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Module: vpn-ppp-down
+#
+# **** 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) 2006, 2007 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Authors: Stig Thormodsrud
+# Date: July 2008
+# Description: wrapper for vyatta-vpn-pppoe
+#
+# **** End License ****
+#
+
+# $1 Interface name ppp0
+# $2 The tty ttyS1
+# $3 The link speed 38400
+# $4 Local IP number 12.34.56.78
+# $5 Peer IP number 12.34.56.99
+# $6 Optional ``ipparam'' value foo
+
+source /etc/default/vyatta
+
+/opt/vyatta/sbin/vyatta-vpn-ppp-updown.pl $6 down
diff --git a/scripts/vpn-ppp-up b/scripts/vpn-ppp-up
new file mode 100755
index 0000000..1a72475
--- /dev/null
+++ b/scripts/vpn-ppp-up
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Module: vpn-ppp-up
+#
+# **** 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) 2006, 2007 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Authors: Stig Thormodsrud
+# Date: July 2008
+# Description: wrapper for vyatta-vpn-pppoe
+#
+# **** End License ****
+#
+
+# $1 Interface name ppp0
+# $2 The tty ttyS1
+# $3 The link speed 38400
+# $4 Local IP number 12.34.56.78
+# $5 Peer IP number 12.34.56.99
+# $6 Optional ``ipparam'' value foo
+
+source /etc/default/vyatta
+
+/opt/vyatta/sbin/vyatta-vpn-ppp-updown.pl $6 up
diff --git a/scripts/vyatta-vpn-ppp-updown.pl b/scripts/vyatta-vpn-ppp-updown.pl
new file mode 100755
index 0000000..5f440e9
--- /dev/null
+++ b/scripts/vyatta-vpn-ppp-updown.pl
@@ -0,0 +1,173 @@
+#!/usr/bin/perl -w
+#
+# Module: vyatta-vpn-pppoe
+#
+# **** 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) 2006, 2007 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Authors: Stig Thormodsrud
+# Date: July 2008
+# Description: bring up/down vpn tunnel for pppoe/pppoa interfaces
+#
+# **** End License ****
+#
+
+use lib "/opt/vyatta/share/perl5/";
+use VyattaConfig;
+use POSIX;
+use strict;
+use warnings;
+
+my $conf_file = '/etc/ipsec.conf';
+my $log_file = '/var/log/pppoe-vpn.log';
+
+
+sub logit {
+ my $timestamp = strftime("%Y%m%d-%H:%M.%S", localtime);
+ open my $fh, ">>", $log_file;
+ print $fh "$timestamp: ", @_ , "\n";
+ close $fh;
+}
+
+sub find_next_ipsec {
+ my $list = shift;
+
+ my $last = -1;
+
+ while ($list =~ s/ipsec([0-9]+)\=\w+\d+//) {
+ $last = $1 if $1 > $last;
+ }
+ return $last + 1;
+}
+
+sub is_dup {
+ my ($line, $intf) = @_;
+
+ while ($line =~ s/ipsec[0-9]+\=(\w+\d+)//) {
+ return 1 if $1 eq $intf;
+ }
+ return 0;
+}
+
+sub vpn_add_intf {
+ my ($line, $intf) = @_;
+
+ logit("UP $intf");
+
+ return (0, $line) if is_dup($line, $intf);
+
+ my $intf_list;
+ my $new_line;
+ my $defaultroute = '';
+ if ($line !~ /interfaces\=\"(.*)\"/) {
+ return (0, $line);
+ }
+ $intf_list = $1;
+ if ($intf_list =~ s/ \%defaultroute//) {
+ $defaultroute = ' %defaultroute';
+ }
+ my $ipsec_num = find_next_ipsec($intf_list);
+ $intf_list .= " ipsec$ipsec_num\=$intf";
+ $new_line = " interfaces=\"$intf_list$defaultroute\"";
+ return (1, $new_line);
+}
+
+sub vpn_remove_intf {
+ my ($line, $intf) = @_;
+
+ logit("DOWN $intf");
+ if ($line =~ s/ipsec[0-9]+\=$intf//) {
+ return (1, $line);
+ } else {
+ return (0, $line);
+ }
+
+}
+
+
+my $pppoe_intf = $ARGV[0];
+my $mode = $ARGV[1];
+
+my $config = new VyattaConfig;
+$config->setLevel("vpn ipsec ipsec-interfaces");
+my @ipsec_intfs = $config->returnOrigValues("interface");
+
+#
+# done if no vpn interfaces
+#
+exit 0 if scalar(@ipsec_intfs) == 0;
+
+my $found = 0;
+foreach my $intf (@ipsec_intfs) {
+ $found++ if $pppoe_intf eq $intf;
+}
+
+#
+# done if interface comming up isn't in vpn ipsec-interfaces
+#
+exit 0 if $found == 0;
+
+#
+# read current ipsec.conf
+#
+open(my $FD, '<', $conf_file)
+ or die "Can't open [$conf_file] for read";
+my @lines = <$FD>;
+close $FD;
+
+my @new_config = ();
+my $changed = 0;
+foreach my $line (@lines) {
+ if ($line =~ /interfaces=\"/) {
+ my $new_line;
+ if ($mode eq 'up') {
+ ($changed, $new_line) = vpn_add_intf($line, $pppoe_intf);
+ $new_line .= "\n";
+ } else {
+ ($changed, $new_line) = vpn_remove_intf($line, $pppoe_intf);
+ }
+ push @new_config, $new_line;
+ chomp $line; chomp $new_line;
+ logit("replacing [$line]");
+ logit("with [$new_line]");
+ } else {
+ push @new_config, $line;
+ }
+}
+
+exit 0 if $changed == 0;
+
+#
+# write out new ipsec.conf
+#
+my $tmp_conf = "/tmp/ipsec.conf.$$";
+open($FD, '>', $tmp_conf)
+ or die "Can't open [$tmp_conf] for write";
+print $FD @new_config;
+close $FD;
+
+my ($cmd, $rc);
+$cmd = "mv $tmp_conf $conf_file";
+$rc =system($cmd);
+logit("$cmd = $rc");
+$cmd = "/usr/sbin/ipsec setup --start 2> /dev/null";
+$rc =system($cmd);
+logit("$cmd = $rc");
+$cmd = "/usr/sbin/ipsec auto --rereadall 2> /dev/null";
+$rc = system($cmd);
+logit("$cmd = $rc");
+
+exit 0;
+
+# end of file