runner.py revision 70d8ef89
1#!/usr/bin/env python3
2
3from os.path import dirname, realpath, split,\
4    join, isdir, exists
5from os import remove, system, mkdir
6from logging import getLogger, basicConfig,\
7    DEBUG, INFO, ERROR
8from argparse import ArgumentParser
9from atexit import register
10from shutil import rmtree
11
12from jinja2 import Environment, FileSystemLoader
13
14from docker.errors import NotFound, APIError
15from docker import from_env
16
17from scapy.contrib.gtp import *
18from scapy.all import *
19
20
21verbose_levels = {
22    'error': ERROR,
23    'debug': DEBUG,
24    'info': INFO}
25
26
27class ContainerStartupError(Exception):
28    pass
29
30
31class Container(object):
32
33    tmp = "/tmp"
34    cmd = "vppctl -s 0:5002"
35    cmd_bash = "/bin/bash"
36
37    def __init__(self, ref, name):
38        self._name = name
39        self._ref = ref
40
41    @property
42    def name(self):
43        return self._name
44
45    @property
46    def temp(self):
47        return join(self.tmp, self.name)
48
49    @property
50    def pg_input_file(self):
51        return join(self.temp, "pgi.pcap")
52
53    @property
54    def pg_output_file(self):
55        return join(self.temp, "pgo.pcap")
56
57    @property
58    def pg_input_file_in(self):
59        return join("/mnt", "pgi.pcap")
60
61    @property
62    def pg_output_file_in(self):
63        return join("/mnt", "pgo.pcap")
64
65    def disconnect_all(self):
66        status = False
67        for net in self._ref.client.networks.list():
68            try:
69                net.disconnect(self._ref)
70            except APIError:
71                continue
72            status = True
73        return status
74
75    @classmethod
76    def new(cls, client, image, name):
77
78        temp = join(cls.tmp, name)
79        if isdir(temp):
80            rmtree(temp)
81        mkdir(temp)
82
83        ref = client.containers.run(
84            detach=True,
85            remove=True,
86            auto_remove=True,
87            image=image,
88            name=name,
89            privileged=True,
90            volumes={
91                temp: {
92                    'bind': '/mnt',
93                    'mode': 'rw'}})
94
95        obj = cls.get(client, name)
96        if not obj:
97            raise ContainerStartupError()
98
99        obj.disconnect_all()
100        return obj
101
102    @classmethod
103    def get(cls, client, name):
104        try:
105            ref = client.containers.get(name)
106        except NotFound:
107            pass
108        else:
109            return cls(ref, name)
110
111    def rem(self):
112        self._ref.kill()
113
114    def vppctl(self):
115        system("docker exec -it {} {}".format(self.name, self.cmd))
116
117    def bash(self):
118        system("docker exec -it {} {}".format(self.name, self.cmd_bash))
119
120    def vppctl_exec(self, cmd):
121        ec, resp = self._ref.exec_run(cmd="{} {}".format(self.cmd, cmd))
122        assert(ec == 0)
123        return resp
124
125    def setup_host_interface(self, name, ip):
126        self.vppctl_exec("create host-interface name {}".format(name))
127        self.vppctl_exec("set int ip addr host-{} {}".format(name, ip))
128        self.vppctl_exec("set int state host-{} up".format(name))
129
130    def pg_create_interface(self, local_ip, remote_ip, local_mac, remote_mac):
131        # remote_ip can't have subnet mask
132
133        time.sleep(2)
134        self.vppctl_exec("create packet-generator interface pg0")
135        self.vppctl_exec("set int mac address pg0 {}".format(local_mac))
136        self.vppctl_exec("set int ip addr pg0 {}".format(local_ip))
137        self.vppctl_exec(
138            "set ip6 neighbor pg0 {} {}".format(remote_ip, remote_mac))
139        self.vppctl_exec("set int state pg0 up")
140
141    def pg_create_interface4(self, local_ip, remote_ip, local_mac, remote_mac):
142        # remote_ip can't have subnet mask
143
144        time.sleep(2)
145        self.vppctl_exec("create packet-generator interface pg0")
146        self.vppctl_exec("set int mac address pg0 {}".format(local_mac))
147        self.vppctl_exec("set int ip addr pg0 {}".format(local_ip))
148        self.vppctl_exec("set ip arp pg0 {} {}".format(remote_ip, remote_mac))
149        self.vppctl_exec("set int state pg0 up")
150
151    def pg_create_interface6(self, local_ip, remote_ip, local_mac, remote_mac):
152        # remote_ip can't have subnet mask
153
154        time.sleep(2)
155        self.vppctl_exec("create packet-generator interface pg0")
156        self.vppctl_exec("set int mac address pg0 {}".format(local_mac))
157        self.vppctl_exec("set int ip6 addr pg0 {}".format(local_ip))
158        self.vppctl_exec("set ip6 arp pg0 {} {}".format(remote_ip, remote_mac))
159        self.vppctl_exec("set int state pg0 up")
160
161    def pg_enable(self):
162        # start packet generator
163        self.vppctl_exec("packet-generator enable")
164
165    def pg_create_stream(self, stream):
166        wrpcap(self.pg_input_file, stream)
167        self.vppctl_exec(
168            "packet-generator new name pg-stream "
169            "node ethernet-input pcap {}".format(
170                self.pg_input_file_in))
171
172    def pg_start_capture(self):
173        if exists(self.pg_output_file):
174            remove(self.pg_output_file)
175        self.vppctl_exec(
176            "packet-generator capture pg0 pcap {}".format(
177                self.pg_output_file_in))
178
179    def pg_read_packets(self):
180        return rdpcap(self.pg_output_file)
181
182    def set_ipv6_route(self, out_if_name, next_hop_ip, subnet):
183        self.vppctl_exec(
184            "ip route add {} via host-{} {}".format(
185                subnet, out_if_name, next_hop_ip))
186
187    def set_ip_pgroute(self, out_if_name, next_hop_ip, subnet):
188        self.vppctl_exec("ip route add {} via {} {}".format(
189            subnet, out_if_name, next_hop_ip))
190
191    def set_ipv6_pgroute(self, out_if_name, next_hop_ip, subnet):
192        self.vppctl_exec("ip route add {} via {} {}".format(
193            subnet, out_if_name, next_hop_ip))
194
195    def set_ipv6_default_route(self, out_if_name, next_hop_ip):
196        self.vppctl_exec(
197            "ip route add ::/0 via host-{} {}".format(
198                out_if_name, next_hop_ip))
199
200    def enable_trace(self, count):
201        self.vppctl_exec("trace add af-packet-input {}".format(count))
202
203
204class Containers(object):
205
206    def __init__(self, client, image):
207        self.client = client
208        self.image = image
209
210    def tmp_render(self, path, template, kwargs):
211
212        with open(path, "w") as fo:
213            fo.write(template.render(**kwargs))
214
215        register(lambda: remove(path))
216
217    def build(self, path, vpp_path):
218        env = Environment(loader=FileSystemLoader(path),
219                          trim_blocks=True)
220
221        self.tmp_render(join(vpp_path, "Dockerfile"),
222                        env.get_template("Dockerfile.j2"),
223                        {'vpp_path': vpp_path})
224
225        self.tmp_render(join(vpp_path, "startup.conf"),
226                        env.get_template("startup.conf.j2"),
227                        {'vpp_path': vpp_path})
228
229        ref, _ = self.client.images.build(path=vpp_path,
230                                          tag=self.image, rm=True)
231        return ref
232
233    def release(self, path, vpp_path):
234        env = Environment(loader=FileSystemLoader(path),
235                          trim_blocks=True)
236
237        self.tmp_render(join(vpp_path, "Dockerfile"),
238                        env.get_template("Dockerfile.j2.release"),
239                        {'vpp_path': vpp_path})
240
241        self.tmp_render(join(vpp_path, "startup.conf"),
242                        env.get_template("startup.conf.j2"),
243                        {'vpp_path': vpp_path})
244
245        ref, _ = self.client.images.build(path=vpp_path,
246                                          tag="srv6m-release-image", rm=True)
247        return ref
248
249    def new(self, name):
250        return Container.new(self.client, self.image, name)
251
252    def get(self, name):
253        return Container.get(self.client, name)
254
255    def vppctl(self, name, command=None):
256        container = self.get(name)
257        if not command:
258            container.vppctl()
259        else:
260            print(container.vppctl_exec(command).decode())
261
262    def bash(self, name):
263        container = self.get(name)
264        container.bash()
265
266
267class Network(object):
268
269    def __init__(self, ref, name):
270        self._name = name
271        self._ref = ref
272
273    @property
274    def name(self):
275        return self._name
276
277    @classmethod
278    def new(cls, client, name):
279        ref = client.networks.create(name, driver="bridge",
280                                     check_duplicate=True)
281        return cls(ref, name)
282
283    @classmethod
284    def get(cls, client, name):
285        try:
286            ref = client.networks.get(name)
287        except NotFound:
288            pass
289        else:
290            return cls(ref, name)
291
292    def rem(self):
293        self._ref.remove()
294
295    def connect(self, c):
296        self._ref.connect(c.name)
297
298
299class Networks(object):
300
301    def __init__(self, client):
302        self.client = client
303
304    def new(self, name):
305        return Network.new(self.client, name)
306
307    def get(self, name):
308        return Network.get(self.client, name)
309
310
311class Program(object):
312
313    image = "srv6m-image"
314
315    name_prefix = "hck"
316
317    # TODO: add description to these instances
318    # for exmaple what the vpp is supposed to be
319    # in our topoloty overview
320
321    instance_names = ["vpp-1",
322                      "vpp-2",
323                      "vpp-3",
324                      "vpp-4"]
325
326    network_names = ["net-1",
327                     "net-2",
328                     "net-3"]
329
330    def __init__(self, image=None, prefix=None):
331        self.path = dirname(realpath(__file__))
332
333        if image:
334            self.image = image
335        if prefix is not None:
336            self.name_prefix = prefix
337
338        client = from_env()
339        self.containers = Containers(client, self.image)
340        self.networks = Networks(client)
341
342        self.logger = getLogger(__name__)
343
344    @property
345    def vpp_path(self):
346        return self.path.rsplit("/", 4)[0]
347
348    def get_name(self, name):
349        if not self.name_prefix:
350            return name
351        return "{}-{}".format(self.name_prefix, name)
352
353    def stop_containers(self):
354
355        for name in self.instance_names:
356            instance = self.containers.get(self.get_name(name))
357            if instance:
358                instance.rem()
359
360        for name in self.network_names:
361            network = self.networks.get(self.get_name(name))
362            if network:
363                network.rem()
364
365    def start_containers(self):
366
367        self.stop_containers()
368
369        networks = list()
370
371        for name in self.network_names:
372            networks.append(self.networks.new(self.get_name(name)))
373
374        n1, n2, n3 = networks
375
376        instances = list()
377
378        for name in self.instance_names:
379            instances.append(self.containers.new(self.get_name(name)))
380
381        c1, c2, c3, c4 = instances
382
383        # setup packet generator interfaces
384        # c1.pg_create_interface(local_ip="C::1/120", remote_ip="C::2",
385        # local_mac="aa:bb:cc:dd:ee:01", remote_mac="aa:bb:cc:dd:ee:02")
386
387        # setup network between instances
388        n1.connect(c1)
389        n1.connect(c2)
390
391        n2.connect(c2)
392        n2.connect(c3)
393
394        n3.connect(c3)
395        n3.connect(c4)
396
397        # c1 & c2 link
398        c1.setup_host_interface("eth1", "A1::1/120")
399        c2.setup_host_interface("eth1", "A1::2/120")
400
401        # c2 & c3 link
402        c2.setup_host_interface("eth2", "A2::1/120")
403        c3.setup_host_interface("eth1", "A2::2/120")
404
405        # c3 & c4 link
406        c3.setup_host_interface("eth2", "A3::1/120")
407        c4.setup_host_interface("eth1", "A3::2/120")
408
409        # c1 > c2 default route
410
411        c1.set_ipv6_default_route("eth1", "A1::2")
412        # c2 > c3 default route
413        c2.set_ipv6_default_route("eth2", "A2::2")
414        # c3 > c2 default route
415        c3.set_ipv6_default_route("eth1", "A2::1")
416        # c4 > c3 default route
417        c4.set_ipv6_default_route("eth1", "A3::1")
418
419        # c3 > c4 static route for address B::1/128
420        c3.set_ipv6_route("eth2", "A3::2", "B::1/128")
421        c3.set_ipv6_route("eth2", "A3::2", "B::2/128")
422
423    def test_ping(self):
424        # TESTS:
425        # trace add af-packet-input 10
426        # pg interface on c1 172.20.0.1
427        # pg interface on c4 B::1/120
428
429        self.start_containers()
430
431        c1 = self.containers.get(self.get_name(self.instance_names[0]))
432        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
433
434        c1.pg_create_interface(
435            local_ip="C::1/120",
436            remote_ip="C::2",
437            local_mac="aa:bb:cc:dd:ee:01",
438            remote_mac="aa:bb:cc:dd:ee:02")
439        c4.pg_create_interface(
440            local_ip="B::1/120",
441            remote_ip="B::2",
442            local_mac="aa:bb:cc:dd:ee:11",
443            remote_mac="aa:bb:cc:dd:ee:22")
444
445        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
446             IPv6(src="C::2", dst="B::2") / ICMPv6EchoRequest())
447
448        print("Sending packet on {}:".format(c1.name))
449        p.show2()
450
451        c1.enable_trace(10)
452        c4.enable_trace(10)
453
454        c4.pg_start_capture()
455
456        c1.pg_create_stream(p)
457        c1.pg_enable()
458
459        # timeout (sleep) if needed
460
461        print("Receiving packet on {}:".format(c4.name))
462        for p in c4.pg_read_packets():
463            p.show2()
464
465    def test_srv6(self):
466        # TESTS:
467        # trace add af-packet-input 10
468        # pg interface on c1 C::1/120
469        # pg interface on c4 B::1/120
470
471        self.start_containers()
472
473        print("Sleeping")
474        time.sleep(30)
475
476        c1 = self.containers.get(self.get_name(self.instance_names[0]))
477        c2 = self.containers.get(self.get_name(self.instance_names[1]))
478        c3 = self.containers.get(self.get_name(self.instance_names[2]))
479        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
480
481        c1.pg_create_interface(
482            local_ip="C::1/120",
483            remote_ip="C::2",
484            local_mac="aa:bb:cc:dd:ee:01",
485            remote_mac="aa:bb:cc:dd:ee:02")
486        c4.pg_create_interface(
487            local_ip="B::1/120",
488            remote_ip="B::2",
489            local_mac="aa:bb:cc:dd:ee:11",
490            remote_mac="aa:bb:cc:dd:ee:22")
491
492        c1.vppctl_exec("set sr encaps source addr D1::")
493        c1.vppctl_exec(
494            "sr policy add bsid D1::999:1 next D2:: next D3:: next D4::")
495        c1.vppctl_exec("sr steer l3 B::/120 via bsid D1::999:1")
496
497        c2.vppctl_exec("sr localsid address D2:: behavior end")
498
499        c3.vppctl_exec("sr localsid address D3:: behavior end")
500
501        c4.vppctl_exec("sr localsid address D4:: behavior end.dx6 pg0 B::2")
502
503        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
504        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
505        c3.set_ipv6_route("eth2", "A3::2", "D4::/128")
506        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
507
508        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
509             IPv6(src="C::2", dst="B::2") / ICMPv6EchoRequest())
510
511        print("Sending packet on {}:".format(c1.name))
512        p.show2()
513
514        c1.enable_trace(10)
515        c2.enable_trace(10)
516        c3.enable_trace(10)
517        c4.enable_trace(10)
518
519        c4.pg_start_capture()
520
521        c1.pg_create_stream(p)
522        c1.pg_enable()
523
524        # timeout (sleep) if needed
525
526        print("Receiving packet on {}:".format(c4.name))
527        for p in c4.pg_read_packets():
528            p.show2()
529
530    ''' T.Map is obsolete
531    def test_tmap(self):
532        # TESTS:
533        # trace add af-packet-input 10
534        # pg interface on c1 172.20.0.1
535        # pg interface on c4 B::1/120
536
537        self.start_containers()
538
539        c1 = self.containers.get(self.get_name(self.instance_names[0]))
540        c2 = self.containers.get(self.get_name(self.instance_names[1]))
541        c3 = self.containers.get(self.get_name(self.instance_names[2]))
542        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
543
544        c1.pg_create_interface4(
545            local_ip="172.16.0.1/30",
546            remote_ip="172.16.0.2/30",
547            local_mac="aa:bb:cc:dd:ee:01",
548            remote_mac="aa:bb:cc:dd:ee:02")
549        c4.pg_create_interface4(
550            local_ip="1.0.0.2/30",
551            remote_ip="1.0.0.1",
552            local_mac="aa:bb:cc:dd:ee:11",
553            remote_mac="aa:bb:cc:dd:ee:22")
554
555        c1.vppctl_exec("set sr encaps source addr A1::1")
556        c1.vppctl_exec(
557            "sr policy add bsid D1:: next D2:: next D3:: "
558            "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
559        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
560
561        c2.vppctl_exec("sr localsid address D2:: behavior end")
562
563        c3.vppctl_exec("sr localsid address D3:: behavior end")
564
565        c4.vppctl_exec(
566            "sr localsid prefix D4::/32 "
567            "behavior end.m.gtp4.e v4src_position 64")
568
569        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
570        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
571        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
572        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
573        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
574
575        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
576             IP(src="172.20.0.2", dst="172.20.0.1") /
577             UDP(sport=2152, dport=2152) /
578             GTP_U_Header(gtp_type="g_pdu", teid=200) /
579             IP(src="172.99.0.1", dst="172.99.0.2") /
580             ICMP())
581
582        print("Sending packet on {}:".format(c1.name))
583        p.show2()
584
585        c1.enable_trace(10)
586        c4.enable_trace(10)
587
588        c4.pg_start_capture()
589
590        c1.pg_create_stream(p)
591        c1.pg_enable()
592
593        # timeout (sleep) if needed
594        print("Sleeping")
595        time.sleep(5)
596
597        print("Receiving packet on {}:".format(c4.name))
598        for p in c4.pg_read_packets():
599            p.show2()
600
601    def test_tmap_5g(self):
602        # TESTS:
603        # trace add af-packet-input 10
604        # pg interface on c1 172.20.0.1
605        # pg interface on c4 B::1/120
606
607        self.start_containers()
608
609        c1 = self.containers.get(self.get_name(self.instance_names[0]))
610        c2 = self.containers.get(self.get_name(self.instance_names[1]))
611        c3 = self.containers.get(self.get_name(self.instance_names[2]))
612        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
613
614        c1.pg_create_interface4(
615            local_ip="172.16.0.1/30",
616            remote_ip="172.16.0.2/30",
617            local_mac="aa:bb:cc:dd:ee:01",
618            remote_mac="aa:bb:cc:dd:ee:02")
619        c4.pg_create_interface4(
620            local_ip="1.0.0.2/30",
621            remote_ip="1.0.0.1",
622            local_mac="aa:bb:cc:dd:ee:11",
623            remote_mac="aa:bb:cc:dd:ee:22")
624
625        c1.vppctl_exec("set sr encaps source addr A1::1")
626        c1.vppctl_exec(
627            "sr policy add bsid D1:: next D2:: next D3:: "
628            "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
629        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
630
631        c2.vppctl_exec("sr localsid address D2:: behavior end")
632
633        c3.vppctl_exec("sr localsid address D3:: behavior end")
634
635        c4.vppctl_exec(
636            "sr localsid prefix D4::/32 "
637            "behavior end.m.gtp4.e v4src_position 64")
638
639        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
640        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
641        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
642        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
643        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
644
645        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
646             IP(src="172.20.0.2", dst="172.20.0.1") /
647             UDP(sport=2152, dport=2152) /
648             GTP_U_Header(gtp_type="g_pdu", teid=200) /
649             GTPPDUSessionContainer(R=1, QFI=3) /
650             IP(src="172.99.0.1", dst="172.99.0.2") /
651             ICMP())
652
653        print("Sending packet on {}:".format(c1.name))
654        p.show2()
655
656        c1.enable_trace(10)
657        c4.enable_trace(10)
658
659        c4.pg_start_capture()
660
661        c1.pg_create_stream(p)
662        c1.pg_enable()
663
664        # timeout (sleep) if needed
665        print("Sleeping")
666        time.sleep(5)
667
668        print("Receiving packet on {}:".format(c4.name))
669        for p in c4.pg_read_packets():
670            p.show2()
671
672    def test_tmap_ipv6(self):
673        # TESTS:
674        # trace add af-packet-input 10
675        # pg interface on c1 172.20.0.1
676        # pg interface on c4 B::1/120
677
678        self.start_containers()
679
680        c1 = self.containers.get(self.get_name(self.instance_names[0]))
681        c2 = self.containers.get(self.get_name(self.instance_names[1]))
682        c3 = self.containers.get(self.get_name(self.instance_names[2]))
683        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
684
685        c1.pg_create_interface4(
686            local_ip="172.16.0.1/30",
687            remote_ip="172.16.0.2/30",
688            local_mac="aa:bb:cc:dd:ee:01",
689            remote_mac="aa:bb:cc:dd:ee:02")
690        c4.pg_create_interface4(
691            local_ip="1.0.0.2/30",
692            remote_ip="1.0.0.1",
693            local_mac="aa:bb:cc:dd:ee:11",
694            remote_mac="aa:bb:cc:dd:ee:22")
695
696        c1.vppctl_exec("set sr encaps source addr A1::1")
697        c1.vppctl_exec(
698            "sr policy add bsid D1:: next D2:: next D3:: "
699            "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
700        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
701
702        c2.vppctl_exec("sr localsid address D2:: behavior end")
703
704        c3.vppctl_exec("sr localsid address D3:: behavior end")
705
706        c4.vppctl_exec(
707            "sr localsid prefix D4::/32 "
708            "behavior end.m.gtp4.e v4src_position 64")
709
710        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
711        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
712        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
713        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
714        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
715
716        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
717             IP(src="172.20.0.2", dst="172.20.0.1") /
718             UDP(sport=2152, dport=2152) /
719             GTP_U_Header(gtp_type="g_pdu", teid=200) /
720             IPv6(src="2001::1", dst="2002::1") /
721             ICMPv6EchoRequest())
722
723        print("Sending packet on {}:".format(c1.name))
724        p.show2()
725
726        c1.enable_trace(10)
727        c4.enable_trace(10)
728
729        c4.pg_start_capture()
730
731        c1.pg_create_stream(p)
732        c1.pg_enable()
733
734        # timeout (sleep) if needed
735        print("Sleeping")
736        time.sleep(5)
737
738        print("Receiving packet on {}:".format(c4.name))
739        for p in c4.pg_read_packets():
740            p.show2()
741
742    def test_tmap_ipv6_5g(self):
743        # TESTS:
744        # trace add af-packet-input 10
745        # pg interface on c1 172.20.0.1
746        # pg interface on c4 B::1/120
747
748        self.start_containers()
749
750        c1 = self.containers.get(self.get_name(self.instance_names[0]))
751        c2 = self.containers.get(self.get_name(self.instance_names[1]))
752        c3 = self.containers.get(self.get_name(self.instance_names[2]))
753        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
754
755        c1.pg_create_interface4(
756            local_ip="172.16.0.1/30",
757            remote_ip="172.16.0.2/30",
758            local_mac="aa:bb:cc:dd:ee:01",
759            remote_mac="aa:bb:cc:dd:ee:02")
760        c4.pg_create_interface4(
761            local_ip="1.0.0.2/30",
762            remote_ip="1.0.0.1",
763            local_mac="aa:bb:cc:dd:ee:11",
764            remote_mac="aa:bb:cc:dd:ee:22")
765
766        c1.vppctl_exec("set sr encaps source addr A1::1")
767        c1.vppctl_exec(
768            "sr policy add bsid D1:: next D2:: next D3:: "
769            "gtp4_removal sr_prefix D4::/32 v6src_prefix C1::/64")
770        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D1::")
771
772        c2.vppctl_exec("sr localsid address D2:: behavior end")
773
774        c3.vppctl_exec("sr localsid address D3:: behavior end")
775
776        c4.vppctl_exec(
777            "sr localsid prefix D4::/32 "
778            "behavior end.m.gtp4.e v4src_position 64")
779
780        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
781        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
782        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
783        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
784        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
785
786        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
787             IP(src="172.20.0.2", dst="172.20.0.1") /
788             UDP(sport=2152, dport=2152) /
789             GTP_U_Header(gtp_type="g_pdu", teid=200) /
790             GTPPDUSessionContainer(R=1, QFI=3) /
791             IPv6(src="2001::1", dst="2002::1") /
792             ICMPv6EchoRequest())
793
794        print("Sending packet on {}:".format(c1.name))
795        print("Sending packet on {}:".format(c1.name))
796        p.show2()
797
798        c1.enable_trace(10)
799        c4.enable_trace(10)
800
801        c4.pg_start_capture()
802
803        c1.pg_create_stream(p)
804        c1.pg_enable()
805
806        # timeout (sleep) if needed
807        print("Sleeping")
808        time.sleep(5)
809
810        print("Receiving packet on {}:".format(c4.name))
811        for p in c4.pg_read_packets():
812            p.show2()
813    '''
814
815    def test_gtp4(self):
816        # TESTS:
817        # trace add af-packet-input 10
818        # pg interface on c1 172.20.0.1
819        # pg interface on c4 B::1/120
820
821        self.start_containers()
822
823        c1 = self.containers.get(self.get_name(self.instance_names[0]))
824        c2 = self.containers.get(self.get_name(self.instance_names[1]))
825        c3 = self.containers.get(self.get_name(self.instance_names[2]))
826        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
827
828        c1.pg_create_interface4(
829            local_ip="172.16.0.1/30",
830            remote_ip="172.16.0.2/30",
831            local_mac="aa:bb:cc:dd:ee:01",
832            remote_mac="aa:bb:cc:dd:ee:02")
833        c4.pg_create_interface4(
834            local_ip="1.0.0.2/30",
835            remote_ip="1.0.0.1",
836            local_mac="aa:bb:cc:dd:ee:11",
837            remote_mac="aa:bb:cc:dd:ee:22")
838
839        c1.vppctl_exec("set sr encaps source addr A1::1")
840        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
841        c1.vppctl_exec("sr policy add bsid D5:: behavior t.m.gtp4.d D4::/32 v6src_prefix C1::/64 nhtype ipv4")
842        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D5::")
843
844        c2.vppctl_exec("sr localsid address D2:: behavior end")
845
846        c3.vppctl_exec("sr localsid address D3:: behavior end")
847
848        c4.vppctl_exec(
849            "sr localsid prefix D4::/32 "
850            "behavior end.m.gtp4.e v4src_position 64")
851
852        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
853        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
854        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
855        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
856        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
857
858        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
859             IP(src="172.20.0.2", dst="172.20.0.1") /
860             UDP(sport=2152, dport=2152) /
861             GTP_U_Header(gtp_type="g_pdu", teid=200) /
862             IP(src="172.99.0.1", dst="172.99.0.2") /
863             ICMP())
864
865        print("Sending packet on {}:".format(c1.name))
866        p.show2()
867
868        c1.enable_trace(10)
869        c4.enable_trace(10)
870
871        c4.pg_start_capture()
872
873        c1.pg_create_stream(p)
874        c1.pg_enable()
875
876        # timeout (sleep) if needed
877        print("Sleeping")
878        time.sleep(5)
879
880        print("Receiving packet on {}:".format(c4.name))
881        for p in c4.pg_read_packets():
882            p.show2()
883
884    def test_gtp4_5g(self):
885        # TESTS:
886        # trace add af-packet-input 10
887        # pg interface on c1 172.20.0.1
888        # pg interface on c4 B::1/120
889
890        self.start_containers()
891
892        c1 = self.containers.get(self.get_name(self.instance_names[0]))
893        c2 = self.containers.get(self.get_name(self.instance_names[1]))
894        c3 = self.containers.get(self.get_name(self.instance_names[2]))
895        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
896
897        c1.pg_create_interface4(
898            local_ip="172.16.0.1/30",
899            remote_ip="172.16.0.2/30",
900            local_mac="aa:bb:cc:dd:ee:01",
901            remote_mac="aa:bb:cc:dd:ee:02")
902        c4.pg_create_interface4(
903            local_ip="1.0.0.2/30",
904            remote_ip="1.0.0.1",
905            local_mac="aa:bb:cc:dd:ee:11",
906            remote_mac="aa:bb:cc:dd:ee:22")
907
908        c1.vppctl_exec("set sr encaps source addr A1::1")
909        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
910        c1.vppctl_exec("sr policy add bsid D5:: behavior t.m.gtp4.d D4::/32 v6src_prefix C1::/64 nhtype ipv4")
911        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D5::")
912
913        c2.vppctl_exec("sr localsid address D2:: behavior end")
914
915        c3.vppctl_exec("sr localsid address D3:: behavior end")
916
917        c4.vppctl_exec(
918            "sr localsid prefix D4::/32 "
919            "behavior end.m.gtp4.e v4src_position 64")
920
921        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
922        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
923        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
924        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
925        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
926
927        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
928             IP(src="172.20.0.2", dst="172.20.0.1") /
929             UDP(sport=2152, dport=2152) /
930             GTP_U_Header(gtp_type="g_pdu", teid=200) /
931             GTPPDUSessionContainer(type=1, R=1, QFI=3) /
932             IP(src="172.99.0.1", dst="172.99.0.2") /
933             ICMP())
934
935        print("Sending packet on {}:".format(c1.name))
936        p.show2()
937
938        c1.enable_trace(10)
939        c4.enable_trace(10)
940
941        c4.pg_start_capture()
942
943        c1.pg_create_stream(p)
944        c1.pg_enable()
945
946        # timeout (sleep) if needed
947        print("Sleeping")
948        time.sleep(5)
949
950        print("Receiving packet on {}:".format(c4.name))
951        for p in c4.pg_read_packets():
952            p.show2()
953
954    def test_gtp4_echo(self):
955        # TESTS:
956        # trace add af-packet-input 10
957        # pg interface on c1 172.20.0.1
958        # pg interface on c4 B::1/120
959
960        self.start_containers()
961
962        c1 = self.containers.get(self.get_name(self.instance_names[0]))
963        c2 = self.containers.get(self.get_name(self.instance_names[1]))
964        c3 = self.containers.get(self.get_name(self.instance_names[2]))
965        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
966
967        c1.pg_create_interface4(
968            local_ip="172.16.0.1/30",
969            remote_ip="172.16.0.2/30",
970            local_mac="aa:bb:cc:dd:ee:01",
971            remote_mac="aa:bb:cc:dd:ee:02")
972        c4.pg_create_interface4(
973            local_ip="1.0.0.2/30",
974            remote_ip="1.0.0.1",
975            local_mac="aa:bb:cc:dd:ee:11",
976            remote_mac="aa:bb:cc:dd:ee:22")
977
978        c1.vppctl_exec("set sr encaps source addr A1::1")
979        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
980        c1.vppctl_exec("sr policy add bsid D5:: behavior t.m.gtp4.d D4::/32 v6src_prefix C1::/64 nhtype ipv4")
981        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D5::")
982
983        c2.vppctl_exec("sr localsid address D2:: behavior end")
984
985        c3.vppctl_exec("sr localsid address D3:: behavior end")
986
987        c4.vppctl_exec(
988            "sr localsid prefix D4::/32 "
989            "behavior end.m.gtp4.e v4src_position 64")
990
991        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
992        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
993        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
994        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
995        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
996
997        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
998             IP(src="172.20.0.2", dst="172.20.0.1") /
999             UDP(sport=2152, dport=2152) /
1000             GTP_U_Header(gtp_type="echo_request", teid=200))
1001
1002        print("Sending packet on {}:".format(c1.name))
1003        p.show2()
1004
1005        c1.enable_trace(10)
1006        c4.enable_trace(10)
1007
1008        c4.pg_start_capture()
1009
1010        c1.pg_create_stream(p)
1011        c1.pg_enable()
1012
1013        # timeout (sleep) if needed
1014        print("Sleeping")
1015        time.sleep(5)
1016
1017        print("Receiving packet on {}:".format(c4.name))
1018        for p in c4.pg_read_packets():
1019            p.show2()
1020
1021    def test_gtp4_ipv6(self):
1022        # TESTS:
1023        # trace add af-packet-input 10
1024        # pg interface on c1 172.20.0.1
1025        # pg interface on c4 B::1/120
1026
1027        self.start_containers()
1028
1029        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1030        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1031        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1032        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1033
1034        c1.pg_create_interface4(
1035            local_ip="172.16.0.1/30",
1036            remote_ip="172.16.0.2/30",
1037            local_mac="aa:bb:cc:dd:ee:01",
1038            remote_mac="aa:bb:cc:dd:ee:02")
1039        c4.pg_create_interface4(
1040            local_ip="1.0.0.2/30",
1041            remote_ip="1.0.0.1",
1042            local_mac="aa:bb:cc:dd:ee:11",
1043            remote_mac="aa:bb:cc:dd:ee:22")
1044
1045        c1.vppctl_exec("set sr encaps source addr A1::1")
1046        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1047        c1.vppctl_exec("sr policy add bsid D5:: behavior t.m.gtp4.d D4::/32 v6src_prefix C1::/64")
1048        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D5::")
1049
1050        c2.vppctl_exec("sr localsid address D2:: behavior end")
1051
1052        c3.vppctl_exec("sr localsid address D3:: behavior end")
1053
1054        c4.vppctl_exec(
1055            "sr localsid prefix D4::/32 "
1056            "behavior end.m.gtp4.e v4src_position 64")
1057
1058        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1059        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1060        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1061        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1062        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
1063
1064        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1065             IP(src="172.20.0.2", dst="172.20.0.1") /
1066             UDP(sport=2152, dport=2152) /
1067             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1068             IPv6(src="2001::1", dst="2002::1") /
1069             ICMPv6EchoRequest())
1070
1071        print("Sending packet on {}:".format(c1.name))
1072        p.show2()
1073
1074        c1.enable_trace(10)
1075        c4.enable_trace(10)
1076
1077        c4.pg_start_capture()
1078
1079        c1.pg_create_stream(p)
1080        c1.pg_enable()
1081
1082        # timeout (sleep) if needed
1083        print("Sleeping")
1084        time.sleep(5)
1085
1086        print("Receiving packet on {}:".format(c4.name))
1087        for p in c4.pg_read_packets():
1088            p.show2()
1089
1090    def test_gtp4_ipv6_5g(self):
1091        # TESTS:
1092        # trace add af-packet-input 10
1093        # pg interface on c1 172.20.0.1
1094        # pg interface on c4 B::1/120
1095
1096        self.start_containers()
1097
1098        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1099        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1100        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1101        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1102
1103        c1.pg_create_interface4(
1104            local_ip="172.16.0.1/30",
1105            remote_ip="172.16.0.2/30",
1106            local_mac="aa:bb:cc:dd:ee:01",
1107            remote_mac="aa:bb:cc:dd:ee:02")
1108        c4.pg_create_interface4(
1109            local_ip="1.0.0.2/30",
1110            remote_ip="1.0.0.1",
1111            local_mac="aa:bb:cc:dd:ee:11",
1112            remote_mac="aa:bb:cc:dd:ee:22")
1113
1114        c1.vppctl_exec("set sr encaps source addr A1::1")
1115        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1116        c1.vppctl_exec("sr policy add bsid D5:: behavior t.m.gtp4.d D4::/32 v6src_prefix C1::/64")
1117        c1.vppctl_exec("sr steer l3 172.20.0.1/32 via bsid D5::")
1118
1119        c2.vppctl_exec("sr localsid address D2:: behavior end")
1120
1121        c3.vppctl_exec("sr localsid address D3:: behavior end")
1122
1123        c4.vppctl_exec(
1124            "sr localsid prefix D4::/32 "
1125            "behavior end.m.gtp4.e v4src_position 64")
1126
1127        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1128        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1129        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1130        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1131        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
1132
1133        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1134             IP(src="172.20.0.2", dst="172.20.0.1") /
1135             UDP(sport=2152, dport=2152) /
1136             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1137             GTPPDUSessionContainer(R=1, QFI=3) /
1138             IPv6(src="2001::1", dst="2002::1") /
1139             ICMPv6EchoRequest())
1140
1141        print("Sending packet on {}:".format(c1.name))
1142        p.show2()
1143
1144        c1.enable_trace(10)
1145        c4.enable_trace(10)
1146
1147        c4.pg_start_capture()
1148
1149        c1.pg_create_stream(p)
1150        c1.pg_enable()
1151
1152        # timeout (sleep) if needed
1153        print("Sleeping")
1154        time.sleep(5)
1155
1156        print("Receiving packet on {}:".format(c4.name))
1157        for p in c4.pg_read_packets():
1158            p.show2()
1159
1160    def test_gtp6_drop_in(self):
1161        # TESTS:
1162        # trace add af-packet-input 10
1163        # pg interface on c1 172.20.0.1
1164        # pg interface on c4 B::1/120
1165
1166        self.start_containers()
1167
1168        print("Deleting the old containers...")
1169        time.sleep(30)
1170        print("Starting the new containers...")
1171
1172        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1173        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1174        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1175        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1176
1177        c1.pg_create_interface(
1178            local_ip="C::1/120",
1179            remote_ip="C::2",
1180            local_mac="aa:bb:cc:dd:ee:01",
1181            remote_mac="aa:bb:cc:dd:ee:02")
1182        c4.pg_create_interface(
1183            local_ip="B::1/120",
1184            remote_ip="B::2",
1185            local_mac="aa:bb:cc:dd:ee:11",
1186            remote_mac="aa:bb:cc:dd:ee:22")
1187
1188        c1.vppctl_exec("set sr encaps source addr A1::1")
1189        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1190
1191        c1.vppctl_exec(
1192            "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
1193
1194        c2.vppctl_exec("sr localsid address D2:: behavior end")
1195
1196        c3.vppctl_exec("sr localsid address D3:: behavior end")
1197
1198        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
1199
1200        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1201        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1202        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1203        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1204        c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
1205
1206        print("Waiting...")
1207        time.sleep(30)
1208
1209        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1210             IPv6(src="C::2", dst="D::2") /
1211             UDP(sport=2152, dport=2152) /
1212             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1213             IP(src="172.99.0.1", dst="172.99.0.2") /
1214             ICMP())
1215
1216        print("Sending packet on {}:".format(c1.name))
1217        p.show2()
1218
1219        c1.enable_trace(10)
1220        c4.enable_trace(10)
1221
1222        c4.pg_start_capture()
1223
1224        c1.pg_create_stream(p)
1225        c1.pg_enable()
1226
1227        # timeout (sleep) if needed
1228        print("Sleeping")
1229        time.sleep(5)
1230
1231        print("Receiving packet on {}:".format(c4.name))
1232        for p in c4.pg_read_packets():
1233            p.show2()
1234
1235    def test_gtp6_drop_in_5g(self):
1236        # TESTS:
1237        # trace add af-packet-input 10
1238        # pg interface on c1 172.20.0.1
1239        # pg interface on c4 B::1/120
1240
1241        self.start_containers()
1242
1243        print("Deleting the old containers...")
1244        time.sleep(30)
1245        print("Starting the new containers...")
1246
1247        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1248        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1249        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1250        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1251
1252        c1.pg_create_interface(
1253            local_ip="C::1/120",
1254            remote_ip="C::2",
1255            local_mac="aa:bb:cc:dd:ee:01",
1256            remote_mac="aa:bb:cc:dd:ee:02")
1257        c4.pg_create_interface(
1258            local_ip="B::1/120",
1259            remote_ip="B::2",
1260            local_mac="aa:bb:cc:dd:ee:11",
1261            remote_mac="aa:bb:cc:dd:ee:22")
1262
1263        c1.vppctl_exec("set sr encaps source addr A1::1")
1264        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1265
1266        c1.vppctl_exec(
1267            "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
1268
1269        c2.vppctl_exec("sr localsid address D2:: behavior end")
1270
1271        c3.vppctl_exec("sr localsid address D3:: behavior end")
1272
1273        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
1274
1275        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1276        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1277        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1278        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1279        c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
1280
1281        print("Waiting...")
1282        time.sleep(30)
1283
1284        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1285             IPv6(src="C::2", dst="D::2") /
1286             UDP(sport=2152, dport=2152) /
1287             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1288             GTPPDUSessionContainer(type=1, R=1, QFI=3) /
1289             IP(src="172.99.0.1", dst="172.99.0.2") /
1290             ICMP())
1291
1292        print("Sending packet on {}:".format(c1.name))
1293        p.show2()
1294
1295        c1.enable_trace(10)
1296        c4.enable_trace(10)
1297
1298        c4.pg_start_capture()
1299
1300        c1.pg_create_stream(p)
1301        c1.pg_enable()
1302
1303        # timeout (sleep) if needed
1304        print("Sleeping")
1305        time.sleep(5)
1306
1307        print("Receiving packet on {}:".format(c4.name))
1308        for p in c4.pg_read_packets():
1309            p.show2()
1310
1311    def test_gtp6_drop_in_echo(self):
1312        # TESTS:
1313        # trace add af-packet-input 10
1314        # pg interface on c1 172.20.0.1
1315        # pg interface on c4 B::1/120
1316
1317        self.start_containers()
1318
1319        print("Deleting the old containers...")
1320        time.sleep(30)
1321        print("Starting the new containers...")
1322
1323        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1324        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1325        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1326        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1327
1328        c1.pg_create_interface(
1329            local_ip="C::1/120",
1330            remote_ip="C::2",
1331            local_mac="aa:bb:cc:dd:ee:01",
1332            remote_mac="aa:bb:cc:dd:ee:02")
1333        c4.pg_create_interface(
1334            local_ip="B::1/120",
1335            remote_ip="B::2",
1336            local_mac="aa:bb:cc:dd:ee:11",
1337            remote_mac="aa:bb:cc:dd:ee:22")
1338
1339        c1.vppctl_exec("set sr encaps source addr A1::1")
1340        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1341
1342        c1.vppctl_exec(
1343            "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
1344
1345        c2.vppctl_exec("sr localsid address D2:: behavior end")
1346
1347        c3.vppctl_exec("sr localsid address D3:: behavior end")
1348
1349        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
1350
1351        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1352        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1353        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1354        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1355        c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
1356
1357        print("Waiting...")
1358        time.sleep(30)
1359
1360        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1361             IPv6(src="C::2", dst="D::2") /
1362             UDP(sport=2152, dport=2152) /
1363             GTP_U_Header(gtp_type="echo_request", teid=200))
1364
1365        print("Sending packet on {}:".format(c1.name))
1366        p.show2()
1367
1368        c1.enable_trace(10)
1369        c4.enable_trace(10)
1370
1371        c4.pg_start_capture()
1372
1373        c1.pg_create_stream(p)
1374        c1.pg_enable()
1375
1376        # timeout (sleep) if needed
1377        print("Sleeping")
1378        time.sleep(5)
1379
1380        print("Receiving packet on {}:".format(c4.name))
1381        for p in c4.pg_read_packets():
1382            p.show2()
1383
1384    def test_gtp6_drop_in_ipv6(self):
1385        # TESTS:
1386        # trace add af-packet-input 10
1387        # pg interface on c1 172.20.0.1
1388        # pg interface on c4 B::1/120
1389
1390        self.start_containers()
1391
1392        print("Deleting the old containers...")
1393        time.sleep(30)
1394        print("Starting the new containers...")
1395
1396        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1397        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1398        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1399        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1400
1401        c1.pg_create_interface(
1402            local_ip="C::1/120",
1403            remote_ip="C::2",
1404            local_mac="aa:bb:cc:dd:ee:01",
1405            remote_mac="aa:bb:cc:dd:ee:02")
1406        c4.pg_create_interface(
1407            local_ip="B::1/120",
1408            remote_ip="B::2",
1409            local_mac="aa:bb:cc:dd:ee:11",
1410            remote_mac="aa:bb:cc:dd:ee:22")
1411
1412        c1.vppctl_exec("set sr encaps source addr A1::1")
1413        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1414
1415        c1.vppctl_exec(
1416            "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
1417
1418        c2.vppctl_exec("sr localsid address D2:: behavior end")
1419
1420        c3.vppctl_exec("sr localsid address D3:: behavior end")
1421
1422        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
1423
1424        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1425        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1426        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1427        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1428        c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
1429
1430        print("Waiting...")
1431        time.sleep(30)
1432
1433        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1434             IPv6(src="C::2", dst="D::2") /
1435             UDP(sport=2152, dport=2152) /
1436             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1437             IPv6(src="2001::1", dst="2002::1") /
1438             ICMPv6EchoRequest())
1439
1440        print("Sending packet on {}:".format(c1.name))
1441        p.show2()
1442
1443        c1.enable_trace(10)
1444        c4.enable_trace(10)
1445
1446        c4.pg_start_capture()
1447
1448        c1.pg_create_stream(p)
1449        c1.pg_enable()
1450
1451        # timeout (sleep) if needed
1452        print("Sleeping")
1453        time.sleep(5)
1454
1455        print("Receiving packet on {}:".format(c4.name))
1456        for p in c4.pg_read_packets():
1457            p.show2()
1458
1459    def test_gtp6_drop_in_ipv6_5g(self):
1460        # TESTS:
1461        # trace add af-packet-input 10
1462        # pg interface on c1 172.20.0.1
1463        # pg interface on c4 B::1/120
1464
1465        self.start_containers()
1466
1467        print("Deleting the old containers...")
1468        time.sleep(30)
1469        print("Starting the new containers...")
1470
1471        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1472        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1473        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1474        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1475
1476        c1.pg_create_interface(
1477            local_ip="C::1/120",
1478            remote_ip="C::2",
1479            local_mac="aa:bb:cc:dd:ee:01",
1480            remote_mac="aa:bb:cc:dd:ee:02")
1481        c4.pg_create_interface(
1482            local_ip="B::1/120",
1483            remote_ip="B::2",
1484            local_mac="aa:bb:cc:dd:ee:11",
1485            remote_mac="aa:bb:cc:dd:ee:22")
1486
1487        c1.vppctl_exec("set sr encaps source addr A1::1")
1488        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1489
1490        c1.vppctl_exec(
1491            "sr localsid prefix D::/64 behavior end.m.gtp6.d.di D4::/64")
1492
1493        c2.vppctl_exec("sr localsid address D2:: behavior end")
1494
1495        c3.vppctl_exec("sr localsid address D3:: behavior end")
1496
1497        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.m.gtp6.e")
1498
1499        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1500        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1501        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1502        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1503        c4.set_ip_pgroute("pg0", "B::2", "D::2/128")
1504
1505        print("Waiting...")
1506        time.sleep(30)
1507
1508        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1509             IPv6(src="C::2", dst="D::2") /
1510             UDP(sport=2152, dport=2152) /
1511             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1512             GTPPDUSessionContainer(R=1, QFI=3) /
1513             IPv6(src="2001::1", dst="2002::1") /
1514             ICMPv6EchoRequest())
1515
1516        print("Sending packet on {}:".format(c1.name))
1517        p.show2()
1518
1519        c1.enable_trace(10)
1520        c4.enable_trace(10)
1521
1522        c4.pg_start_capture()
1523
1524        c1.pg_create_stream(p)
1525        c1.pg_enable()
1526
1527        # timeout (sleep) if needed
1528        print("Sleeping")
1529        time.sleep(5)
1530
1531        print("Receiving packet on {}:".format(c4.name))
1532        for p in c4.pg_read_packets():
1533            p.show2()
1534
1535    def test_gtp6(self):
1536        # TESTS:
1537        # trace add af-packet-input 10
1538        # pg interface on c1 172.20.0.1
1539        # pg interface on c4 B::1/120
1540
1541        self.start_containers()
1542
1543        print("Deleting the old containers...")
1544        time.sleep(30)
1545        print("Starting the new containers...")
1546
1547        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1548        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1549        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1550        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1551
1552        c1.pg_create_interface(
1553            local_ip="C::1/120",
1554            remote_ip="C::2",
1555            local_mac="aa:bb:cc:dd:ee:01",
1556            remote_mac="aa:bb:cc:dd:ee:02")
1557        c4.pg_create_interface4(
1558            local_ip="1.0.0.2/30",
1559            remote_ip="1.0.0.1",
1560            local_mac="aa:bb:cc:dd:ee:11",
1561            remote_mac="aa:bb:cc:dd:ee:22")
1562
1563        c1.vppctl_exec("set sr encaps source addr A1::1")
1564        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1565
1566        c1.vppctl_exec(
1567            "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
1568
1569        c2.vppctl_exec("sr localsid address D2:: behavior end")
1570
1571        c3.vppctl_exec("sr localsid address D3:: behavior end")
1572
1573        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt4 2")
1574
1575        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1576        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1577        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1578        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1579        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.200.0.1/32")
1580
1581        print("Waiting...")
1582        time.sleep(30)
1583
1584        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1585             IPv6(src="C::2", dst="D::2") /
1586             UDP(sport=2152, dport=2152) /
1587             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1588             IP(src="172.100.0.1", dst="172.200.0.1") /
1589             ICMP())
1590
1591        print("Sending packet on {}:".format(c1.name))
1592        p.show2()
1593
1594        c1.enable_trace(10)
1595        c4.enable_trace(10)
1596
1597        c4.pg_start_capture()
1598
1599        c1.pg_create_stream(p)
1600        c1.pg_enable()
1601
1602        # timeout (sleep) if needed
1603        print("Sleeping")
1604        time.sleep(5)
1605
1606        print("Receiving packet on {}:".format(c4.name))
1607        for p in c4.pg_read_packets():
1608            p.show2()
1609
1610    def test_gtp6_5g(self):
1611        # TESTS:
1612        # trace add af-packet-input 10
1613        # pg interface on c1 172.20.0.1
1614        # pg interface on c4 B::1/120
1615
1616        self.start_containers()
1617
1618        print("Deleting the old containers...")
1619        time.sleep(30)
1620        print("Starting the new containers...")
1621
1622        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1623        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1624        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1625        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1626
1627        c1.pg_create_interface(
1628            local_ip="C::1/120",
1629            remote_ip="C::2",
1630            local_mac="aa:bb:cc:dd:ee:01",
1631            remote_mac="aa:bb:cc:dd:ee:02")
1632        c4.pg_create_interface4(
1633            local_ip="1.0.0.2/30",
1634            remote_ip="1.0.0.1",
1635            local_mac="aa:bb:cc:dd:ee:11",
1636            remote_mac="aa:bb:cc:dd:ee:22")
1637
1638        c1.vppctl_exec("set sr encaps source addr A1::1")
1639        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1640
1641        c1.vppctl_exec(
1642            "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
1643
1644        c2.vppctl_exec("sr localsid address D2:: behavior end")
1645
1646        c3.vppctl_exec("sr localsid address D3:: behavior end")
1647
1648        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt4 2")
1649
1650        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1651        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1652        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1653        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1654        c4.set_ip_pgroute("pg0", "1.0.0.1", "172.200.0.1/32")
1655
1656        print("Waiting...")
1657        time.sleep(30)
1658
1659        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1660             IPv6(src="C::2", dst="D::2") /
1661             UDP(sport=2152, dport=2152) /
1662             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1663             GTPPDUSessionContainer(R=1, QFI=3) /
1664             IP(src="172.100.0.1", dst="172.200.0.1") /
1665             ICMP())
1666
1667        print("Sending packet on {}:".format(c1.name))
1668        p.show2()
1669
1670        c1.enable_trace(10)
1671        c4.enable_trace(10)
1672
1673        c4.pg_start_capture()
1674
1675        c1.pg_create_stream(p)
1676        c1.pg_enable()
1677
1678        # timeout (sleep) if needed
1679        print("Sleeping")
1680        time.sleep(5)
1681
1682        print("Receiving packet on {}:".format(c4.name))
1683        for p in c4.pg_read_packets():
1684            p.show2()
1685
1686    def test_gtp6_ipv6(self):
1687        # TESTS:
1688        # trace add af-packet-input 10
1689        # pg interface on c1 172.20.0.1
1690        # pg interface on c4 B::1/120
1691
1692        self.start_containers()
1693
1694        print("Deleting the old containers...")
1695        time.sleep(30)
1696        print("Starting the new containers...")
1697
1698        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1699        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1700        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1701        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1702
1703        c1.pg_create_interface(
1704            local_ip="C::1/120",
1705            remote_ip="C::2",
1706            local_mac="aa:bb:cc:dd:ee:01",
1707            remote_mac="aa:bb:cc:dd:ee:02")
1708        c4.pg_create_interface(
1709            local_ip="B::1/120",
1710            remote_ip="B::2",
1711            local_mac="aa:bb:cc:dd:ee:11",
1712            remote_mac="aa:bb:cc:dd:ee:22")
1713
1714        c1.vppctl_exec("set sr encaps source addr A1::1")
1715        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1716
1717        c1.vppctl_exec(
1718            "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
1719
1720        c2.vppctl_exec("sr localsid address D2:: behavior end")
1721
1722        c3.vppctl_exec("sr localsid address D3:: behavior end")
1723
1724        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt6 2")
1725
1726        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1727        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1728        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1729        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1730        c4.set_ipv6_pgroute("pg0", "B::2", "2002::1/128")
1731
1732        print("Waiting...")
1733        time.sleep(30)
1734
1735        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1736             IPv6(src="C::2", dst="D::2") /
1737             UDP(sport=2152, dport=2152) /
1738             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1739             IPv6(src="2001::1", dst="2002::1") /
1740             ICMPv6EchoRequest())
1741
1742        print("Sending packet on {}:".format(c1.name))
1743        p.show2()
1744
1745        c1.enable_trace(10)
1746        c4.enable_trace(10)
1747
1748        c4.pg_start_capture()
1749
1750        c1.pg_create_stream(p)
1751        c1.pg_enable()
1752
1753        # timeout (sleep) if needed
1754        print("Sleeping")
1755        time.sleep(5)
1756
1757        print("Receiving packet on {}:".format(c4.name))
1758        for p in c4.pg_read_packets():
1759            p.show2()
1760
1761    def test_gtp6_ipv6_5g(self):
1762        # TESTS:
1763        # trace add af-packet-input 10
1764        # pg interface on c1 172.20.0.1
1765        # pg interface on c4 B::1/120
1766
1767        self.start_containers()
1768
1769        print("Deleting the old containers...")
1770        time.sleep(30)
1771        print("Starting the new containers...")
1772
1773        c1 = self.containers.get(self.get_name(self.instance_names[0]))
1774        c2 = self.containers.get(self.get_name(self.instance_names[1]))
1775        c3 = self.containers.get(self.get_name(self.instance_names[2]))
1776        c4 = self.containers.get(self.get_name(self.instance_names[-1]))
1777
1778        c1.pg_create_interface(
1779            local_ip="C::1/120",
1780            remote_ip="C::2",
1781            local_mac="aa:bb:cc:dd:ee:01",
1782            remote_mac="aa:bb:cc:dd:ee:02")
1783        c4.pg_create_interface(
1784            local_ip="B::1/120",
1785            remote_ip="B::2",
1786            local_mac="aa:bb:cc:dd:ee:11",
1787            remote_mac="aa:bb:cc:dd:ee:22")
1788
1789        c1.vppctl_exec("set sr encaps source addr A1::1")
1790        c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
1791
1792        c1.vppctl_exec(
1793            "sr localsid prefix D::/64 behavior end.m.gtp6.d D4::/64")
1794
1795        c2.vppctl_exec("sr localsid address D2:: behavior end")
1796
1797        c3.vppctl_exec("sr localsid address D3:: behavior end")
1798
1799        c4.vppctl_exec("sr localsid prefix D4::/64 behavior end.dt6 2")
1800
1801        c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
1802        c2.set_ipv6_route("eth1", "A1::1", "C::/120")
1803        c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
1804        c3.set_ipv6_route("eth1", "A2::1", "C::/120")
1805        c4.set_ipv6_pgroute("pg0", "B::2", "2002::1/128")
1806
1807        print("Waiting...")
1808        time.sleep(30)
1809
1810        p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01") /
1811             IPv6(src="C::2", dst="D::2") /
1812             UDP(sport=2152, dport=2152) /
1813             GTP_U_Header(gtp_type="g_pdu", teid=200) /
1814             GTPPDUSessionContainer(R=1, QFI=3) /
1815             IPv6(src="2001::1", dst="2002::1") /
1816             ICMPv6EchoRequest())
1817
1818        print("Sending packet on {}:".format(c1.name))
1819        p.show2()
1820
1821        c1.enable_trace(10)
1822        c4.enable_trace(10)
1823
1824        c4.pg_start_capture()
1825
1826        c1.pg_create_stream(p)
1827        c1.pg_enable()
1828
1829        # timeout (sleep) if needed
1830        print("Sleeping")
1831        time.sleep(5)
1832
1833        print("Receiving packet on {}:".format(c4.name))
1834        for p in c4.pg_read_packets():
1835            p.show2()
1836
1837    def status_containers(self):
1838
1839        print("Instances:")
1840
1841        for i, name in enumerate(self.instance_names):
1842            name = self.get_name(name)
1843            print("\t[{}] {} - {}".format(
1844                i, name,
1845                "running" if self.containers.get(name) else "missing"))
1846
1847        print("Networks:")
1848
1849        for i, name in enumerate(self.network_names):
1850            name = self.get_name(name)
1851            print("\t[{}] {} - {}".format(
1852                i, name,
1853                "running" if self.networks.get(name) else "missing"))
1854
1855    def build_image(self):
1856        # TODO: optimize build process for speed and image size
1857        print("VPP Path (build): {}".format(self.vpp_path))
1858        self.containers.build(self.path, self.vpp_path)
1859
1860    def release_image(self):
1861        print("VPP Path (release): {}".format(self.vpp_path))
1862        instance = self.containers.new("release-build")
1863
1864        system(
1865            "docker cp release-build:{}/vpp-package.tgz {}/".format(
1866                self.vpp_path, self.vpp_path))
1867
1868        instance.rem()
1869
1870        self.containers.release(self.path, self.vpp_path)
1871
1872        system("rm -rf {}/vpp-package.tgz".format(self.vpp_path))
1873
1874    def vppctl(self, index, command=None):
1875        if index >= len(self.instance_names):
1876            return
1877        name = self.get_name(self.instance_names[index])
1878        self.logger.error("connecting to: {}".format(name))
1879        self.containers.vppctl(name, command)
1880
1881    def bash(self, index):
1882        if index >= len(self.instance_names):
1883            return
1884        name = self.get_name(self.instance_names[index])
1885        self.logger.error("connecting to: {}".format(name))
1886        self.containers.bash(name)
1887
1888
1889def get_args():
1890    parser = ArgumentParser()
1891
1892    parser.add_argument("--verbose", choices=['error', 'debug', 'info'])
1893
1894    parser.add_argument('--image', choices=['debug', 'release'])
1895
1896    subparsers = parser.add_subparsers()
1897
1898    p1 = subparsers.add_parser(
1899        "infra", help="Infrastructure related commands.")
1900
1901    p1.add_argument(
1902        "op",
1903        choices=[
1904            'stop',
1905            'start',
1906            'status',
1907            'restart',
1908            'build',
1909            'release'])
1910
1911    p1.add_argument("--prefix")
1912    p1.add_argument("--image")
1913
1914    p2 = subparsers.add_parser("cmd", help="Instance related commands.")
1915
1916    p2.add_argument("op", choices=['vppctl', 'bash'])
1917
1918    p2.add_argument(
1919        "index",
1920        type=int,
1921        help="Container instance index. (./runner.py infra status)")
1922
1923    p2.add_argument(
1924        "--command", help="Only vppctl supports this optional argument.")
1925
1926    p3 = subparsers.add_parser("test", help="Test related commands.")
1927
1928    p3.add_argument(
1929        "op",
1930        choices=[
1931            "ping",
1932            "srv6",
1933            # "tmap",
1934            # "tmap_5g",
1935            # "tmap_ipv6",
1936            # "tmap_ipv6_5g",
1937            "gtp4",
1938            "gtp4_5g",
1939            "gtp4_echo",
1940            "gtp4_ipv6",
1941            "gtp4_ipv6_5g",
1942            "gtp6_drop_in",
1943            "gtp6_drop_in_5g",
1944            "gtp6_drop_in_echo",
1945            "gtp6_drop_in_ipv6",
1946            "gtp6_drop_in_ipv6_5g",
1947            "gtp6",
1948            "gtp6_5g",
1949            "gtp6_ipv6",
1950            "gtp6_ipv6_5g"])
1951
1952    args = parser.parse_args()
1953    if not hasattr(args, "op") or not args.op:
1954        parser.print_help(sys.stderr)
1955        sys.exit(1)
1956
1957    return vars(args)
1958
1959
1960def main(op=None, prefix=None, verbose=None,
1961         image=None, index=None, command=None):
1962
1963    if verbose:
1964        basicConfig(level=verbose_levels[verbose])
1965
1966    if image == 'release':
1967        image = "srv6m-release-image"
1968    elif image == 'debug':
1969        image = "srv6m-image"
1970
1971    print("Verified image: {}".format(image))
1972
1973    program = Program(image, prefix)
1974
1975    try:
1976        if op == 'build':
1977            program.build_image()
1978        elif op == 'release':
1979            program.release_image()
1980        elif op == 'stop':
1981            program.stop_containers()
1982        elif op == 'start':
1983            program.start_containers()
1984        elif op == 'status':
1985            program.status_containers()
1986        elif op == 'vppctl':
1987            program.vppctl(index, command)
1988        elif op == 'bash':
1989            program.bash(index)
1990        elif op == 'ping':
1991            program.test_ping()
1992        elif op == 'srv6':
1993            program.test_srv6()
1994        # elif op == 'tmap':
1995        #    program.test_tmap()
1996        # elif op == 'tmap_5g':
1997        #    program.test_tmap_5g()
1998        # elif op == 'tmap_ipv6':
1999        #    program.test_tmap_ipv6()
2000        # elif op == 'tmap_ipv6_5g':
2001        #    program.test_tmap_ipv6_5g()
2002        elif op == 'gtp4':
2003            program.test_gtp4()
2004        elif op == 'gtp4_5g':
2005            program.test_gtp4_5g()
2006        elif op == 'gtp4_echo':
2007            program.test_gtp4_echo()
2008        elif op == 'gtp4_ipv6':
2009            program.test_gtp4_ipv6()
2010        elif op == 'gtp4_ipv6_5g':
2011            program.test_gtp4_ipv6_5g()
2012        elif op == 'gtp6_drop_in':
2013            program.test_gtp6_drop_in()
2014        elif op == 'gtp6_drop_in_5g':
2015            program.test_gtp6_drop_in_5g()
2016        elif op == 'gtp6_drop_in_echo':
2017            program.test_gtp6_drop_in_echo()
2018        elif op == 'gtp6_drop_in_ipv6':
2019            program.test_gtp6_drop_in_ipv6()
2020        elif op == 'gtp6_drop_in_ipv6_5g':
2021            program.test_gtp6_drop_in_ipv6_5g()
2022        elif op == 'gtp6':
2023            program.test_gtp6()
2024        elif op == 'gtp6_5g':
2025            program.test_gtp6_5g()
2026        elif op == 'gtp6_ipv6':
2027            program.test_gtp6_ipv6()
2028        elif op == 'gtp6_ipv6_5g':
2029            program.test_gtp6_ipv6_5g()
2030
2031    except Exception:
2032        program.logger.exception("")
2033        rc = 1
2034    else:
2035        rc = 0
2036
2037    return rc
2038
2039
2040if __name__ == "__main__":
2041    sys.exit(main(**get_args()))
2042