summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzsdc <taras@vyos.io>2020-05-04 16:24:57 +0300
committerzsdc <taras@vyos.io>2020-05-04 16:24:57 +0300
commit00825afd79a45977698e25f31db65fc60d96628f (patch)
tree7943022c7336f9f535ac92d4cce3a86fdb28228e
parent64ebf2127d62165870e03653659116e381d1582e (diff)
downloadvyatta-cfg-vpn-00825afd79a45977698e25f31db65fc60d96628f.tar.gz
vyatta-cfg-vpn-00825afd79a45977698e25f31db65fc60d96628f.zip
VTI: T1291: Fix for invlid VTI interface down state
In case when between hosts exists two IPSec tunnels for VTI (for example, when both sides act as connection initiators), the older unused/replaced tunnel may switch VTI interface to the "down" state even if a newer IPSec connection is still in-use. Depending on other IPSec settings, this leads to a situation when VTI interfaces continuously flapping or stuck in a "down" state. This fix is an adaptation of PR from @m-asama for the current code base. It adding new dependency from actual SA state of IPSec connection, and do not allow to switch down a VTI interface if at least one of child connections is active or try to change the state of a VTI interface to the same, as already active.
-rwxr-xr-xscripts/vti-up-down7
-rwxr-xr-xscripts/vyatta-vti-config.pl22
2 files changed, 21 insertions, 8 deletions
diff --git a/scripts/vti-up-down b/scripts/vti-up-down
index 08e31c0..4672076 100755
--- a/scripts/vti-up-down
+++ b/scripts/vti-up-down
@@ -5,15 +5,14 @@
source /etc/default/vyatta
source /etc/default/locale
case "$PLUTO_VERB" in
-route-client | up-client | up-host)
+up-client | up-host)
/bin/ip route delete default table 220
-/opt/vyatta/sbin/vyatta-vti-config.pl --updown --intf=$1 --action=up
+/opt/vyatta/sbin/vyatta-vti-config.pl --updown --intf=$1 --conn=$PLUTO_CONNECTION --action=up > /dev/null 2>&1 &
;;
down-client | down-host)
-/opt/vyatta/sbin/vyatta-vti-config.pl --updown --intf=$1 --action=down
+/opt/vyatta/sbin/vyatta-vti-config.pl --updown --intf=$1 --conn=$PLUTO_CONNECTION --action=down > /dev/null 2>&1 &
;;
*)
;;
esac
exit 0
-
diff --git a/scripts/vyatta-vti-config.pl b/scripts/vyatta-vti-config.pl
index 0886202..0318b22 100755
--- a/scripts/vyatta-vti-config.pl
+++ b/scripts/vyatta-vti-config.pl
@@ -45,29 +45,35 @@ my $gencmds = "";
my $result = 0;
my $updown="";
my $intfName="";
+my $conn_name="";
my $action="";
my $checkref="";
GetOptions(
"updown" => \$updown,
"intf=s" => \$intfName,
+ "conn=s" => \$conn_name,
"action=s" => \$action,
"checkref" => \$checkref,
);
#
-# --updown intfName --action=[up|down]
+# --updown --intf=vtiX --conn=peer-X.X.X.X-tunnel-vti --action=[up|down]
#
if ($updown ne '') {
if (!(defined $intfName) || $intfName eq '') {
# invalid
exit -1;
}
+ if (!(defined $conn_name) || $conn_name eq '' || $conn_name !~ m/^peer-[a-zA-Z0-9_.:-]+-tunnel-vti$/) {
+ # invalid
+ exit -1;
+ }
if (!(defined $action) || $action eq '') {
# invalid
exit -1;
}
- vti_handle_updown($intfName, $action);
+ vti_handle_updown($intfName, $conn_name, $action);
exit 0;
}
@@ -230,7 +236,7 @@ exit $result;
# Handle VTI tunnel state based on input from strongswan and configuration.
#
sub vti_handle_updown {
- my ($intfName, $action) = @_;
+ my ($intfName, $conn_name, $action) = @_;
my $vcIntf = new Vyatta::Config();
$vcIntf->setLevel('interfaces');
my $disabled = $vcIntf->existsOrig("vti $intfName disabled");
@@ -254,7 +260,15 @@ sub vti_handle_updown {
}
}
}
- system("sudo /sbin/ip link set $intfName $action\n");
+ # check if child SA is in ISTALLED state (connection already fully established)
+ # we are inverting exit code to convert 0 value to True in Perl
+ my $child_sa_installed = !system("sudo swanctl -l -r -i $conn_name | grep -s -q state=INSTALLED");
+ # change interface state only if one of these is true:
+ # - VTI interface is in UP state, no active child SA was found, and event is down-client or down-host
+ # - VTI interface is in DOWN state, active child SA was found, and event is up-client or up-host
+ if (($state && !$child_sa_installed && ($action eq "down")) || (!$state && $child_sa_installed && ($action eq "up"))) {
+ system("sudo /sbin/ip link set $intfName $action\n");
+ }
}
}
}