srv6-mobile
[vpp.git] / src / plugins / srv6-mobile / extra / runner.py
1 #!/usr/bin/env python3
2
3 from os.path import dirname, realpath, split,\
4     join, isdir, exists
5 from os import remove, system, mkdir
6 from logging import getLogger, basicConfig,\
7     DEBUG, INFO, ERROR
8 from argparse import ArgumentParser
9 from atexit import register
10 from shutil import rmtree
11
12 from jinja2 import Environment, FileSystemLoader
13
14 from docker.errors import NotFound, APIError
15 from docker import from_env
16
17 from scapy.contrib.gtp import *
18 from scapy.all import *
19
20
21 verbose_levels = {
22     'error': ERROR,
23     'debug': DEBUG,
24     'info': INFO}
25
26
27 class ContainerStartupError(Exception):
28     pass
29
30
31 class 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
204 class 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
267 class 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
299 class 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
311 class 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
1889 def 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
1960 def 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
2040 if __name__ == "__main__":
2041     sys.exit(main(**get_args()))