misc: add ikev2 tests usecases

Type: test
Ticket: VPP-1893

Change-Id: Ib6ffd00e73f7110bf9e702f4a0fd5c68395d6786
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
diff --git a/extras/strongswan/README.md b/extras/strongswan/README.md
new file mode 100644
index 0000000..58cbcd9
--- /dev/null
+++ b/extras/strongswan/README.md
@@ -0,0 +1,23 @@
+## vpp-sswan-test
+
+Simple test framework for VPP and strongSwan scenarios.
+
+## setup and run
+
+`docker` is needed to run the tests.
+
+Create `~/.vpp_sswan` file and set `VPP_BIN` and `VPPCTL` variables that points to vpp and vppctl binaries, like follows:
+```
+export VPP_BIN=/path/to/vpp
+export VPPCTL=/path/to/vppctl
+```
+
+To run all test
+```
+./run.sh
+```
+
+or specific test
+```
+./test_responder.sh
+```
diff --git a/extras/strongswan/configs/initiator/ipsec.conf b/extras/strongswan/configs/initiator/ipsec.conf
new file mode 100644
index 0000000..6a7c0f6
--- /dev/null
+++ b/extras/strongswan/configs/initiator/ipsec.conf
@@ -0,0 +1,22 @@
+config setup
+  strictcrlpolicy=no
+
+conn initiator
+  mobike=no
+  auto=add
+  type=tunnel
+  keyexchange=ikev2
+  ike=aes256gcm16-prfsha256-modp2048!
+  esp=aes256gcm16-esn!
+
+# local:
+  leftauth=psk
+  leftid=@sswan.vpn.example.com
+  leftsubnet=192.168.5.0/24
+
+# remote: (gateway)
+  rightid=@roadwarrior.vpp
+  right=192.168.10.2
+  rightauth=psk
+  rightsubnet=192.168.3.0/24
+
diff --git a/extras/strongswan/configs/initiator/ipsec.secrets b/extras/strongswan/configs/initiator/ipsec.secrets
new file mode 100644
index 0000000..adcf951
--- /dev/null
+++ b/extras/strongswan/configs/initiator/ipsec.secrets
@@ -0,0 +1 @@
+: PSK 'Vpp123'
diff --git a/extras/strongswan/configs/initiator/vpp.conf b/extras/strongswan/configs/initiator/vpp.conf
new file mode 100644
index 0000000..36352aa
--- /dev/null
+++ b/extras/strongswan/configs/initiator/vpp.conf
@@ -0,0 +1,30 @@
+create host-interface name vpp
+set interface ip addr host-vpp 192.168.10.2/24
+set interface state host-vpp up
+
+create host-interface name priv
+set interface ip addr host-priv 192.168.3.1/24
+set interface state host-priv up
+
+ikev2 profile add pr1
+ikev2 profile set pr1 auth shared-key-mic string Vpp123
+ikev2 profile set pr1 id local fqdn roadwarrior.vpp
+ikev2 profile set pr1 id remote fqdn sswan.vpn.example.com
+
+ikev2 profile set pr1 traffic-selector local ip-range 192.168.3.0 - 192.168.3.255 port-range 0 - 65535 protocol 0
+ikev2 profile set pr1 traffic-selector remote ip-range 192.168.5.0 - 192.168.5.255 port-range 0 - 65535 protocol 0
+
+ikev2 profile set pr1 responder host-vpp 192.168.10.1
+ikev2 profile set pr1 ike-crypto-alg aes-gcm-16 256 ike-dh modp-2048
+ikev2 profile set pr1 esp-crypto-alg aes-gcm-16 256
+
+event-logger clear
+trace add af-packet-input 100
+
+create ipip tunnel src 192.168.10.2 dst 192.168.10.1
+ikev2 profile set pr1 tunnel ipip0
+ip route add 192.168.5.0/24 via 192.168.10.1 ipip0
+set interface unnumbered ipip0 use host-vpp
+
+ikev2 set liveness 30 4
+ikev2 set logging level 4
diff --git a/extras/strongswan/configs/responder/ipsec.conf b/extras/strongswan/configs/responder/ipsec.conf
new file mode 100644
index 0000000..7ca0d41
--- /dev/null
+++ b/extras/strongswan/configs/responder/ipsec.conf
@@ -0,0 +1,23 @@
+config setup
+  strictcrlpolicy=no
+
+conn initiator
+  mobike=no
+  auto=add
+  type=tunnel
+  keyexchange=ikev2
+  ike=aes256gcm16-prfsha256-modp2048!
+  esp=aes256gcm16-esn!
+  lifetime=1h
+
+# local:
+  leftauth=psk
+  leftid=@roadwarrior.vpn.example.com
+  leftsubnet=192.168.5.0/24
+
+# remote: (gateway)
+  rightid=@vpp.home
+  right=192.168.10.2
+  rightauth=psk
+  rightsubnet=192.168.3.0/24
+
diff --git a/extras/strongswan/configs/responder/ipsec.secrets b/extras/strongswan/configs/responder/ipsec.secrets
new file mode 100644
index 0000000..adcf951
--- /dev/null
+++ b/extras/strongswan/configs/responder/ipsec.secrets
@@ -0,0 +1 @@
+: PSK 'Vpp123'
diff --git a/extras/strongswan/configs/responder/vpp.conf b/extras/strongswan/configs/responder/vpp.conf
new file mode 100644
index 0000000..291b817
--- /dev/null
+++ b/extras/strongswan/configs/responder/vpp.conf
@@ -0,0 +1,26 @@
+create host-interface name vpp
+set interface ip addr host-vpp 192.168.10.2/24
+set interface state host-vpp up
+
+create host-interface name priv
+set interface ip addr host-priv 192.168.3.1/24
+set interface state host-priv up
+
+ikev2 profile add pr1
+ikev2 profile set pr1 auth shared-key-mic string Vpp123
+ikev2 profile set pr1 id local fqdn vpp.home
+ikev2 profile set pr1 id remote fqdn roadwarrior.vpn.example.com
+
+ikev2 profile set pr1 traffic-selector local ip-range 192.168.3.0 - 192.168.3.255 port-range 0 - 65535 protocol 0
+ikev2 profile set pr1 traffic-selector remote ip-range 192.168.5.0 - 192.168.5.255 port-range 0 - 65535 protocol 0
+
+event-logger clear
+trace add af-packet-input 100
+
+create ipip tunnel src 192.168.10.2 dst 192.168.10.1
+ikev2 profile set pr1 tunnel ipip0
+ip route add 192.168.5.0/24 via 192.168.10.1 ipip0
+set interface unnumbered ipip0 use host-vpp
+
+ikev2 set liveness 30 4
+ikev2 set logging level 4
diff --git a/extras/strongswan/configs/responder_keepalive/ipsec.conf b/extras/strongswan/configs/responder_keepalive/ipsec.conf
new file mode 100644
index 0000000..7ca0d41
--- /dev/null
+++ b/extras/strongswan/configs/responder_keepalive/ipsec.conf
@@ -0,0 +1,23 @@
+config setup
+  strictcrlpolicy=no
+
+conn initiator
+  mobike=no
+  auto=add
+  type=tunnel
+  keyexchange=ikev2
+  ike=aes256gcm16-prfsha256-modp2048!
+  esp=aes256gcm16-esn!
+  lifetime=1h
+
+# local:
+  leftauth=psk
+  leftid=@roadwarrior.vpn.example.com
+  leftsubnet=192.168.5.0/24
+
+# remote: (gateway)
+  rightid=@vpp.home
+  right=192.168.10.2
+  rightauth=psk
+  rightsubnet=192.168.3.0/24
+
diff --git a/extras/strongswan/configs/responder_keepalive/ipsec.secrets b/extras/strongswan/configs/responder_keepalive/ipsec.secrets
new file mode 100644
index 0000000..adcf951
--- /dev/null
+++ b/extras/strongswan/configs/responder_keepalive/ipsec.secrets
@@ -0,0 +1 @@
+: PSK 'Vpp123'
diff --git a/extras/strongswan/configs/responder_keepalive/vpp.conf b/extras/strongswan/configs/responder_keepalive/vpp.conf
new file mode 100644
index 0000000..f3f8470
--- /dev/null
+++ b/extras/strongswan/configs/responder_keepalive/vpp.conf
@@ -0,0 +1,26 @@
+create host-interface name vpp
+set interface ip addr host-vpp 192.168.10.2/24
+set interface state host-vpp up
+
+create host-interface name priv
+set interface ip addr host-priv 192.168.3.1/24
+set interface state host-priv up
+
+ikev2 profile add pr1
+ikev2 profile set pr1 auth shared-key-mic string Vpp123
+ikev2 profile set pr1 id local fqdn vpp.home
+ikev2 profile set pr1 id remote fqdn roadwarrior.vpn.example.com
+
+ikev2 profile set pr1 traffic-selector local ip-range 192.168.3.0 - 192.168.3.255 port-range 0 - 65535 protocol 0
+ikev2 profile set pr1 traffic-selector remote ip-range 192.168.5.0 - 192.168.5.255 port-range 0 - 65535 protocol 0
+
+event-logger clear
+trace add af-packet-input 100
+
+create ipip tunnel src 192.168.10.2 dst 192.168.10.1
+ikev2 profile set pr1 tunnel ipip0
+ip route add 192.168.5.0/24 via 192.168.10.1 ipip0
+set interface unnumbered ipip0 use host-vpp
+
+ikev2 set liveness 10 2
+ikev2 set logging level 4
diff --git a/extras/strongswan/configs/responder_nat/ipsec.conf b/extras/strongswan/configs/responder_nat/ipsec.conf
new file mode 100644
index 0000000..00ebd21
--- /dev/null
+++ b/extras/strongswan/configs/responder_nat/ipsec.conf
@@ -0,0 +1,22 @@
+config setup
+  strictcrlpolicy=no
+
+conn initiator
+  mobike=no
+  auto=add
+  type=tunnel
+  keyexchange=ikev2
+  ike=aes256gcm16-prfsha256-modp2048!
+  esp=aes256gcm16-esn!
+
+# local:
+  leftauth=psk
+  leftid=@roadwarrior.vpn.example.com
+  leftsubnet=192.168.5.0/24
+
+# remote: (gateway)
+  rightid=@vpp.home
+  right=192.168.10.2
+  rightauth=psk
+  rightsubnet=192.168.3.0/24
+
diff --git a/extras/strongswan/configs/responder_nat/ipsec.secrets b/extras/strongswan/configs/responder_nat/ipsec.secrets
new file mode 100644
index 0000000..adcf951
--- /dev/null
+++ b/extras/strongswan/configs/responder_nat/ipsec.secrets
@@ -0,0 +1 @@
+: PSK 'Vpp123'
diff --git a/extras/strongswan/configs/responder_nat/vpp.conf b/extras/strongswan/configs/responder_nat/vpp.conf
new file mode 100644
index 0000000..9ba3fdf
--- /dev/null
+++ b/extras/strongswan/configs/responder_nat/vpp.conf
@@ -0,0 +1,44 @@
+create host-interface name vpp
+create host-interface name priv
+pipe create
+
+set interface ip addr host-vpp 192.168.10.2/24
+set interface state host-vpp up
+
+ip table add 1
+set int ip table host-priv 1
+set int ip table pipe0.1 1
+
+set interface ip addr host-priv 192.168.3.1/24
+set interface state host-priv up
+
+set int ip address pipe0.0 10.0.0.1/24
+set int ip address pipe0.1 10.0.0.2/24
+set int state pipe0 up
+
+ikev2 profile add pr1
+ikev2 profile set pr1 auth shared-key-mic string Vpp123
+ikev2 profile set pr1 id local fqdn vpp.home
+ikev2 profile set pr1 id remote fqdn roadwarrior.vpn.example.com
+ikev2 profile set pr1 traffic-selector local ip-range 192.168.3.0 - 192.168.3.255 port-range 0 - 65535 protocol 0
+ikev2 profile set pr1 traffic-selector remote ip-range 192.168.5.0 - 192.168.5.255 port-range 0 - 65535 protocol 0
+
+ip route add table 1 192.168.10.0/24 via 10.0.0.1 pipe0.1
+
+create ipip tunnel src 10.0.0.2 dst 192.168.10.1 outer-table-id 1
+set interface ip table ipip0 1
+
+ikev2 profile set pr1 tunnel ipip0
+ip route add table 1 192.168.5.0/24 via ipip0
+set interface unnumbered ipip0 use pipe0.1
+
+nat44 enable sessions 10
+nat44 add address 192.168.10.2
+set interface nat44 in pipe0.0 out host-vpp
+nat44 add static mapping udp local 10.0.0.2 500 external 192.168.10.2 500
+nat44 add static mapping udp local 10.0.0.2 4500 external 192.168.10.2 4500
+
+event-logger clear
+trace add af-packet-input 100
+ikev2 set liveness 10 2
+ikev2 set logging level 4
diff --git a/extras/strongswan/configs/responder_vrf/ipsec.secrets b/extras/strongswan/configs/responder_vrf/ipsec.secrets
new file mode 100644
index 0000000..adcf951
--- /dev/null
+++ b/extras/strongswan/configs/responder_vrf/ipsec.secrets
@@ -0,0 +1 @@
+: PSK 'Vpp123'
diff --git a/extras/strongswan/configs/responder_vrf/ipsec1.conf b/extras/strongswan/configs/responder_vrf/ipsec1.conf
new file mode 100644
index 0000000..0291b8e
--- /dev/null
+++ b/extras/strongswan/configs/responder_vrf/ipsec1.conf
@@ -0,0 +1,23 @@
+config setup
+  strictcrlpolicy=no
+
+conn initiator
+  mobike=no
+  auto=add
+  type=tunnel
+  keyexchange=ikev2
+  ike=aes256gcm16-prfsha256-modp2048!
+  esp=aes256gcm16-esn!
+  lifetime=1m
+
+# local:
+  leftauth=psk
+  leftid=@roadwarrior1.vpn.example.com
+  leftsubnet=192.168.5.0/24
+
+# remote: (gateway)
+  rightid=@vpp.home
+  right=192.168.10.2
+  rightauth=psk
+  rightsubnet=192.168.3.0/24
+
diff --git a/extras/strongswan/configs/responder_vrf/ipsec2.conf b/extras/strongswan/configs/responder_vrf/ipsec2.conf
new file mode 100644
index 0000000..c96c1ff
--- /dev/null
+++ b/extras/strongswan/configs/responder_vrf/ipsec2.conf
@@ -0,0 +1,23 @@
+config setup
+  strictcrlpolicy=no
+
+conn initiator
+  mobike=no
+  auto=add
+  type=tunnel
+  keyexchange=ikev2
+  ike=aes256gcm16-prfsha256-modp2048!
+  esp=aes256gcm16-esn!
+  lifetime=1m
+
+# local:
+  leftauth=psk
+  leftid=@roadwarrior2.vpn.example.com
+  leftsubnet=192.168.5.0/24
+
+# remote: (gateway)
+  rightid=@vpp.home
+  right=192.168.10.2
+  rightauth=psk
+  rightsubnet=192.168.3.0/24
+
diff --git a/extras/strongswan/configs/responder_vrf/vpp.conf b/extras/strongswan/configs/responder_vrf/vpp.conf
new file mode 100644
index 0000000..1b32226
--- /dev/null
+++ b/extras/strongswan/configs/responder_vrf/vpp.conf
@@ -0,0 +1,48 @@
+ip table add 1
+
+create host-interface name gw1
+set interface ip addr host-gw1 192.168.10.2/24
+set interface state host-gw1 up
+
+create host-interface name gw2
+set int ip table host-gw2 1
+set interface ip addr host-gw2 192.168.10.2/24
+set interface state host-gw2 up
+
+create host-interface name priv1
+set interface ip addr host-priv1 192.168.3.1/24
+set interface state host-priv1 up
+
+create host-interface name priv2
+set int ip table host-priv2 1
+set interface ip addr host-priv2 192.168.3.1/24
+set interface state host-priv2 up
+
+ikev2 profile add pr1
+ikev2 profile set pr1 auth shared-key-mic string Vpp123
+ikev2 profile set pr1 id local fqdn vpp.home
+ikev2 profile set pr1 id remote fqdn roadwarrior1.vpn.example.com
+ikev2 profile set pr1 traffic-selector local ip-range 192.168.3.0 - 192.168.3.255 port-range 0 - 65535 protocol 0
+ikev2 profile set pr1 traffic-selector remote ip-range 192.168.5.0 - 192.168.5.255 port-range 0 - 65535 protocol 0
+create ipip tunnel src 192.168.10.2 dst 192.168.10.1
+ikev2 profile set pr1 tunnel ipip0
+ip route add 192.168.5.0/24 via 192.168.10.1 ipip0
+set interface unnumbered ipip0 use host-gw1
+
+ikev2 profile add pr2
+ikev2 profile set pr2 auth shared-key-mic string Vpp123
+ikev2 profile set pr2 id local fqdn vpp.home
+ikev2 profile set pr2 id remote fqdn roadwarrior2.vpn.example.com
+ikev2 profile set pr2 traffic-selector local ip-range 192.168.3.0 - 192.168.3.255 port-range 0 - 65535 protocol 0
+ikev2 profile set pr2 traffic-selector remote ip-range 192.168.5.0 - 192.168.5.255 port-range 0 - 65535 protocol 0
+create ipip tunnel src 192.168.10.2 dst 192.168.10.1 outer-table-id 1
+set interface ip table ipip1 1
+ikev2 profile set pr2 tunnel ipip1
+ip route add table 1 192.168.5.0/24 via 192.168.10.1 ipip1
+set interface unnumbered ipip1 use host-gw2
+
+ikev2 set liveness 300 4
+ikev2 set logging level 4
+event-logger clear
+trace add af-packet-input 100
+
diff --git a/extras/strongswan/configs/strongswan.conf b/extras/strongswan/configs/strongswan.conf
new file mode 100644
index 0000000..9a6e2f2
--- /dev/null
+++ b/extras/strongswan/configs/strongswan.conf
@@ -0,0 +1,16 @@
+charon {
+  load_modular = yes
+  plugins {
+    include strongswan.d/charon/*.conf
+  }
+  filelog {
+    /tmp/charon.log {
+      time_format = %b %e %T
+      ike_name = yes
+      append = no
+      default = 2
+      flush_line = yes
+    }
+  }
+}
+include strongswan.d/*.conf
diff --git a/extras/strongswan/run.sh b/extras/strongswan/run.sh
new file mode 100755
index 0000000..a185514
--- /dev/null
+++ b/extras/strongswan/run.sh
@@ -0,0 +1,26 @@
+print_help() {
+  echo "vpp/strongswan tests"
+}
+
+count=0
+test_num=`ls -l test_* | wc -l`
+
+for test_case in test_*
+do
+  let "count=$count + 1"
+
+  base_name=`basename -a "$test_case"`
+  printf "%2d/%d : %-48s" $count $test_num "$base_name"
+  logger "test start $base_name"
+
+  bash $test_case  &> /dev/null
+  rc=$?
+
+  if [ $rc -ne 0 ] ; then
+    printf "failed!\n"
+  else
+    printf "passed.\n"
+  fi
+done
+
+exit 0
diff --git a/extras/strongswan/test_initiator.sh b/extras/strongswan/test_initiator.sh
new file mode 100755
index 0000000..ae1fa02
--- /dev/null
+++ b/extras/strongswan/test_initiator.sh
@@ -0,0 +1,5 @@
+. topos/basic.sh
+
+TC_DIR=initiator
+
+run_initiator_test
diff --git a/extras/strongswan/test_responder.sh b/extras/strongswan/test_responder.sh
new file mode 100755
index 0000000..486b6f9
--- /dev/null
+++ b/extras/strongswan/test_responder.sh
@@ -0,0 +1,5 @@
+. topos/basic.sh
+
+TC_DIR=responder
+
+run_responder_test
diff --git a/extras/strongswan/test_responder_keepalive.sh b/extras/strongswan/test_responder_keepalive.sh
new file mode 100755
index 0000000..5be7722
--- /dev/null
+++ b/extras/strongswan/test_responder_keepalive.sh
@@ -0,0 +1,12 @@
+. topos/basic.sh
+
+TC_DIR=responder_keepalive
+
+config_topo
+initiate_from_sswan
+
+test_ping
+sleep 30
+test_ping
+
+unconf_topo
diff --git a/extras/strongswan/test_responder_nat.sh b/extras/strongswan/test_responder_nat.sh
new file mode 100755
index 0000000..06f4f7f
--- /dev/null
+++ b/extras/strongswan/test_responder_nat.sh
@@ -0,0 +1,5 @@
+. topos/basic.sh
+
+TC_DIR=responder_nat
+
+run_responder_test
diff --git a/extras/strongswan/test_responder_vrf.sh b/extras/strongswan/test_responder_vrf.sh
new file mode 100755
index 0000000..15a4a5a
--- /dev/null
+++ b/extras/strongswan/test_responder_vrf.sh
@@ -0,0 +1,5 @@
+. topos/2_init.sh
+
+TC_DIR=responder_vrf
+
+run_responder_test
diff --git a/extras/strongswan/topos/2_init.sh b/extras/strongswan/topos/2_init.sh
new file mode 100644
index 0000000..4e4b190
--- /dev/null
+++ b/extras/strongswan/topos/2_init.sh
@@ -0,0 +1,113 @@
+#
+# 2 initiators (strongswan), 1 responder (vpp) topology
+#
+
+if [ -f ~/.vpp_sswan ]; then
+  . ~/.vpp_sswan
+fi
+
+STARTUP_DIR="`pwd`"
+SSWAN_CFG_DIR=/tmp/sswan
+
+vppctl () {
+  sudo $VPPCTL -s /tmp/vpp_sswan.sock $@
+}
+
+start_vpp() {
+  sudo $VPP_BIN unix { \
+        cli-listen /tmp/vpp_sswan.sock \
+        gid $(id -g) } \
+        api-segment { prefix vpp } \
+        plugins { plugin dpdk_plugin.so { disable } }
+  sleep 5
+
+  echo "exec $STARTUP_DIR/configs/$TC_DIR/vpp.conf"
+  vppctl exec $STARTUP_DIR/configs/$TC_DIR/vpp.conf
+  sleep 3
+}
+
+initiator_conf() {
+  sudo rm -r $SSWAN_CFG_DIR$1
+  sudo mkdir -p $SSWAN_CFG_DIR$1
+  sudo cp configs/$TC_DIR/ipsec$1.conf $SSWAN_CFG_DIR$1/ipsec.conf
+  sudo cp configs/$TC_DIR/ipsec.secrets $SSWAN_CFG_DIR$1/ipsec.secrets
+  sudo cp configs/strongswan.conf $SSWAN_CFG_DIR$1/strongswan.conf
+}
+
+config_topo () {
+  ns_name="ns"$1
+  init_name="sswan"$1
+  (sudo ip link add gw$1 type veth peer name veth_gw$1
+  sudo ip link set dev gw$1 up
+
+  sudo ip netns add $ns_name
+  sudo ip link add veth_priv$1 type veth peer name priv$1
+  sudo ip link set dev priv$1 up
+  sudo ip link set dev veth_priv$1 up netns $ns_name
+
+  sudo ip netns exec $ns_name \
+    bash -c "
+      ip link set dev lo up
+      ip addr add 192.168.3.2/24 dev veth_priv$1
+      ip addr add fec3::2/16 dev veth_priv$1
+      ip route add 192.168.5.0/24 via 192.168.3.1
+      ip route add fec5::0/16 via fec3::1
+      ") &> /dev/null
+
+  initiator_conf $1
+
+  (docker run --name $init_name -d --privileged --rm --net=none \
+  -v $SSWAN_CFG_DIR$1:/conf -v $SSWAN_CFG_DIR$1:/etc/ipsec.d philplckthun/strongswan)
+
+  pid=$(docker inspect --format "{{.State.Pid}}" $init_name)
+  sudo ip link set netns $pid dev veth_gw$1
+
+  sudo nsenter -t $pid -n ip addr add 192.168.10.1/24 dev veth_gw$1
+  sudo nsenter -t $pid -n ip link set dev veth_gw$1 up
+
+  sudo nsenter -t $pid -n ip addr add 192.168.5.2/32 dev lo
+  sudo nsenter -t $pid -n ip link set dev lo up
+}
+
+initiate_from_sswan () {
+  echo "start initiation.."
+  sudo docker exec sswan$1 ipsec up initiator
+  sleep 3
+}
+
+test_ping() {
+  sudo ip netns exec $1 ping -c 1 192.168.5.2
+  rc=$?
+  if [ $rc -ne 0 ] ; then
+    echo "Test failed!"
+  else
+    echo "Test passed."
+  fi
+  return $rc
+}
+
+unconf_topo () {
+  docker stop sswan1 &> /dev/null
+  docker stop sswan2 &> /dev/null
+  sudo pkill vpp
+  sudo ip netns delete ns1
+  sudo ip netns delete ns2
+  sleep 2
+}
+
+initiate_from_vpp () {
+  vppctl ikev2 initiate sa-init pr1
+  sleep 2
+}
+
+#vpp as an responder
+run_responder_test() {
+  unconf_topo
+  config_topo "1"
+  config_topo "2"
+  start_vpp
+  initiate_from_sswan "1"
+  initiate_from_sswan "2"
+  test_ping "ns2"
+  test_ping "ns1"
+}
diff --git a/extras/strongswan/topos/basic.sh b/extras/strongswan/topos/basic.sh
new file mode 100644
index 0000000..68968a0
--- /dev/null
+++ b/extras/strongswan/topos/basic.sh
@@ -0,0 +1,115 @@
+if [ -f ~/.vpp_sswan ]; then
+  . ~/.vpp_sswan
+fi
+
+STARTUP_DIR="`pwd`"
+SSWAN_CFG_DIR=/tmp/sswan
+
+start_vpp() {
+  sudo $VPP_BIN unix { \
+	cli-listen /tmp/vpp_sswan.sock \
+        gid $(id -g) } \
+        api-segment { prefix vpp } \
+        plugins { plugin dpdk_plugin.so { disable } }
+}
+
+vppctl () {
+  sudo $VPPCTL -s /tmp/vpp_sswan.sock $@
+}
+
+initiator_conf() {
+  sudo rm -r $SSWAN_CFG_DIR
+  sudo mkdir -p $SSWAN_CFG_DIR
+  sudo cp configs/$TC_DIR/ipsec.conf $SSWAN_CFG_DIR/ipsec.conf
+  sudo cp configs/$TC_DIR/ipsec.secrets $SSWAN_CFG_DIR/ipsec.secrets
+  sudo cp configs/strongswan.conf $SSWAN_CFG_DIR/strongswan.conf
+}
+
+config_topo () {
+  (sudo ip link add vpp type veth peer name swanif
+  sudo ip link set dev vpp up
+
+  sudo ip netns add ns
+  sudo ip link add veth_priv type veth peer name priv
+  sudo ip link set dev priv up
+  sudo ip link set dev veth_priv up netns ns
+
+  sudo ip netns exec ns \
+	bash -c "
+		ip link set dev lo up
+		ip addr add 192.168.3.2/24 dev veth_priv
+		ip addr add fec3::2/16 dev veth_priv
+                ip route add 192.168.5.0/24 via 192.168.3.1
+                ip route add fec5::0/16 via fec3::1
+                ") &> /dev/null
+
+  initiator_conf
+  (docker run --name sswan -d --privileged --rm --net=none \
+  -v $SSWAN_CFG_DIR:/conf -v $SSWAN_CFG_DIR:/etc/ipsec.d philplckthun/strongswan)
+
+  pid=$(docker inspect --format "{{.State.Pid}}" sswan)
+  sudo ip link set netns $pid dev swanif
+
+  sudo nsenter -t $pid -n ip addr add 192.168.10.1/24 dev swanif
+  sudo nsenter -t $pid -n ip link set dev swanif up
+
+  sudo nsenter -t $pid -n ip addr add 192.168.5.2/32 dev lo
+  sudo nsenter -t $pid -n ip link set dev lo up
+
+  start_vpp
+  echo "vpp started.."
+  sleep 3
+
+  echo "exec $STARTUP_DIR/configs/$TC_DIR/vpp.conf"
+  vppctl exec $STARTUP_DIR/configs/$TC_DIR/vpp.conf
+  sleep 3
+}
+
+initiate_from_sswan () {
+  echo "start initiation.."
+  sudo docker exec sswan ipsec up initiator
+  sleep 1
+}
+
+test_ping() {
+  sudo ip netns exec ns ping -c 1 192.168.5.2
+  rc=$?
+  if [ $rc -ne 0 ] ; then
+    echo "Test failed!"
+  else
+    echo "Test passed."
+  fi
+  return $rc
+}
+
+unconf_topo () {
+  docker stop sswan &> /dev/null
+  sudo pkill vpp
+  sudo ip netns delete ns
+  sleep 2
+}
+
+initiate_from_vpp () {
+  vppctl ikev2 initiate sa-init pr1
+  sleep 2
+}
+
+#vpp as an responder
+run_responder_test() {
+  config_topo
+  initiate_from_sswan
+  test_ping
+  rc=$?
+  unconf_topo
+  return ${rc}
+}
+
+# vpp as an initiator
+run_initiator_test() {
+  config_topo
+  initiate_from_vpp
+  test_ping
+  rc=$?
+  unconf_topo
+  return ${rc}
+}