From f9c4cfa7d6c7a90541601041fb7886e5e5f15ed3 Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Fri, 22 Jul 2016 10:42:41 +0200 Subject: Add map resolver failover test Change-Id: Ic4d5a553950e7d3dee36a818f4b06f69890b1719 Signed-off-by: Filip Tehlar --- .../vpp_lite_config/basic/4o4_failover/vpp1.config | 15 ++++ .../vpp_lite_config/basic/4o4_failover/vpp2.config | 13 +++ tests/data_plane/vpp_lite_topo/scripts/dummy_mr.py | 94 +++++++++++++++++++++ .../vpp_lite_topo/test_driver/resolver_failover.sh | 56 +++++++++++++ .../tests/manual_test_resolver_failover.sh | 14 ++++ .../vpp_lite_topo/topologies/basic_two_odls.sh | 97 ++++++++++++++++++++++ 6 files changed, 289 insertions(+) create mode 100644 tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp1.config create mode 100644 tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp2.config create mode 100755 tests/data_plane/vpp_lite_topo/scripts/dummy_mr.py create mode 100644 tests/data_plane/vpp_lite_topo/test_driver/resolver_failover.sh create mode 100755 tests/data_plane/vpp_lite_topo/tests/manual_test_resolver_failover.sh create mode 100644 tests/data_plane/vpp_lite_topo/topologies/basic_two_odls.sh diff --git a/tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp1.config b/tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp1.config new file mode 100644 index 0000000..72ac2ab --- /dev/null +++ b/tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp1.config @@ -0,0 +1,15 @@ +create host-interface name vpp1 +set int state host-vpp1 up +set int ip address host-vpp1 6.0.1.1/24 + +create host-interface name intervpp1 +set int state host-intervpp1 up +set int ip address host-intervpp1 6.0.3.1/24 + +lisp enable + +lisp locator-set add ls1 iface host-intervpp1 p 1 w 1 +lisp eid-table add eid 6.0.1.0/24 locator-set ls1 + +lisp map-resolver add 6.0.3.99 +lisp map-resolver add 6.0.3.100 diff --git a/tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp2.config b/tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp2.config new file mode 100644 index 0000000..1bac043 --- /dev/null +++ b/tests/data_plane/configs/vpp_lite_config/basic/4o4_failover/vpp2.config @@ -0,0 +1,13 @@ +create host-interface name vpp2 +set int state host-vpp2 up +set int ip address host-vpp2 6.0.2.1/24 + +create host-interface name intervpp2 +set int state host-intervpp2 up +set int ip address host-intervpp2 6.0.3.2/24 + +lisp enable + +lisp locator-set add ls1 iface host-intervpp2 p 1 w 1 +lisp eid-table add eid 6.0.2.0/24 locator-set ls1 +lisp map-resolver add 6.0.3.100 diff --git a/tests/data_plane/vpp_lite_topo/scripts/dummy_mr.py b/tests/data_plane/vpp_lite_topo/scripts/dummy_mr.py new file mode 100755 index 0000000..4740586 --- /dev/null +++ b/tests/data_plane/vpp_lite_topo/scripts/dummy_mr.py @@ -0,0 +1,94 @@ +#/usr/bin/env python + +# Simple map resolver +# +# This script creates an UDP socket and starts listening on it. +# When a map-request is received nonce is extracted from the request and +# used in map-reply. +# +# Notes: +# * works only with ipv4 in both under/over-lays. +# * exact address matching is done while looking for a mapping +# +# Usage: +# ./dummy_mr +# + +import sys +import socket + +# mapping between EIDs and RLOCs +mappings = { + b'\x06\x00\x02\x02' : (b'\x06\x00\x03\x02', ), + b'\x06\x00\x01\x02' : (b'\x06\x00\x03\x01', ) +} + +# LISP map-reply message +reply_data = (b'\x20\x00\x00\x01' # type, PES, reserved, record count + + '\x00\x00\x00\x00' # nonce + + '\x00\x00\x00\x00' # nonce + + '\x00\x00\x05\xa0' # record TTL + + '\x01\x18\x10\x00' # loc-count, EID-len, ACT + + '\x00\x00\x00\x01' # rsvd, map-version, EID-AFI=ipv4 + + '\x06\x00\x02\x00' # EID prefix + + '\x01\x01\xff\x00' # prio, weight, mprio, mweight + + '\x00\x05\x00\x01' # unused, LpR, Loc-AFI + + '\x06\x00\x03\x02') # locator + +request_nonce_offset = 36 +reply_nonce_offset = 4 + +request_eid_offset = 60 +reply_eid_offset = 24 + +reply_rloc_offset = 36 + + +def build_reply(nonce, deid): + if deid not in mappings: + raise Exception('No mapping found for eid {}!'.format(repr(deid))) + m = mappings[deid] + + # prepare reply data + reply = bytearray(reply_data) + + # update rloc field in reply message + rloc = bytearray(m[0]) + + for i in range(0, 4): + reply[reply_rloc_offset + i] = rloc[i] + + # update eid prefix field + for i in range(0, 4): + reply[reply_eid_offset + i] = deid[i] + + # update nonce + for i in range(0, 8): + reply[reply_nonce_offset + i] = nonce[i] + + return reply + + +def run(host, port): + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + server_address = (host, int(port)) + sock.bind(server_address) + + while True: + data, address = sock.recvfrom(4096) + + # extract nonce from request + nonce = data[request_nonce_offset:request_nonce_offset+8] + + # extract deid + deid = data[request_eid_offset:request_eid_offset+4] + + rp = build_reply(nonce, deid) + sock.sendto(rp, address) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + raise Exception('IP and port expected') + + run(sys.argv[1], sys.argv[2]) diff --git a/tests/data_plane/vpp_lite_topo/test_driver/resolver_failover.sh b/tests/data_plane/vpp_lite_topo/test_driver/resolver_failover.sh new file mode 100644 index 0000000..3f07a7e --- /dev/null +++ b/tests/data_plane/vpp_lite_topo/test_driver/resolver_failover.sh @@ -0,0 +1,56 @@ +source config.sh +source odl_utils.sh +source topologies/basic_two_odls.sh + +ODL_CONFIG_FILE1="vpp1.json" +ODL_CONFIG_FILE2="vpp2.json" + +if [ "$1" == "clean" ] ; then + basic_two_odls_clean + exit 0 +fi + +if [[ $(id -u) != 0 ]]; then + echo "Error: run this as a root." + exit 1 +fi + +function start_map_resolver +{ + echo "starting dummy map resolver on interface $1" + python scripts/dummy_mr.py "$1" 4342 & + mr_id=$! +} + +function test_resolver_failover +{ + basic_two_odls_setup + + start_map_resolver "6.0.3.100" + + test_result=1 + + if [ "$3" == "wait" ] ; then + read -p "press any key to continue .." -n1 + fi + + ip netns exec vppns1 "${1}" -w 20 -c 1 "${2}" + rc=$? + + # test done + if [ "$3" == "wait" ] ; then + read -p "press any key to continue .." -n1 + fi + + basic_two_odls_clean + kill $mr_id + + if [ $rc -ne 0 ] ; then + echo "Test failed: No ICMP response received within specified timeout limit!" + else + echo "Test passed." + test_result=0 + fi + + exit $test_result +} diff --git a/tests/data_plane/vpp_lite_topo/tests/manual_test_resolver_failover.sh b/tests/data_plane/vpp_lite_topo/tests/manual_test_resolver_failover.sh new file mode 100755 index 0000000..1e505b3 --- /dev/null +++ b/tests/data_plane/vpp_lite_topo/tests/manual_test_resolver_failover.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Test map resover failover scenario +# +# Current implementation selects first map resolver that is configured +# and sends map requests towards it. If there is no response try next one. +# This test verifies whether ITR is able to switch ultimately to a working one. + +VPP_LITE_CONF=`pwd`/../configs/vpp_lite_config/basic/4o4_failover +ODL_CONFIG_DIR=`pwd`/../configs/odl/basic/4o4 + +source test_driver/resolver_failover.sh + +test_resolver_failover ping "6.0.2.2" diff --git a/tests/data_plane/vpp_lite_topo/topologies/basic_two_odls.sh b/tests/data_plane/vpp_lite_topo/topologies/basic_two_odls.sh new file mode 100644 index 0000000..73c0a1d --- /dev/null +++ b/tests/data_plane/vpp_lite_topo/topologies/basic_two_odls.sh @@ -0,0 +1,97 @@ + +#!/usr/bin/env bash + +function basic_two_odls_clean +{ + echo "Clearing all VPP instances.." + pkill vpp --signal 9 + rm /dev/shm/* + + echo "Cleaning topology.." + ip netns exec intervppns ifconfig vppbr down + ip netns exec intervppns brctl delbr vppbr + ip link del dev veth_vpp1 &> /dev/null + ip link del dev veth_vpp2 &> /dev/null + ip link del dev veth_intervpp1 &> /dev/null + ip link del dev veth_intervpp2 &> /dev/null + ip link del dev veth_odl1 &> /dev/null + ip link del dev veth_odl2 &> /dev/null + ip netns del vppns1 &> /dev/null + ip netns del vppns2 &> /dev/null + ip netns del intervppns &> /dev/null +} + +function basic_two_odls_setup +{ + + # create vpp to clients and inter-vpp namespaces + ip netns add vppns1 + ip netns add vppns2 + ip netns add intervppns + + # create vpp and odl interfaces and set them in intervppns + ip link add veth_intervpp1 type veth peer name intervpp1 + ip link add veth_intervpp2 type veth peer name intervpp2 + ip link add veth_odl1 type veth peer name odl1 + ip link add veth_odl2 type veth peer name odl2 + ip link set dev intervpp1 up + ip link set dev intervpp2 up + ip link set dev odl1 up + ip link set dev odl2 up + ip link set dev veth_intervpp1 up netns intervppns + ip link set dev veth_intervpp2 up netns intervppns + ip link set dev veth_odl1 up netns intervppns + ip link set dev veth_odl2 up netns intervppns + + # create bridge in intervppns and add vpp and odl interfaces + ip netns exec intervppns brctl addbr vppbr + ip netns exec intervppns brctl addif vppbr veth_intervpp1 + ip netns exec intervppns brctl addif vppbr veth_intervpp2 + ip netns exec intervppns brctl addif vppbr veth_odl1 + ip netns exec intervppns brctl addif vppbr veth_odl2 + ip netns exec intervppns ifconfig vppbr up + + # create and configure 1st veth client to vpp pair + ip link add veth_vpp1 type veth peer name vpp1 + ip link set dev vpp1 up + ip link set dev veth_vpp1 up netns vppns1 + + # create and configure 2nd veth client to vpp pair + ip link add veth_vpp2 type veth peer name vpp2 + ip link set dev vpp2 up + ip link set dev veth_vpp2 up netns vppns2 + + ip netns exec vppns1 \ + bash -c " + ip link set dev lo up + ip addr add 6.0.1.2/24 dev veth_vpp1 + ip route add 6.0.2.0/24 via 6.0.1.1 + " + + ip netns exec vppns2 \ + bash -c " + ip link set dev lo up + ip addr add 6.0.2.2/24 dev veth_vpp2 + ip route add 6.0.1.0/24 via 6.0.2.1 + " + + # set odl iface ip and disable checksum offloading + ip addr add 6.0.3.100/24 dev odl1 + ethtool --offload odl1 rx off tx off + + #ip addr add 6.0.3.100/24 dev odl2 + #ethtool --offload odl2 rx off tx off + + # start vpp1 and vpp2 in separate chroot + ${VPP_LITE_BIN} \ + unix { log /tmp/vpp1.log cli-listen \ + localhost:5002 full-coredump \ + exec ${VPP_LITE_CONF}/vpp1.config } \ + api-trace { on } api-segment {prefix xtr1} + + ${VPP_LITE_BIN} \ + unix { log /tmp/vpp2.log cli-listen \ + localhost:5003 full-coredump \ + exec ${VPP_LITE_CONF}/vpp2.config } \ + api-trace { on } api-segment {prefix xtr2} +} -- cgit 1.2.3-korg