summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaurabh Mohan <saurabh@vyatta.com>2012-05-16 17:44:36 -0700
committerSaurabh Mohan <saurabh@vyatta.com>2012-05-16 17:44:36 -0700
commit2403afbb9b6b58877b6b8a8ae932ff06827be026 (patch)
tree30c974d191f20041eb952a7460ec278c9fc7ae4f
parente46d2937711e4fec4c09191cbdbbd9149206eb6d (diff)
downloadvyatta-cfg-vpn-2403afbb9b6b58877b6b8a8ae932ff06827be026.tar.gz
vyatta-cfg-vpn-2403afbb9b6b58877b6b8a8ae932ff06827be026.zip
Vti config support.
-rw-r--r--Makefile.am1
-rwxr-xr-xscripts/vpn-config.pl103
-rwxr-xr-xscripts/vyatta-vti-config.pl146
-rw-r--r--templates/vpn/ipsec/site-to-site/peer/node.tag/vti/bind/node.def3
-rw-r--r--templates/vpn/ipsec/site-to-site/peer/node.tag/vti/disable/node.def1
-rw-r--r--templates/vpn/ipsec/site-to-site/peer/node.tag/vti/esp-group/node.def3
-rw-r--r--templates/vpn/ipsec/site-to-site/peer/node.tag/vti/mark/node.def2
-rw-r--r--templates/vpn/ipsec/site-to-site/peer/node.tag/vti/node.def1
-rw-r--r--templates/vpn/node.def1
9 files changed, 236 insertions, 25 deletions
diff --git a/Makefile.am b/Makefile.am
index ca5db1a..f3c732d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,6 +12,7 @@ sbin_SCRIPTS =
sbin_SCRIPTS += scripts/vpn-config.pl
sbin_SCRIPTS += scripts/vyatta-vpn-ppp-updown.pl
sbin_SCRIPTS += scripts/is_valid_address.pl
+sbin_SCRIPTS += scripts/vyatta-vti-config.pl
bin_sudo_users_SCRIPTS = scripts/vyatta-ipsec-dhcp.pl
share_perl5_DATA = lib/Vyatta/VPN/Util.pm
diff --git a/scripts/vpn-config.pl b/scripts/vpn-config.pl
index e91d1cd..8f35e7e 100755
--- a/scripts/vpn-config.pl
+++ b/scripts/vpn-config.pl
@@ -394,6 +394,7 @@ if ( $vcVPN->exists('ipsec') ) {
. " remote-users configured\n";
}
my $prev_peer = "";
+ my %marks = ();
foreach my $peer (@peers) {
my $peer_ike_group =
$vcVPN->returnValue("ipsec site-to-site peer $peer ike-group");
@@ -487,37 +488,53 @@ if ( $vcVPN->exists('ipsec') ) {
#
# Name connection by peer and tunnel
#
+ my $isVti = 0;
my @tunnels = $vcVPN->listNodes("ipsec site-to-site peer $peer tunnel");
if ( @tunnels == 0 ) {
- vpn_die(["vpn", "ipsec", "site-to-site","peer",$peer,"tunnel"],
- "$vpn_cfg_err No tunnels configured for peer \"$peer\". At least"
- . " one tunnel required per peer.\n");
+ #
+ # Check if this is VTI
+ #
+ if ($vcVPN->exists("ipsec site-to-site peer $peer vti") ) {
+ $isVti = 1;
+ @tunnels = (@tunnels, "vti");
+ }
+ if (@tunnels == 0) {
+ vpn_die(["vpn", "ipsec", "site-to-site","peer",$peer,"tunnel"],
+ "$vpn_cfg_err No tunnels configured for peer \"$peer\". At least"
+ . " one tunnel required per peer.\n");
+ }
}
foreach my $tunnel (@tunnels) {
my $needs_passthrough = 'false';
+ my $tunKeyword;
+ if ($isVti == 1) {
+ $tunKeyword = 'vti';
+ } else {
+ $tunKeyword = 'tunnel '."$tunnel";
+ }
#
# Add support for tunnel disable.
#
if (
- $vcVPN->exists("ipsec site-to-site peer $peer tunnel $tunnel disable") )
+ $vcVPN->exists("ipsec site-to-site peer $peer $tunKeyword disable") )
{
next;
}
my $peer_tunnel_esp_group = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel esp-group");
+ "ipsec site-to-site peer $peer $tunKeyword esp-group");
$peer_tunnel_esp_group = '' if (!defined($peer_tunnel_esp_group));
if ( (!defined($peer_tunnel_esp_group) || $peer_tunnel_esp_group eq '') &&
(!defined($def_esp_group) || $def_esp_group eq '')) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel",$tunnel,"esp-group"],
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"esp-group"],
"$vpn_cfg_err No ESP group specified for peer \"$peer\" "
- . "tunnel $tunnel.\n");
+ . "$tunKeyword.\n");
} elsif ( !$vcVPN->exists("ipsec esp-group $peer_tunnel_esp_group") ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel",$tunnel,"esp-group"],
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"esp-group"],
"$vpn_cfg_err The ESP group \"$peer_tunnel_esp_group\" specified "
- . "for peer \"$peer\" tunnel $tunnel has not been configured.\n");
+ . "for peer \"$peer\" $tunKeyword has not been configured.\n");
}
my $conn_head = "\nconn peer-$peer-tunnel-$tunnel\n";
@@ -546,6 +563,11 @@ if ( $vcVPN->exists('ipsec') ) {
#
if ( defined($lip) ) {
if ( $lip eq 'any' ) {
+ if ($isVti) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,$tunKeyword,"local-address"],
+ "$vpn_cfg_err The local interface must be specified "
+ . "for peer \"$peer\" $tunKeyword.\n");
+ }
$genout .= "\tleft=%defaultroute\n";
# no need for leftsourceip as a defaultroute is must for this to work
} else {
@@ -555,6 +577,7 @@ if ( $vcVPN->exists('ipsec') ) {
$genout .= "\tleftid=$authid\n" if defined $authid;
}
+ # @SM Todo: must have explicit settings for VTI.
my $any_peer = 0;
my $right;
my $rightid = undef;
@@ -570,6 +593,11 @@ if ( $vcVPN->exists('ipsec') ) {
or ( $peer eq '0.0.0.0' )
or $any_peer == 1 )
{
+ if ($isVti) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer],
+ "$vpn_cfg_err The \"$peer\" is invalid "
+ . "ip address must be specified for $tunKeyword.\n");
+ }
$right = '%any';
$any_peer = 1;
} else {
@@ -585,8 +613,8 @@ if ( $vcVPN->exists('ipsec') ) {
# Write tunnel configuration
#
my $leftsubnet = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel local prefix");
- if ( defined($leftsubnet) && $leftsubnet eq 'any' ) {
+ "ipsec site-to-site peer $peer $tunKeyword local prefix");
+ if ( (defined($leftsubnet) && $leftsubnet eq 'any') || $isVti == 1 ) {
$leftsubnet = '0.0.0.0/0';
}
@@ -613,12 +641,15 @@ if ( $vcVPN->exists('ipsec') ) {
}
my $remotesubnet = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel remote prefix");
+ "ipsec site-to-site peer $peer $tunKeyword remote prefix");
+ if ($isVti) {
+ $remotesubnet = 'any';
+ }
# Check local and remote prefix protocol consistency
my $leftsubnet_proto = is_ip_v4_or_v6($leftsubnet);
my $remotesubnet_proto = is_ip_v4_or_v6($remotesubnet);
- if ($leftsubnet_proto != $remotesubnet_proto) {
+ if ( !$isVti && ($leftsubnet_proto != $remotesubnet_proto) ) {
vpn_die(["vpn", "ipsec", "site-to-site", "peer", $peer, "tunnel", $tunnel],
"$vpn_cfg_err The 'remote prefix' and 'local prefix' protocols ".
"do not match");
@@ -636,9 +667,9 @@ if ( $vcVPN->exists('ipsec') ) {
my $rightsubnet;
my $allow_nat_networks = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel allow-nat-networks");
+ "ipsec site-to-site peer $peer $tunKeyword allow-nat-networks");
my $allow_public_networks = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel allow-public-networks");
+ "ipsec site-to-site peer $peer $tunKeyword allow-public-networks");
if ( defined($allow_nat_networks) && $allow_nat_networks eq 'enable' ) {
if ( defined($remotesubnet) && $remotesubnet ne "" ) {
@@ -653,7 +684,7 @@ if ( $vcVPN->exists('ipsec') ) {
if ( @allowed_network == 0 ) {
vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
"$vpn_cfg_err While 'allow-nat-networks' has been enabled for peer"
- . " \"$peer\" tunnel $tunnel, no global allowed NAT networks have"
+ . " \"$peer\" $tunKeyword, no global allowed NAT networks have"
. " been configured.\n");
}
@@ -665,7 +696,7 @@ if ( $vcVPN->exists('ipsec') ) {
vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
"$vpn_cfg_err The 'remote-subnet' has been specified while "
. "'allow-public-networks' has been enabled for peer \"$peer\" "
- . "tunnel $tunnel. Both not allowed at once.\n");
+ . "$tunKeyword. Both not allowed at once.\n");
}
$rightsubnet .= ",%no";
}
@@ -696,13 +727,13 @@ if ( $vcVPN->exists('ipsec') ) {
# Protocol/port
#
my $protocol = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel protocol");
+ "ipsec site-to-site peer $peer $tunKeyword protocol");
my $lprotoport = '';
if (defined($protocol)){
$lprotoport .= $protocol;
}
my $lport = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel local port");
+ "ipsec site-to-site peer $peer $tunKeyword local port");
if (defined($lport)){
if (!defined($protocol)){
$lprotoport .= "0/$lport";
@@ -722,7 +753,7 @@ if ( $vcVPN->exists('ipsec') ) {
$rprotoport .= $protocol;
}
my $rport = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel remote port");
+ "ipsec site-to-site peer $peer $tunKeyword remote port");
if (defined($rport)){
if (!defined($protocol)){
$rprotoport .= "0/$rport";
@@ -742,7 +773,7 @@ if ( $vcVPN->exists('ipsec') ) {
# check if passthrough connection is needed
# needed when remote-subnet encompasses local-subnet
#
- if (defined $leftsubnet && defined $rightsubnet) {
+ if (!$isVti && defined $leftsubnet && defined $rightsubnet) {
# validate that these values are ipv4net
my $valid_leftsubnet = 'false';
my $valid_rightsubnet = 'false';
@@ -810,7 +841,7 @@ if ( $vcVPN->exists('ipsec') ) {
} elsif ( $dh_group ne '' ) {
vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
"$vpn_cfg_err Invalid 'dh-group' $dh_group specified for "
- . "peer \"$peer\" tunnel $tunnel. Only 2 or 5 accepted.\n");
+ . "peer \"$peer\" $tunKeyword. Only 2 or 5 accepted.\n");
}
}
}
@@ -852,7 +883,7 @@ if ( $vcVPN->exists('ipsec') ) {
my $esplifetime = ESPLIFETIME_DEFAULT;
$genout .= "\tesp=";
my $esp_group = $vcVPN->returnValue(
- "ipsec site-to-site peer $peer tunnel $tunnel esp-group");
+ "ipsec site-to-site peer $peer $tunKeyword esp-group");
if (!defined($esp_group) || $esp_group eq ''){
$esp_group = $vcVPN->returnValue(
"ipsec site-to-site peer $peer default-esp-group");
@@ -920,10 +951,14 @@ if ( $vcVPN->exists('ipsec') ) {
}
if ( $espmode eq "transport" ) {
if ( defined $leftsubnet or defined $rightsubnet ) {
- vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"tunnel", $tunnel],
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"$tunKeyword"],
"$vpn_cfg_err Can not use local-subnet or remote-subnet when "
. "using transport mode\n");
}
+ if ( $isVti == 1) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"$tunKeyword"],
+ "$vpn_cfg_err Can not use transport mode for \"$peer\" with vti\n");
+ }
}
$genout .= "\ttype=$espmode\n";
@@ -1094,6 +1129,25 @@ if ( $vcVPN->exists('ipsec') ) {
}
#
+ # Mark setting for vti.
+ #
+ if ($isVti) {
+ my $mark = $vcVPN->returnValue("ipsec site-to-site peer $peer vti mark");
+ if (!defined($mark) || $mark eq '' || $mark eq "0") {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"vti","mark"],
+ "$vpn_cfg_err No mark specified for peer \"$peer\" vti\n");
+ } else {
+ if (defined($marks{ $mark })) {
+ vpn_die(["vpn","ipsec","site-to-site","peer",$peer,"vti","mark"],
+ "$vpn_cfg_err vti mark $mark already used.\n");
+ } else {
+ $marks{ $mark } = 1;
+ $genout .= "\tmark=$mark\n";
+ }
+ }
+ }
+
+ #
# Start automatically
#
if ($any_peer) {
@@ -1136,7 +1190,6 @@ if ( $vcVPN->exists('ipsec') ) {
$genout .= "#$passthrough_conn_head";
}
-
}
}
} else {
diff --git a/scripts/vyatta-vti-config.pl b/scripts/vyatta-vti-config.pl
new file mode 100755
index 0000000..94c2edf
--- /dev/null
+++ b/scripts/vyatta-vti-config.pl
@@ -0,0 +1,146 @@
+#!/usr/bin/perl -w
+#
+# Module: vpn-config.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) 2006, 2007, 2008, 2009 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Authors: Justin Fletcher, Marat Nepomnyashy
+# Date: 2012
+# Description: setup the vti tunnel
+#
+# **** End License ****
+#
+#
+# For each VTI tunnel (vpn ipsec site-to-site peer ip-address sti); find the vti tunnel, local address, mark.
+# Find the corresponding tunnel (interfaces vti vtiXXX), tunnel address, disable, mtu
+# if not configured: ip tunnel add vtiXXX mode esp local $local remote $remote i_key $mark
+# if (mtu): configure mtu
+# if (tunnel-addres): configur ip link vtiXXX address
+# if (!disable): enable the interface.
+#
+
+use strict;
+use lib "/opt/vyatta/share/perl5";
+
+use Vyatta::TypeChecker;
+use Vyatta::VPN::Util;
+use Getopt::Long;
+use Vyatta::Misc;
+use NetAddr::IP;
+
+
+my $vti_cfg_err = "VPN VTI configuration error:";
+my $gencmds = "";
+my $result = 0;
+
+#
+# Prepare Vyatta::Config object
+#
+use Vyatta::Config;
+my $vcIntf = new Vyatta::Config();
+my $vcVPN = new Vyatta::Config();
+$vcVPN->setLevel('vpn');
+$vcIntf->setLevel('interfaces');
+
+if (!$vcVPN->exists('ipsec') ) {
+ exit $result;
+}
+if (!$vcVPN->exists('ipsec site-to-site') ) {
+ exit $result;
+}
+
+my @peers = $vcVPN->listNodes('ipsec site-to-site peer');
+if (@peers == 0) {
+ exit $result;
+}
+ foreach my $peer (@peers) {
+ if (! $vcVPN->exists("ipsec site-to-site peer $peer vti")) {
+ next;
+ }
+ #
+ # we have the vti configured.
+ #
+ my $lip = $vcVPN->returnValue("ipsec site-to-site peer $peer local-address");
+ my $mark = $vcVPN->returnValue("ipsec site-to-site peer $peer vti mark");
+ my $tunName = $vcVPN->returnValue("ipsec site-to-site peer $peer vti bind");
+
+ # Check local address is valid.
+ if (!defined($lip)) {
+ print STDERR "$vti_cfg_err local-address not defined.\n";
+ exit -1;
+ }
+
+ if ($lip eq "" || $lip eq "0.0.0.0") {
+ print STDERR "$vti_cfg_err Invalid local-address \"$lip\".\n";
+ exit -1;
+ }
+ # Check mark is valid.
+ if (!defined($mark) || $mark eq "" || $mark eq "0") {
+ print STDERR "$vti_cfg_err Invalid mark \"$mark\".\n";
+ exit -1;
+ }
+ # Check tunName is valid.
+ if (!defined($tunName) || $tunName eq "" || ! $vcIntf->exists("vti $tunName") ) {
+ print STDERR "$vti_cfg_err Invalid tunnel name vti \"$tunName\".\n";
+ exit -1;
+ }
+ #
+ # Get the tunnel parameters.
+ #
+ # ip address's
+ my @tunIPs = $vcIntf->returnValues("vti $tunName address");
+ # mtu
+ my $mtu = $vcIntf->returnValue("vti $tunName mtu");
+ if (!defined($mtu) || $mtu eq "") {
+ $mtu = 1500;
+ }
+ # disabled or not.
+ my $disabled = $vcIntf->exists("vti $tunName disabled");
+ #my $exists = `ls -l /sys/class/net/$tunName &> /dev/null`;
+
+ # description.
+ my $description = $vcIntf->returnValue("vti $tunName description");
+
+ #
+ # Set the configuration into the output string.
+ #
+ # By default we delete the tunnel...
+ $gencmds .= "sudo /sbin/ip tunnel del $tunName &> /dev/null\n";
+ $gencmds .= "sudo /sbin/ip tunnel add $tunName mode esp remote $peer local $lip ikey $mark\n";
+ foreach my $tunIP (@tunIPs) {
+ $gencmds .= "sudo /sbin/ip addr add $tunIP dev $tunName\n";
+ }
+ $gencmds .= "sudo /sbin/ip link set $tunName mtu $mtu\n";
+
+ if (! $disabled) {
+ # @SM TODO: Don not bring the tunnel link-state up till strongswan does it.
+ $gencmds .= "sudo /sbin/ip link set $tunName up\n";
+ # @SM TODO: Add the static routes over this tunnel...
+ }
+ if (defined($description)) {
+ $gencmds .= "sudo /sbin/ip tunnel show $tunName || sudo echo \"$description\" > /sys/class/net/$tunName/ifalias\n";
+ }
+ }
+
+if ($gencmds ne "") {
+ open my $output_config, '>', '/tmp/vti_config' or die "Can't open /tmp/vti_config $!";
+ print ${output_config} "#!/bin/sh\n";
+ print ${output_config} $gencmds;
+ close $output_config;
+ `chmod 755 /tmp/vti_config`;
+ #$result=`/tmp/vti_config`;
+ #@SM TODO: remove /tmp/vti_config;
+}
+exit $result;
diff --git a/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/bind/node.def b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/bind/node.def
new file mode 100644
index 0000000..01bb112
--- /dev/null
+++ b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/bind/node.def
@@ -0,0 +1,3 @@
+type: txt
+help: VTI tunnel interface associated with this configuration [REQUIRED]
+allowed: cli-shell-api listActiveNodes interfaces vti
diff --git a/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/disable/node.def b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/disable/node.def
new file mode 100644
index 0000000..b797d44
--- /dev/null
+++ b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/disable/node.def
@@ -0,0 +1 @@
+help: Option to disable vpn tunnel
diff --git a/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/esp-group/node.def b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/esp-group/node.def
new file mode 100644
index 0000000..700d0ee
--- /dev/null
+++ b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/esp-group/node.def
@@ -0,0 +1,3 @@
+help: ESP group name [REQUIRED]
+type: txt
+allowed: cli-shell-api listActiveNodes vpn ipsec esp-group
diff --git a/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/mark/node.def b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/mark/node.def
new file mode 100644
index 0000000..1d29970
--- /dev/null
+++ b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/mark/node.def
@@ -0,0 +1,2 @@
+type: u32
+help: Mark associated with the secure tunnel interface [REQUIRED]
diff --git a/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/node.def b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/node.def
new file mode 100644
index 0000000..2915f9e
--- /dev/null
+++ b/templates/vpn/ipsec/site-to-site/peer/node.tag/vti/node.def
@@ -0,0 +1 @@
+help: Virtual tunnel interface [REQUIRED]
diff --git a/templates/vpn/node.def b/templates/vpn/node.def
index f16f39a..8adc512 100644
--- a/templates/vpn/node.def
+++ b/templates/vpn/node.def
@@ -6,3 +6,4 @@ end:sudo /opt/vyatta/sbin/vpn-config.pl \
--init_script='/etc/init.d/ipsec' || exit 1
sudo /opt/vyatta/sbin/vyatta-update-l2tp.pl || exit 1
sudo /opt/vyatta/sbin/vyatta-update-pptp.pl || exit 1
+ sudo /opt/vyatta/sbin/vyatta-vti-config.pl || exit 1