aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/srv6-mobile/extra/runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/srv6-mobile/extra/runner.py')
-rwxr-xr-xsrc/plugins/srv6-mobile/extra/runner.py2046
1 files changed, 2046 insertions, 0 deletions
diff --git a/src/plugins/srv6-mobile/extra/runner.py b/src/plugins/srv6-mobile/extra/runner.py
new file mode 100755
index 00000000000..710252d5ce1
--- /dev/null
+++ b/src/plugins/srv6-mobile/extra/runner.py
@@ -0,0 +1,2046 @@
+#!/usr/bin/env python3
+
+from os.path import dirname, realpath, split,\
+ join, isdir, exists
+from os import remove, system, mkdir
+from logging import getLogger, basicConfig,\
+ DEBUG, INFO, ERROR
+from argparse import ArgumentParser
+from atexit import register
+from shutil import rmtree
+
+from jinja2 import Environment, FileSystemLoader
+
+from docker.errors import NotFound, APIError
+from docker import from_env
+
+from scapy.contrib.gtp import *
+from scapy.all import *
+
+
+verbose_levels = {
+ 'error': ERROR,
+ 'debug': DEBUG,
+ 'info': INFO}
+
+
+class ContainerStartupError(Exception):
+ pass
+
+
+class Container(object):
+
+ tmp = "/tmp"
+ cmd = "vppctl -s 0:5002"
+ cmd_bash = "/bin/bash"
+
+ def __init__(self, ref, name):
+ self._name = name
+ self._ref = ref
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def temp(self):
+ return join(self.tmp, self.name)
+
+ @property
+ def pg_input_file(self):
+ return join(self.temp, "pgi.pcap")
+
+ @property
+ def pg_output_file(self):
+ return join(self.temp, "pgo.pcap")
+
+ @property
+ def pg_input_file_in(self):
+ return join("/mnt", "pgi.pcap")
+
+ @property
+ def pg_output_file_in(self):
+ return join("/mnt", "pgo.pcap")
+
+ def disconnect_all(self):
+ status = False
+ for net in self._ref.client.networks.list():
+ try:
+ net.disconnect(self._ref)
+ except APIError:
+ continue
+ status = True
+ return status
+
+ @classmethod
+ def new(cls, client, image, name):
+
+ temp = join(cls.tmp, name)
+ if isdir(temp):
+ rmtree(temp)
+ mkdir(temp)
+
+ ref = client.containers.run(
+ detach=True,
+ remove=True,
+ auto_remove=True,
+ image=image,
+ name=name,
+ privileged=True,
+ volumes={
+ temp: {
+ 'bind': '/mnt',
+ 'mode': 'rw'}})
+
+ obj = cls.get(client, name)
+ if not obj:
+ raise ContainerStartupError()
+
+ obj.disconnect_all()
+ return obj
+
+ @classmethod
+ def get(cls, client, name):
+ try:
+ ref = client.containers.get(name)
+ except NotFound:
+ pass
+ else:
+ return cls(ref, name)
+
+ def rem(self):
+ self._ref.kill()
+
+ def vppctl(self):
+ system("docker exec -it {} {}".format(self.name, self.cmd))
+
+ def bash(self):
+ system("docker exec -it {} {}".format(self.name, self.cmd_bash))
+
+ def vppctl_exec(self, cmd):
+ ec, resp = self._ref.exec_run(cmd="{} {}".format(self.cmd, cmd))
+ assert(ec == 0)
+ return resp
+
+ def setup_host_interface(self, name, ip):
+ self.vppctl_exec("create host-interface name {}".format(name))
+ self.vppctl_exec("set int ip addr host-{} {}".format(name, ip))
+ self.vppctl_exec("set int state host-{} up".format(name))
+
+ def pg_create_interface(self, local_ip, remote_ip, local_mac, remote_mac):
+ # remote_ip can't have subnet mask
+
+ time.sleep(2)
+ self.vppctl_exec("create packet-generator interface pg0")
+ self.vppctl_exec("set int mac address pg0 {}".format(local_mac))
+ self.vppctl_exec("set int ip addr pg0 {}".format(local_ip))
+ self.vppctl_exec(
+ "set ip6 neighbor pg0 {} {}".format(remote_ip, remote_mac))
+ self.vppctl_exec("set int state pg0 up")
+
+ def pg_create_interface4(self, local_ip, remote_ip, local_mac, remote_mac):
+ # remote_ip can't have subnet mask
+
+ time.sleep(2)
+ self.vppctl_exec("create packet-generator interface pg0")
+ self.vppctl_exec("set int mac address pg0 {}".format(local_mac))
+ self.vppctl_exec("set int ip addr pg0 {}".format(local_ip))
+ self.vppctl_exec("set ip arp pg0 {} {}".format(remote_ip, remote_mac))
+ self.vppctl_exec("set int state pg0 up")
+
+ def pg_create_interface6(self, local_ip, remote_ip, local_mac, remote_mac):
+ # remote_ip can't have subnet mask
+
+ time.sleep(2)
+ self.vppctl_exec("create packet-generator interface pg0")
+ self.vppctl_exec("set int mac address pg0 {}".format(local_mac))
+ self.vppctl_exec("set int ip6 addr pg0 {}".format(local_ip))
+ self.vppctl_exec("set ip6 arp pg0 {} {}".format(remote_ip, remote_mac))
+ self.vppctl_exec("set int state pg0 up")
+
+ def pg_enable(self):
+ # start packet generator
+ self.vppctl_exec("packet-generator enable")
+
+ def pg_create_stream(self, stream):
+ wrpcap(self.pg_input_file, stream)
+ self.vppctl_exec(
+ "packet-generator new name pg-stream "
+ "node ethernet-input pcap {}".format(
+ self.pg_input_file_in))
+
+ def pg_start_capture(self):
+ if exists(self.pg_output_file):
+ remove(self.pg_output_file)
+ self.vppctl_exec(
+ "packet-generator capture pg0 pcap {}".format(
+ self.pg_output_file_in))
+
+ def pg_read_packets(self):
+ return rdpcap(self.pg_output_file)
+
+ def set_ipv6_route(self, out_if_name, next_hop_ip, subnet):
+ self.vppctl_exec(
+ "ip route add {} via host-{} {}".format(
+ subnet, out_if_name, next_hop_ip))
+
+ def set_ip_pgroute(self, out_if_name, next_hop_ip, subnet):
+ self.vppctl_exec("ip route add {} via {} {}".format(
+ subnet, out_if_name, next_hop_ip))
+
+ def set_ipv6_pgroute(self, out_if_name, next_hop_ip, subnet):
+ self.vppctl_exec("ip route add {} via {} {}".format(
+ subnet, out_if_name, next_hop_ip))
+
+ def set_ipv6_default_route(self, out_if_name, next_hop_ip):
+ self.vppctl_exec(
+ "ip route add ::/0 via host-{} {}".format(
+ out_if_name, next_hop_ip))
+
+ def enable_trace(self, count):
+ self.vppctl_exec("trace add af-packet-input {}".format(count))
+
+
+class Containers(object):
+
+ def __init__(self, client, image):
+ self.client = client
+ self.image = image
+
+ def tmp_render(self, path, template, kwargs):
+
+ with open(path, "w") as fo:
+ fo.write(template.render(**kwargs))
+
+ register(lambda: remove(path))
+
+ def build(self, path, vpp_path):
+ env = Environment(loader=FileSystemLoader(path),
+ trim_blocks=True)
+
+ self.tmp_render(join(vpp_path, "Dockerfile"),
+ env.get_template("Dockerfile.j2"),
+ {'vpp_path': vpp_path})
+
+ self.tmp_render(join(vpp_path, "startup.conf"),
+ env.get_template("startup.conf.j2"),
+ {'vpp_path': vpp_path})
+
+ ref, _ = self.client.images.build(path=vpp_path,
+ tag=self.image, rm=True)
+ return ref
+
+ def release(self, path, vpp_path):
+ env = Environment(loader=FileSystemLoader(path),
+ trim_blocks=True)
+
+ self.tmp_render(join(vpp_path, "Dockerfile"),
+ env.get_template("Dockerfile.j2.release"),
+ {'vpp_path': vpp_path})
+
+ self.tmp_render(join(vpp_path, "startup.conf"),
+ env.get_template("startup.conf.j2"),
+ {'vpp_path': vpp_path})
+
+ ref, _ = self.client.images.build(path=vpp_path,
+ tag="srv6m-release-image", rm=True)
+ return ref
+
+ def new(self, name):
+ return Container.new(self.client, self.image, name)
+
+ def get(self, name):
+ return Container.get(self.client, name)
+
+ def vppctl(self, name, command=None):
+ container = self.get(name)
+ if not command:
+ container.vppctl()
+ else:
+ print(container.vppctl_exec(command).decode())
+
+ def bash(self, name):
+ container = self.get(name)
+ container.bash()
+
+
+class Network(object):
+
+ def __init__(self, ref, name):
+ self._name = name
+ self._ref = ref
+
+ @property
+ def name(self):
+ return self._name
+
+ @classmethod
+ def new(cls, client, name):
+ ref = client.networks.create(name, driver="bridge",
+ check_duplicate=True)
+ return cls(ref, name)
+
+ @classmethod
+ def get(cls, client, name):
+ try:
+ ref = client.networks.get(name)
+ except NotFound:
+ pass
+ else:
+ return cls(ref, name)
+
+ def rem(self):
+ self._ref.remove()
+
+ def connect(self, c):
+ self._ref.connect(c.name)
+
+
+class Networks(object):
+
+ def __init__(self, client):
+ self.client = client
+
+ def new(self, name):
+ return Network.new(self.client, name)
+
+ def get(self, name):
+ return Network.get(self.client, name)
+
+
+class Program(object):
+
+ image = "srv6m-image"
+
+ name_prefix = "hck"
+
+ # TODO: add description to these instances
+ # for exmaple what the vpp is supposed to be
+ # in our topoloty overview
+
+ instance_names = ["vpp-1",
+ "vpp-2",
+ "vpp-3",
+ "vpp-4"]
+
+ network_names = ["net-1",
+ "net-2",
+ "net-3"]
+
+ def __init__(self, image=None, prefix=None):
+ self.path = dirname(realpath(__file__))
+
+ if image:
+ self.image = image
+ if prefix is not None:
+ self.name_prefix = prefix
+
+ client = from_env()
+ self.containers = Containers(client, self.image)
+ self.networks = Networks(client)
+
+ self.logger = getLogger(__name__)
+
+ @property
+ def vpp_path(self):
+ return self.path.rsplit("/", 4)[0]
+
+ def get_name(self, name):
+ if not self.name_prefix:
+ return name
+ return "{}-{}".format(self.name_prefix, name)
+
+ def stop_containers(self):
+
+ for name in self.instance_names:
+ instance = self.containers.get(self.get_name(name))
+ if instance:
+ instance.rem()
+
+ for name in self.network_names:
+ network = self.networks.get(self.get_name(name))
+ if network:
+ network.rem()
+
+ def start_containers(self):
+
+ self.stop_containers()
+
+ networks = list()
+
+ for name in self.network_names:
+ networks.append(self.networks.new(self.get_name(name)))
+
+ n1, n2, n3 = networks
+
+ instances = list()
+
+ for name in self.instance_names:
+ instances.append(self.containers.new(self.get_name(name)))
+
+ c1, c2, c3, c4 = instances
+
+ # setup packet generator interfaces
+ # c1.pg_create_interface(local_ip="C::1/120", remote_ip="C::2",
+ # local_mac="aa:bb:cc:dd:ee:01", remote_mac="aa:bb:cc:dd:ee:02")
+
+ # setup network between instances
+ n1.connect(c1)
+ n1.connect(c2)
+
+ n2.connect(c2)
+ n2.connect(c3)
+
+ n3.connect(c3)
+ n3.connect(c4)
+
+ # c1 & c2 link
+ c1.setup_host_interface("eth1", "A1::1/120")
+ c2.setup_host_interface("eth1", "A1::2/120")
+
+ # c2 & c3 link
+ c2.setup_host_interface("eth2", "A2::1/120")
+ c3.setup_host_interface("eth1", "A2::2/120")
+
+ # c3 & c4 link
+ c3.setup_host_interface("eth2", "A3::1/120")
+ c4.setup_host_interface("eth1", "A3::2/120")
+
+ # c1 > c2 default route
+
+ c1.set_ipv6_default_route("eth1", "A1::2")
+ # c2 > c3 default route
+ c2.set_ipv6_default_route("eth2", "A2::2")
+ # c3 > c2 default route
+ c3.set_ipv6_default_route("eth1", "A2::1")
+ # c4 > c3 default route
+ c4.set_ipv6_default_route("eth1", "A3::1")
+
+ # c3 > c4 static route for address B::1/128
+ c3.set_ipv6_route("eth2", "A3::2", "B::1/128")
+ c3.set_ipv6_route("eth2", "A3::2", "B::2/128")
+
+ def test_ping(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="B::2") / ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_srv6(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 C::1/120
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Sleeping")
+ time.sleep(30)
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr D1::")
+ c1.vppctl_exec(
+ "sr policy add bsid D1::999:1 next D2:: next D3:: next D4::")
+ c1.vppctl_exec("sr steer l3 B::/120 via bsid D1::999:1")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid address D4:: behavior end.dx6 pg0 B::2")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/128")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="B::2") / ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c2.enable_trace(10)
+ c3.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_tmap(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec(
+ "sr policy add bsid D1:: next D2:: next D3:: "
+ "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
+ c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IP(src="172.99.0.1", dst="172.99.0.2") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_tmap_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec(
+ "sr policy add bsid D1:: next D2:: next D3:: "
+ "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
+ c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(R=1, QFI=3) /
+ IP(src="172.99.0.1", dst="172.99.0.2") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_tmap_ipv6(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec(
+ "sr policy add bsid D1:: next D2:: next D3:: "
+ "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
+ c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_tmap_ipv6_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec(
+ "sr policy add bsid D1:: next D2:: next D3:: "
+ "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
+ c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(R=1, QFI=3) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp4(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+ c1.vppctl_exec(
+ "sr localsid prefix 172.20.0.1/32 "
+ "behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64 nhtype ipv4")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IP(src="172.99.0.1", dst="172.99.0.2") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp4_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+ c1.vppctl_exec(
+ "sr localsid prefix ::ffff:ac14:0001/128 "
+ "behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64 "
+ "nhtype ipv4")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(type=1, R=1, QFI=3) /
+ IP(src="172.99.0.1", dst="172.99.0.2") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp4_echo(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+ c1.vppctl_exec(
+ "sr localsid prefix 172.20.0.1/32 "
+ "behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64 "
+ "nhtype ipv4")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="echo_request", teid=200))
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp4_ipv6(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+ c1.vppctl_exec(
+ "sr localsid prefix ::ffff:ac14:0001/128 "
+ "behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp4_ipv6_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface4(
+ local_ip="172.16.0.1/30",
+ remote_ip="172.16.0.2/30",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+ c1.vppctl_exec(
+ "sr localsid prefix ::ffff:ac14:0001/128 "
+ "behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec(
+ "sr localsid prefix D4::/32 "
+ "behavior end.m.gtp4.e v4src_position 64")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IP(src="172.20.0.2", dst="172.20.0.1") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(R=1, QFI=3) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_drop_in(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IP(src="172.99.0.1", dst="172.99.0.2") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_drop_in_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(type=1, R=1, QFI=3) /
+ IP(src="172.99.0.1", dst="172.99.0.2") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_drop_in_echo(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="echo_request", teid=200))
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_drop_in_ipv6(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_drop_in_ipv6_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(R=1, QFI=3) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt4 2")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.200.0.1/32")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IP(src="172.100.0.1", dst="172.200.0.1") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface4(
+ local_ip="1.0.0.2/30",
+ remote_ip="1.0.0.1",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt4 2")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ip_pgroute("pg0", "1.0.0.1", "172.200.0.1/32")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(R=1, QFI=3) /
+ IP(src="172.100.0.1", dst="172.200.0.1") /
+ ICMP())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_ipv6(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt6 2")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ipv6_pgroute("pg0", "B::2", "2002::1/128")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def test_gtp6_ipv6_5g(self):
+ # TESTS:
+ # trace add af-packet-input 10
+ # pg interface on c1 172.20.0.1
+ # pg interface on c4 B::1/120
+
+ self.start_containers()
+
+ print("Deleting the old containers...")
+ time.sleep(30)
+ print("Starting the new containers...")
+
+ c1 = self.containers.get(self.get_name(self.instance_names[0]))
+ c2 = self.containers.get(self.get_name(self.instance_names[1]))
+ c3 = self.containers.get(self.get_name(self.instance_names[2]))
+ c4 = self.containers.get(self.get_name(self.instance_names[-1]))
+
+ c1.pg_create_interface(
+ local_ip="C::1/120",
+ remote_ip="C::2",
+ local_mac="aa:bb:cc:dd:ee:01",
+ remote_mac="aa:bb:cc:dd:ee:02")
+ c4.pg_create_interface(
+ local_ip="B::1/120",
+ remote_ip="B::2",
+ local_mac="aa:bb:cc:dd:ee:11",
+ remote_mac="aa:bb:cc:dd:ee:22")
+
+ c1.vppctl_exec("set sr encaps source addr A1::1")
+ c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
+
+ c1.vppctl_exec(
+ "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
+
+ c2.vppctl_exec("sr localsid address D2:: behavior end")
+
+ c3.vppctl_exec("sr localsid address D3:: behavior end")
+
+ c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt6 2")
+
+ c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
+ c2.set_ipv6_route("eth1", "A1::1", "C::/120")
+ c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
+ c3.set_ipv6_route("eth1", "A2::1", "C::/120")
+ c4.set_ipv6_pgroute("pg0", "B::2", "2002::1/128")
+
+ print("Waiting...")
+ time.sleep(30)
+
+ p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
+ IPv6(src="C::2", dst="D::2") /
+ UDP(sport=2152, dport=2152) /
+ GTP_U_Header(gtp_type="g_pdu", teid=200) /
+ GTPPDUSessionContainer(R=1, QFI=3) /
+ IPv6(src="2001::1", dst="2002::1") /
+ ICMPv6EchoRequest())
+
+ print("Sending packet on {}:".format(c1.name))
+ p.show2()
+
+ c1.enable_trace(10)
+ c4.enable_trace(10)
+
+ c4.pg_start_capture()
+
+ c1.pg_create_stream(p)
+ c1.pg_enable()
+
+ # timeout (sleep) if needed
+ print("Sleeping")
+ time.sleep(5)
+
+ print("Receiving packet on {}:".format(c4.name))
+ for p in c4.pg_read_packets():
+ p.show2()
+
+ def status_containers(self):
+
+ print("Instances:")
+
+ for i, name in enumerate(self.instance_names):
+ name = self.get_name(name)
+ print("\t[{}] {} - {}".format(
+ i, name,
+ "running" if self.containers.get(name) else "missing"))
+
+ print("Networks:")
+
+ for i, name in enumerate(self.network_names):
+ name = self.get_name(name)
+ print("\t[{}] {} - {}".format(
+ i, name,
+ "running" if self.networks.get(name) else "missing"))
+
+ def build_image(self):
+ # TODO: optimize build process for speed and image size
+ print("VPP Path (build): {}".format(self.vpp_path))
+ self.containers.build(self.path, self.vpp_path)
+
+ def release_image(self):
+ print("VPP Path (release): {}".format(self.vpp_path))
+ instance = self.containers.new("release-build")
+
+ system(
+ "docker cp release-build:{}/vpp-package.tgz {}/".format(
+ self.vpp_path, self.vpp_path))
+
+ instance.rem()
+
+ self.containers.release(self.path, self.vpp_path)
+
+ system("rm -rf {}/vpp-package.tgz".format(self.vpp_path))
+
+ def vppctl(self, index, command=None):
+ if index >= len(self.instance_names):
+ return
+ name = self.get_name(self.instance_names[index])
+ self.logger.error("connecting to: {}".format(name))
+ self.containers.vppctl(name, command)
+
+ def bash(self, index):
+ if index >= len(self.instance_names):
+ return
+ name = self.get_name(self.instance_names[index])
+ self.logger.error("connecting to: {}".format(name))
+ self.containers.bash(name)
+
+
+def get_args():
+ parser = ArgumentParser()
+
+ parser.add_argument("--verbose", choices=['error', 'debug', 'info'])
+
+ parser.add_argument('--image', choices=['debug', 'release'])
+
+ subparsers = parser.add_subparsers()
+
+ p1 = subparsers.add_parser(
+ "infra", help="Infrastructure related commands.")
+
+ p1.add_argument(
+ "op",
+ choices=[
+ 'stop',
+ 'start',
+ 'status',
+ 'restart',
+ 'build',
+ 'release'])
+
+ p1.add_argument("--prefix")
+ p1.add_argument("--image")
+
+ p2 = subparsers.add_parser("cmd", help="Instance related commands.")
+
+ p2.add_argument("op", choices=['vppctl', 'bash'])
+
+ p2.add_argument(
+ "index",
+ type=int,
+ help="Container instance index. (./runner.py infra status)")
+
+ p2.add_argument(
+ "--command", help="Only vppctl supports this optional argument.")
+
+ p3 = subparsers.add_parser("test", help="Test related commands.")
+
+ p3.add_argument(
+ "op",
+ choices=[
+ "ping",
+ "srv6",
+ "tmap",
+ "tmap_5g",
+ "tmap_ipv6",
+ "tmap_ipv6_5g",
+ "gtp4",
+ "gtp4_5g",
+ "gtp4_echo",
+ "gtp4_ipv6",
+ "gtp4_ipv6_5g",
+ "gtp6_drop_in",
+ "gtp6_drop_in_5g",
+ "gtp6_drop_in_echo",
+ "gtp6_drop_in_ipv6",
+ "gtp6_drop_in_ipv6_5g",
+ "gtp6",
+ "gtp6_5g",
+ "gtp6_ipv6",
+ "gtp6_ipv6_5g"])
+
+ args = parser.parse_args()
+ if not hasattr(args, "op") or not args.op:
+ parser.print_help(sys.stderr)
+ sys.exit(1)
+
+ return vars(args)
+
+
+def main(op=None, prefix=None, verbose=None,
+ image=None, index=None, command=None):
+
+ if verbose:
+ basicConfig(level=verbose_levels[verbose])
+
+ if image == 'release':
+ image = "srv6m-release-image"
+ elif image == 'debug':
+ image = "srv6m-image"
+
+ print("Verified image: {}".format(image))
+
+ program = Program(image, prefix)
+
+ try:
+ if op == 'build':
+ program.build_image()
+ elif op == 'release':
+ program.release_image()
+ elif op == 'stop':
+ program.stop_containers()
+ elif op == 'start':
+ program.start_containers()
+ elif op == 'status':
+ program.status_containers()
+ elif op == 'vppctl':
+ program.vppctl(index, command)
+ elif op == 'bash':
+ program.bash(index)
+ elif op == 'ping':
+ program.test_ping()
+ elif op == 'srv6':
+ program.test_srv6()
+ elif op == 'tmap':
+ program.test_tmap()
+ elif op == 'tmap_5g':
+ program.test_tmap_5g()
+ elif op == 'tmap_ipv6':
+ program.test_tmap_ipv6()
+ elif op == 'tmap_ipv6_5g':
+ program.test_tmap_ipv6_5g()
+ elif op == 'gtp4':
+ program.test_gtp4()
+ elif op == 'gtp4_5g':
+ program.test_gtp4_5g()
+ elif op == 'gtp4_echo':
+ program.test_gtp4_echo()
+ elif op == 'gtp4_ipv6':
+ program.test_gtp4_ipv6()
+ elif op == 'gtp4_ipv6_5g':
+ program.test_gtp4_ipv6_5g()
+ elif op == 'gtp6_drop_in':
+ program.test_gtp6_drop_in()
+ elif op == 'gtp6_drop_in_5g':
+ program.test_gtp6_drop_in_5g()
+ elif op == 'gtp6_drop_in_echo':
+ program.test_gtp6_drop_in_echo()
+ elif op == 'gtp6_drop_in_ipv6':
+ program.test_gtp6_drop_in_ipv6()
+ elif op == 'gtp6_drop_in_ipv6_5g':
+ program.test_gtp6_drop_in_ipv6_5g()
+ elif op == 'gtp6':
+ program.test_gtp6()
+ elif op == 'gtp6_5g':
+ program.test_gtp6_5g()
+ elif op == 'gtp6_ipv6':
+ program.test_gtp6_ipv6()
+ elif op == 'gtp6_ipv6_5g':
+ program.test_gtp6_ipv6_5g()
+
+ except Exception:
+ program.logger.exception("")
+ rc = 1
+ else:
+ rc = 0
+
+ return rc
+
+
+if __name__ == "__main__":
+ sys.exit(main(**get_args()))