vpp-swan: Add scripts for testing

Added scripts to reparing setups for testing

To prepare and run containers:
sudo ./extras/strongswan/vpp_sswan/docker/run.sh prepare_containers

To prepare setups:
sudo ./extras/strongswan/vpp_sswan/docker/run.sh config

To clean-up settups:
sudo ./extras/strongswan/vpp_sswan/docker/run.sh clean

To deleted all containers and images in Docker:
sudo ./extras/strongswan/vpp_sswan/docker/run.sh deleted

Type: feature
Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I77f01c0419dccc95f610046c8552ae825f2c7e12
diff --git a/extras/strongswan/vpp_sswan/docker/Dockerfile b/extras/strongswan/vpp_sswan/docker/Dockerfile
new file mode 100644
index 0000000..a030708
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/Dockerfile
@@ -0,0 +1,28 @@
+FROM    jrei/systemd-ubuntu:20.04
+
+# add proxy according your own network
+#ENV	http_proxy=""
+#ENV	https_proxy=""
+#ENV	no_proxy=""
+
+# update
+RUN	apt-get update
+
+# tools
+RUN	apt-get install -y git make wget libsystemd-dev
+RUN	apt-get install -y sudo gperf bison flex
+RUN	apt-get install -y iproute2 iputils-ping
+
+# setup env
+WORKDIR /root
+COPY    ./docker/scripts/init_docker1.sh /root/
+COPY    ./docker/scripts/init_docker2.sh /root/
+COPY    ./docker/scripts/init.sh /root/
+COPY    ./docker/scripts/run_vpp.sh /root/
+RUN     chmod +x /root/init_docker1.sh
+RUN     chmod +x /root/init_docker2.sh
+RUN     chmod +x /root/init.sh
+RUN     chmod +x /root/run_vpp.sh
+COPY    / /root/vpp_sswan
+
+RUN     ./init.sh
diff --git a/extras/strongswan/vpp_sswan/docker/configs/startup.conf b/extras/strongswan/vpp_sswan/docker/configs/startup.conf
new file mode 100644
index 0000000..5cdd389
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/configs/startup.conf
@@ -0,0 +1,32 @@
+unix {
+        nodaemon
+        full-coredump
+        cli-listen /run/vpp/cli.sock
+        exec /root/vpp_sswan/docker/configs/vpp.conf
+}
+
+api-trace {
+        on
+}
+
+socksvr {
+        default
+}
+
+cpu {
+        main-core 1
+        corelist-workers 2
+}
+
+dpdk {
+        no-pci
+}
+
+plugins {
+  plugin linux_cp_plugin.so { enable }
+  plugin ikev2_plugin.so { disable }
+}
+
+linux-cp {
+  lcp-sync
+}
diff --git a/extras/strongswan/vpp_sswan/docker/configs/swanctl_docker1.conf b/extras/strongswan/vpp_sswan/docker/configs/swanctl_docker1.conf
new file mode 100644
index 0000000..ac24bf5
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/configs/swanctl_docker1.conf
@@ -0,0 +1,35 @@
+connections {
+        net-net {
+                local_addrs = 192.168.0.2
+                remote_addrs = 192.168.0.1
+                local {
+                        auth = psk
+                        id = sun.strongswan.org
+                }
+                remote {
+                        auth = psk
+                        id = moon.strongswan.org
+                }
+                children {
+                        net-net {
+                                local_ts = 192.168.200.0/24
+                                remote_ts = 192.168.100.0/24
+                                esp_proposals = aes128-sha1-modp2048
+                                rekey_time = 240m
+                        }
+                }
+                version = 2
+                mobike = yes
+                encap = no # NAT-T if needed
+                proposals = aes128-sha256-x25519
+        }
+}
+secrets {
+        ike-net-net {
+                id = moon.strongswan.org
+                secret = simplepsk
+        }
+}
+
+# Include config snippets
+include conf.d/*.conf
diff --git a/extras/strongswan/vpp_sswan/docker/configs/swanctl_docker2.conf b/extras/strongswan/vpp_sswan/docker/configs/swanctl_docker2.conf
new file mode 100644
index 0000000..a7ada86
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/configs/swanctl_docker2.conf
@@ -0,0 +1,35 @@
+connections {
+        net-net {
+                local_addrs = 192.168.0.1
+                remote_addrs = 192.168.0.2
+                local {
+                        auth = psk
+                        id = moon.strongswan.org
+                }
+                remote {
+                        auth = psk
+                        id = sun.strongswan.org
+                }
+                children {
+                        net-net {
+                                local_ts = 192.168.100.0/24
+                                remote_ts = 192.168.200.0/24
+                                esp_proposals = aes128-sha1-modp2048
+                                rekey_time = 240m
+                        }
+                }
+                version = 2
+                mobike = yes
+                encap = no # NAT-T if needed
+                proposals = aes128-sha256-x25519
+        }
+}
+secrets {
+        ike-net-net {
+                id = moon.strongswan.org
+                secret = simplepsk
+        }
+}
+
+# Include config snippets
+include conf.d/*.conf
diff --git a/extras/strongswan/vpp_sswan/docker/configs/vpp.conf b/extras/strongswan/vpp_sswan/docker/configs/vpp.conf
new file mode 100644
index 0000000..dbf142d
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/configs/vpp.conf
@@ -0,0 +1,8 @@
+create host-interface name docker_1_eth2
+lcp create host-docker_1_eth2 host-if eth2
+set interface state host-docker_1_eth2 up
+set interface ip address host-docker_1_eth2 192.168.0.2/24
+
+create host-interface name docker_1a_eth1
+set interface state host-docker_1a_eth1 up
+set interface ip address host-docker_1a_eth1 192.168.200.1/24
diff --git a/extras/strongswan/vpp_sswan/docker/exposedockernetns.sh b/extras/strongswan/vpp_sswan/docker/exposedockernetns.sh
new file mode 100755
index 0000000..ff223ce
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/exposedockernetns.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+if [ "$1" == "" ]; then
+        echo "usage: $0 <container_name>"
+        echo "Exposes the netns of a docker container to the host"
+        exit 1
+fi
+
+        pid=`docker inspect -f '{{.State.Pid}}' $1`
+        ln -s /proc/$pid/ns/net /var/run/netns/$1
+
+        echo "netns of ${1} exposed as /var/run/netns/${1}"
+
+        #echo "try: ip netns exec ${1} ip addr list"
diff --git a/extras/strongswan/vpp_sswan/docker/init_containers.sh b/extras/strongswan/vpp_sswan/docker/init_containers.sh
new file mode 100755
index 0000000..c0e1e26
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/init_containers.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+DOCKER_IMAGE_NAME="vppstrongswan"
+DOCKER_IMAGE_TAG="0.1"
+DOCKER_IMAGE_NAME_FULL="$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG"
+
+if [ "_$1" == "_build_docker_image" ];
+then
+	count=`docker image list | grep -c "$DOCKER_IMAGE_NAME.*$DOCKER_IMAGE_TAG"`
+	if [ $count -ne 0 ];
+	then
+		echo "Error: docker image $DOCKER_IMAGE_NAME_FULL already exists"
+		echo "Re-use it or remove to build new image"
+		exit 0
+	else
+		echo "### Building docker image $DOCKER_IMAGE_NAME ..."
+                cd ../ && docker build -t $DOCKER_IMAGE_NAME_FULL -f ./docker/Dockerfile .
+                echo "### Building docker image $DOCKER_IMAGE_NAME finished"
+	fi
+elif [ "_$1" == "_create_docker1" ];
+then
+        if [ "_$2" == "_" ];
+	then
+		exit 1
+	fi
+	DOCKER_CONTAINER_NAME="$2"
+
+	echo "### Creating container $DOCKER_CONTAINER_NAME"
+	docker run -itd --name="$DOCKER_CONTAINER_NAME" --privileged --cap-add=ALL -p 8022:22 -v /mnt/huge:/mnt/huge -v /sys/bus/pci/devices:/sys/bus/pci/devices -v /sys/devices/system/node:/sys/devices/system/node -v /lib/modules:/lib/modules -v /dev:/dev --tmpfs /tmp --tmpfs /run --tmpfs /run/lock -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$DOCKER_IMAGE_NAME_FULL"
+        if [ $? -eq 0 ];
+	then
+            docker exec -i "$DOCKER_CONTAINER_NAME" "/root/init_docker1.sh" || { echo "call init_docker1.sh failed"; exit 127; }
+	fi
+        echo "### Creating container $DOCKER_CONTAINER_NAME finished"
+	exit 0
+elif [ "_$1" == "_create_docker2" ];
+then
+        if [ "_$2" == "_" ];
+	then
+		exit 1
+	fi
+	DOCKER_CONTAINER_NAME="$2"
+
+	echo "### Creating container $DOCKER_CONTAINER_NAME"
+	docker run -itd --name="$DOCKER_CONTAINER_NAME" --privileged --cap-add=ALL -p 8023:22 -v /mnt/huge:/mnt/huge -v /sys/bus/pci/devices:/sys/bus/pci/devices -v /sys/devices/system/node:/sys/devices/system/node -v /lib/modules:/lib/modules -v /dev:/dev --tmpfs /tmp --tmpfs /run --tmpfs /run/lock -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$DOCKER_IMAGE_NAME_FULL"
+        if [ $? -eq 0 ];
+	then
+            docker exec -i "$DOCKER_CONTAINER_NAME" "/root/init_docker2.sh" || { echo "call init_docker2.sh failed"; exit 127; }
+            fi
+	echo "### Creating container $DOCKER_CONTAINER_NAME finished"
+        exit 0
+elif [ "_$1" == "_clean" ];
+then
+        if [ "_$2" == "_" ];
+	then
+		exit 1
+	fi
+	DOCKER_CONTAINER_NAME="$2"
+
+	echo "### Deleting container $DOCKER_CONTAINER_NAME"
+	sudo docker rm -f $DOCKER_CONTAINER_NAME
+        echo "### Deleting container $DOCKER_CONTAINER_NAME finished"
+        exit 0
+elif [ "_$1" == "_clean_image" ];
+then
+	echo "### Deleting image $DOCKER_IMAGE_NAME_FULL"
+	sudo docker rmi -f $DOCKER_IMAGE_NAME_FULL
+        echo "### Deleting image $DOCKER_IMAGE_NAME_FULL finished"
+        exit 0
+fi
diff --git a/extras/strongswan/vpp_sswan/docker/run.sh b/extras/strongswan/vpp_sswan/docker/run.sh
new file mode 100755
index 0000000..3b1dc6d
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/run.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+
+DOCKER_1_NAME="vpp_sswan_docker1"
+DOCKER_2_NAME="vpp_sswan_docker2"
+
+if [ "_$1" == "_prepare_containers" ];
+then
+        echo "### Building docker image for vpp sswan plugin"
+        ./init_containers.sh build_docker_image
+        echo "### Building the first container for vpp sswan plugin"
+        ./init_containers.sh create_docker1 $DOCKER_1_NAME
+        echo "### Building the second container for vpp sswan plugin"
+        ./init_containers.sh create_docker2 $DOCKER_2_NAME
+elif [ "_$1" == "_config" ];
+then
+        echo "### Configuration $DOCKER_1_NAME and $DOCKER_2_NAME"
+        #ADD 1: set network namespace
+        echo "### Adding network namespace for $DOCKER_1_NAME and $DOCKER_2_NAME"
+        ip netns add vpp_sswan_temp
+        ./exposedockernetns.sh $DOCKER_1_NAME
+        ./exposedockernetns.sh $DOCKER_2_NAME
+        ip netns del vpp_sswan_temp
+        echo "### Adding network namespace for $DOCKER_1_NAME and $DOCKER_2_NAME finished"
+
+        #ADD 2: settings network
+        echo "### Setting network for $DOCKER_1_NAME and $DOCKER_2_NAME"
+
+        ip link add docker_1_eth2 type veth peer name docker_2_eth2
+        ip link set netns $DOCKER_1_NAME dev docker_1_eth2
+        ip link set netns $DOCKER_2_NAME dev docker_2_eth2
+        #ADD 3: ip address
+        ip netns exec $DOCKER_2_NAME ip addr add 192.168.0.1/24 dev docker_2_eth2
+        ip netns exec $DOCKER_2_NAME ip link set dev docker_2_eth2 up
+
+        #LAN for Docker 1
+        ip link add docker_1a_eth1 type veth peer name docker_1b_eth1
+        ip link set netns $DOCKER_1_NAME dev docker_1a_eth1
+        ip link set netns $DOCKER_1_NAME dev docker_1b_eth1
+        ip netns exec $DOCKER_1_NAME ip addr add 192.168.200.10/24 dev docker_1b_eth1
+        ip netns exec $DOCKER_1_NAME ip link set dev docker_1b_eth1 up
+        ip netns exec $DOCKER_1_NAME ip route add 192.168.100.0/24 via 192.168.200.1 dev docker_1b_eth1
+
+        #LAN for Docker 2
+        ip link add docker_2a_eth1 type veth peer name docker_2b_eth1
+        ip link set netns $DOCKER_2_NAME dev docker_2a_eth1
+        ip link set netns $DOCKER_2_NAME dev docker_2b_eth1
+        ip netns exec $DOCKER_2_NAME ip addr add 192.168.100.1/24 dev docker_2a_eth1
+        ip netns exec $DOCKER_2_NAME ip addr add 192.168.100.10/24 dev docker_2b_eth1
+        ip netns exec $DOCKER_2_NAME ip link set dev docker_2a_eth1 up
+        ip netns exec $DOCKER_2_NAME ip link set dev docker_2b_eth1 up
+        ip netns exec $DOCKER_2_NAME ip route add 192.168.200.0/24 via 192.168.100.1 dev docker_2b_eth1
+
+        echo "### Setting network for $DOCKER_1_NAME and $DOCKER_2_NAME finished"
+
+        #ADD 4: run VPP on the first docker
+        echo "### Running VPP and sswan on: $DOCKER_1_NAME and $DOCKER_2_NAME"
+        docker exec -i "$DOCKER_1_NAME" "/root/run_vpp.sh"
+        docker exec -d $DOCKER_2_NAME systemctl restart strongswan.service
+        echo "### Running VPP and sswan on: $DOCKER_1_NAME and $DOCKER_2_NAME finished"
+
+        #ADD 5: initiate sswan
+        echo "### initiate SSWAN between $DOCKER_1_NAME and $DOCKER_2_NAME"
+        docker exec -i $DOCKER_1_NAME swanctl --initiate --child net-net
+        echo "### initiate SSWAN between $DOCKER_1_NAME and $DOCKER_2_NAME finished"
+
+elif [ "_$1" == "_clean" ];
+then
+        #DELETE 5: initiate sswan
+        echo "### Terminate SSWAN between $DOCKER_1_NAME and $DOCKER_2_NAME"
+        docker exec -i $DOCKER_1_NAME swanctl --terminate --child net-net
+        echo "### Terminate SSWAN between $DOCKER_1_NAME and $DOCKER_2_NAME finished"
+
+        #DELETE 4: run VPP on the first docker
+        echo "### Exit VPP on: $DOCKER_1_NAME"
+        docker exec -d $DOCKER_1_NAME pkill -9 -f vpp
+        echo "### Exit VPP on: $DOCKER_1_NAME finished"
+
+        echo "### Deletting settings network for $DOCKER_1_NAME and $DOCKER_2_NAME"
+        #DELETE 3: ip address
+        ip netns exec $DOCKER_1_NAME ip link set dev docker_1_eth2 down
+        ip netns exec $DOCKER_2_NAME ip link set dev docker_2_eth2 down
+        #docker 1
+        ip netns exec $DOCKER_1_NAME ip link set dev docker_1b_eth1 down
+        ip netns exec $DOCKER_1_NAME ip link set netns 1 dev docker_1a_eth1
+        ip netns exec $DOCKER_1_NAME ip link set netns 1 dev docker_1b_eth1
+        ip link del docker_1a_eth1 type veth peer name docker_1b_eth1
+
+        #docker 2
+        ip netns exec $DOCKER_2_NAME ip link set dev docker_2a_eth1 down
+        ip netns exec $DOCKER_2_NAME ip link set dev docker_2b_eth1 down
+        ip netns exec $DOCKER_2_NAME ip link set netns 1 dev docker_2a_eth1
+        ip netns exec $DOCKER_2_NAME ip link set netns 1 dev docker_2b_eth1
+        ip link del docker_2a_eth1 type veth peer name docker_2b_eth1
+
+        #DELETE 2: settings network
+        ip netns exec $DOCKER_1_NAME ip link set netns 1 dev docker_1_eth2
+        ip netns exec $DOCKER_2_NAME ip link set netns 1 dev docker_2_eth2
+        ip link del docker_1_eth2 type veth peer name docker_2_eth2
+        echo "### Deletting settings network for $DOCKER_1_NAME and $DOCKER_2_NAME finished"
+
+        #DELETE 1: delete network namespace
+        echo "### Deleting network namespace for $DOCKER_1_NAME and $DOCKER_2_NAME"
+        ip netns del $DOCKER_1_NAME
+        ip netns del $DOCKER_2_NAME
+        echo "### Deleting network namespace for $DOCKER_1_NAME and $DOCKER_2_NAME finished"
+
+elif [ "_$1" == "_deleted" ];
+then
+        echo "### Exit VPP on: $DOCKER_1_NAME"
+        docker exec -d $DOCKER_1_NAME pkill -9 -f vpp
+        echo "### Exit VPP on: $DOCKER_1_NAME finished"
+
+        echo "### Deleting container $DOCKER_1_NAME and $DOCKER_2_NAME"
+        ./init_containers.sh clean $DOCKER_1_NAME
+        ./init_containers.sh clean $DOCKER_2_NAME
+        echo "### Deleting image"
+        ./init_containers.sh clean_image
+fi
diff --git a/extras/strongswan/vpp_sswan/docker/scripts/init.sh b/extras/strongswan/vpp_sswan/docker/scripts/init.sh
new file mode 100644
index 0000000..80901c9
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/scripts/init.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+echo "Initialization Image"
+
+git clone https://github.com/FDio/vpp.git ./vpp
+
+cp -R vpp_sswan vpp/extras/strongswan/
+cd vpp
+yes | make install-dep
diff --git a/extras/strongswan/vpp_sswan/docker/scripts/init_docker1.sh b/extras/strongswan/vpp_sswan/docker/scripts/init_docker1.sh
new file mode 100644
index 0000000..9be7786
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/scripts/init_docker1.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+echo "Initialization Docker 1 - VPP with SSWAN"
+
+cd /root/vpp
+make build-release
+
+cd /root/vpp/extras/strongswan/vpp_sswan
+make clean
+make all
+
+cd /root/vpp/build-root/build-vpp-native/external/sswan
+sudo make install
+
+cd /root/vpp/extras/strongswan/vpp_sswan
+make install
+
+sudo systemctl daemon-reload
+sudo systemctl restart strongswan.service
+
+echo "### Loaded plugin in strogswan"
+sudo swanctl --stats
+
+sudo cp /root/vpp_sswan/docker/configs/swanctl_docker1.conf /etc/swanctl/conf.d/swanctl.conf
diff --git a/extras/strongswan/vpp_sswan/docker/scripts/init_docker2.sh b/extras/strongswan/vpp_sswan/docker/scripts/init_docker2.sh
new file mode 100644
index 0000000..2e38fba
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/scripts/init_docker2.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+echo "Initialization Docker 2 - SSWAN in kernel"
+
+# tested only with 5.9.5 and 5.9.6 version of strongSwan
+VERSION_SSWAN=5.9.6
+
+curl -o ./strongswan-${VERSION_SSWAN}.tar.gz -LO https://github.com/strongswan/strongswan/archive/${VERSION_SSWAN}.tar.gz;
+tar -zxof ./strongswan-${VERSION_SSWAN}.tar.gz
+
+cd /root/strongswan-${VERSION_SSWAN}
+./autogen.sh
+./configure --prefix=/usr --sysconfdir=/etc --enable-libipsec --enable-systemd --enable-swanctl --disable-gmp --enable-openssl
+make -j$(nproc)
+sudo make install
+
+sudo cp /root/vpp_sswan/docker/configs/swanctl_docker2.conf /etc/swanctl/conf.d/swanctl.conf
+
+sudo systemctl daemon-reload
+sudo systemctl restart strongswan.service
+
+echo "### Loaded plugin in strogswan"
+sudo swanctl --stats
diff --git a/extras/strongswan/vpp_sswan/docker/scripts/run_vpp.sh b/extras/strongswan/vpp_sswan/docker/scripts/run_vpp.sh
new file mode 100644
index 0000000..0497d8a
--- /dev/null
+++ b/extras/strongswan/vpp_sswan/docker/scripts/run_vpp.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+cd /root/vpp/
+make run-release STARTUP_CONF=/root/vpp_sswan/docker/configs/startup.conf &
+
+sleep 5
+
+sudo systemctl restart strongswan.service
+
+sleep 2
+
+echo "### Checking connections between VPP and Strongswan"
+/root/vpp/build-root/build-vpp-native/vpp/bin/vppctl -s /run/vpp/cli.sock sh api client