http: fix user agent in request
[vpp.git] / test / test_p2p_ethernet.py
1 #!/usr/bin/env python3
2 import random
3 import unittest
4 import re
5
6 from scapy.packet import Raw
7 from scapy.layers.l2 import Ether
8 from scapy.layers.inet import IP, UDP
9 from scapy.layers.inet6 import IPv6
10
11 from framework import VppTestCase
12 from asfframework import VppTestRunner
13 from vpp_sub_interface import VppP2PSubint
14 from vpp_ip_route import VppIpRoute, VppRoutePath
15 from vpp_papi import mac_pton
16
17
18 class P2PEthernetAPI(VppTestCase):
19     """P2P Ethernet tests"""
20
21     p2p_sub_ifs = []
22
23     @classmethod
24     def setUpClass(cls):
25         super(P2PEthernetAPI, cls).setUpClass()
26
27         # Create pg interfaces
28         cls.create_pg_interfaces(range(4))
29
30         # Set up all interfaces
31         for i in cls.pg_interfaces:
32             i.admin_up()
33
34     @classmethod
35     def tearDownClass(cls):
36         super(P2PEthernetAPI, cls).tearDownClass()
37
38     def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
39         p2p = VppP2PSubint(self, parent_if, sub_id, mac_pton(remote_mac))
40         self.p2p_sub_ifs.append(p2p)
41
42     def delete_p2p_ethernet(self, parent_if, remote_mac):
43         self.vapi.p2p_ethernet_del(parent_if.sw_if_index, mac_pton(remote_mac))
44
45     def test_api(self):
46         """delete/create p2p subif"""
47         self.logger.info("FFP_TEST_START_0000")
48
49         self.create_p2p_ethernet(self.pg0, 1, "de:ad:00:00:00:01")
50         self.create_p2p_ethernet(self.pg0, 2, "de:ad:00:00:00:02")
51         intfs = self.vapi.cli("show interface")
52
53         self.assertIn("pg0.1", intfs)
54         self.assertIn("pg0.2", intfs)
55         self.assertNotIn("pg0.5", intfs)
56
57         # create pg2.5 subif
58         self.create_p2p_ethernet(self.pg0, 5, "de:ad:00:00:00:ff")
59         intfs = self.vapi.cli("show interface")
60         self.assertIn("pg0.5", intfs)
61         # delete pg2.5 subif
62         self.delete_p2p_ethernet(self.pg0, "de:ad:00:00:00:ff")
63
64         intfs = self.vapi.cli("show interface")
65
66         self.assertIn("pg0.1", intfs)
67         self.assertIn("pg0.2", intfs)
68         self.assertNotIn("pg0.5", intfs)
69
70         self.logger.info("FFP_TEST_FINISH_0000")
71
72     def test_p2p_subif_creation_1k(self):
73         """create 1k of p2p subifs"""
74         self.logger.info("FFP_TEST_START_0001")
75
76         macs = []
77         clients = 1000
78         mac = int("dead00000000", 16)
79
80         for i in range(1, clients + 1):
81             try:
82                 macs.append(":".join(re.findall("..", "{:02x}".format(mac + i))))
83                 self.vapi.p2p_ethernet_add(
84                     self.pg2.sw_if_index, mac_pton(macs[i - 1]), i
85                 )
86             except Exception:
87                 self.logger.info("Failed to create subif %d %s" % (i, macs[i - 1]))
88                 raise
89
90         intfs = self.vapi.cli("show interface").split("\n")
91         count = 0
92         for intf in intfs:
93             if intf.startswith("pg2."):
94                 count += 1
95         self.assertEqual(count, clients)
96
97         self.logger.info("FFP_TEST_FINISH_0001")
98
99
100 class P2PEthernetIPV6(VppTestCase):
101     """P2P Ethernet IPv6 tests"""
102
103     p2p_sub_ifs = []
104     packets = []
105
106     @classmethod
107     def setUpClass(cls):
108         super(P2PEthernetIPV6, cls).setUpClass()
109
110         # Create pg interfaces
111         cls.create_pg_interfaces(range(3))
112
113         # Packet sizes
114         cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
115
116         # Set up all interfaces
117         for i in cls.pg_interfaces:
118             i.admin_up()
119
120         cls.pg0.generate_remote_hosts(3)
121         cls.pg0.configure_ipv6_neighbors()
122
123         cls.pg1.config_ip6()
124         cls.pg1.generate_remote_hosts(3)
125         cls.pg1.configure_ipv6_neighbors()
126         cls.pg1.disable_ipv6_ra()
127
128     @classmethod
129     def tearDownClass(cls):
130         super(P2PEthernetIPV6, cls).tearDownClass()
131
132     def setUp(self):
133         super(P2PEthernetIPV6, self).setUp()
134         for p in self.packets:
135             self.packets.remove(p)
136         self.p2p_sub_ifs.append(
137             self.create_p2p_ethernet(self.pg0, 1, self.pg0._remote_hosts[0].mac)
138         )
139         self.p2p_sub_ifs.append(
140             self.create_p2p_ethernet(self.pg0, 2, self.pg0._remote_hosts[1].mac)
141         )
142         self.vapi.cli("trace add p2p-ethernet-input 50")
143
144     def tearDown(self):
145         while len(self.p2p_sub_ifs):
146             p2p = self.p2p_sub_ifs.pop()
147             self.delete_p2p_ethernet(p2p)
148
149         super(P2PEthernetIPV6, self).tearDown()
150
151     def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
152         p2p = VppP2PSubint(self, parent_if, sub_id, mac_pton(remote_mac))
153         p2p.admin_up()
154         p2p.config_ip6()
155         p2p.disable_ipv6_ra()
156         return p2p
157
158     def delete_p2p_ethernet(self, p2p):
159         p2p.unconfig_ip6()
160         p2p.admin_down()
161         self.vapi.p2p_ethernet_del(p2p.parent.sw_if_index, p2p.p2p_remote_mac)
162
163     def create_stream(
164         self, src_mac=None, dst_mac=None, src_ip=None, dst_ip=None, size=None
165     ):
166         pkt_size = size
167         if size is None:
168             pkt_size = random.choice(self.pg_if_packet_sizes)
169         p = Ether(src=src_mac, dst=dst_mac)
170         p /= IPv6(src=src_ip, dst=dst_ip)
171         p /= UDP(sport=1234, dport=4321) / Raw(b"\xa5" * 20)
172         self.extend_packet(p, pkt_size)
173         return p
174
175     def send_packets(self, src_if=None, dst_if=None, packets=None, count=None):
176         self.pg_enable_capture([dst_if])
177         if packets is None:
178             packets = self.packets
179         src_if.add_stream(packets)
180         self.pg_start()
181         if count is None:
182             count = len(packets)
183         return dst_if.get_capture(count)
184
185     def test_no_p2p_subif(self):
186         """standard routing without p2p subinterfaces"""
187         self.logger.info("FFP_TEST_START_0001")
188
189         self.pg0.config_ip6()
190         route_8000 = VppIpRoute(
191             self,
192             "8000::",
193             64,
194             [VppRoutePath(self.pg0.remote_ip6, self.pg0.sw_if_index)],
195         )
196         route_8000.add_vpp_config()
197
198         self.packets = [
199             (
200                 Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
201                 / IPv6(src="3001::1", dst="8000::100")
202                 / UDP(sport=1234, dport=1234)
203                 / Raw(b"\xa5" * 100)
204             )
205         ]
206         self.send_packets(self.pg1, self.pg0)
207
208         self.pg0.unconfig_ip6()
209         self.logger.info("FFP_TEST_FINISH_0001")
210
211     def test_ip6_rx_p2p_subif(self):
212         """receive ipv6 packet via p2p subinterface"""
213         self.logger.info("FFP_TEST_START_0002")
214
215         route_9001 = VppIpRoute(
216             self,
217             "9001::",
218             64,
219             [VppRoutePath(self.pg1.remote_ip6, self.pg1.sw_if_index)],
220         )
221         route_9001.add_vpp_config()
222
223         self.packets.append(
224             self.create_stream(
225                 src_mac=self.pg0._remote_hosts[0].mac,
226                 dst_mac=self.pg0.local_mac,
227                 src_ip=self.p2p_sub_ifs[0].remote_ip6,
228                 dst_ip="9001::100",
229             )
230         )
231
232         self.send_packets(self.pg0, self.pg1, self.packets)
233         self.assert_packet_counter_equal("p2p-ethernet-input", 1)
234
235         route_9001.remove_vpp_config()
236         self.logger.info("FFP_TEST_FINISH_0002")
237
238     def test_ip6_rx_p2p_subif_route(self):
239         """route rx ip6 packet not matching p2p subinterface"""
240         self.logger.info("FFP_TEST_START_0003")
241
242         self.pg0.config_ip6()
243
244         route_3 = VppIpRoute(
245             self,
246             "9000::",
247             64,
248             [VppRoutePath(self.pg1._remote_hosts[0].ip6, self.pg1.sw_if_index)],
249         )
250         route_3.add_vpp_config()
251
252         self.packets.append(
253             self.create_stream(
254                 src_mac="02:03:00:00:ff:ff",
255                 dst_mac=self.pg0.local_mac,
256                 src_ip="a000::100",
257                 dst_ip="9000::100",
258             )
259         )
260
261         self.send_packets(self.pg0, self.pg1)
262
263         self.pg0.unconfig_ip6()
264
265         route_3.remove_vpp_config()
266
267         self.logger.info("FFP_TEST_FINISH_0003")
268
269     def test_ip6_rx_p2p_subif_drop(self):
270         """drop rx packet not matching p2p subinterface"""
271         self.logger.info("FFP_TEST_START_0004")
272
273         route_9001 = VppIpRoute(
274             self,
275             "9000::",
276             64,
277             [VppRoutePath(self.pg1._remote_hosts[0].ip6, self.pg1.sw_if_index)],
278         )
279         route_9001.add_vpp_config()
280
281         self.packets.append(
282             self.create_stream(
283                 src_mac="02:03:00:00:ff:ff",
284                 dst_mac=self.pg0.local_mac,
285                 src_ip="a000::100",
286                 dst_ip="9000::100",
287             )
288         )
289
290         # no packet received
291         self.send_packets(self.pg0, self.pg1, count=0)
292         self.logger.info("FFP_TEST_FINISH_0004")
293
294     def test_ip6_tx_p2p_subif(self):
295         """send packet via p2p subinterface"""
296         self.logger.info("FFP_TEST_START_0005")
297
298         self.pg0.config_ip6()
299
300         route_8000 = VppIpRoute(
301             self,
302             "8000::",
303             64,
304             [VppRoutePath(self.pg0.remote_hosts[0].ip6, self.pg0.sw_if_index)],
305         )
306         route_8000.add_vpp_config()
307         route_8001 = VppIpRoute(
308             self,
309             "8001::",
310             64,
311             [
312                 VppRoutePath(
313                     self.p2p_sub_ifs[0].remote_ip6, self.p2p_sub_ifs[0].sw_if_index
314                 )
315             ],
316         )
317         route_8001.add_vpp_config()
318         route_8002 = VppIpRoute(
319             self,
320             "8002::",
321             64,
322             [
323                 VppRoutePath(
324                     self.p2p_sub_ifs[1].remote_ip6, self.p2p_sub_ifs[1].sw_if_index
325                 )
326             ],
327         )
328         route_8002.add_vpp_config()
329
330         for i in range(0, 3):
331             self.packets.append(
332                 self.create_stream(
333                     src_mac=self.pg1.remote_mac,
334                     dst_mac=self.pg1.local_mac,
335                     src_ip=self.pg1.remote_ip6,
336                     dst_ip="800%d::100" % i,
337                 )
338             )
339
340         self.send_packets(self.pg1, self.pg0, count=3)
341
342         route_8000.remove_vpp_config()
343         route_8001.remove_vpp_config()
344         route_8002.remove_vpp_config()
345
346         self.pg0.unconfig_ip6()
347         self.logger.info("FFP_TEST_FINISH_0005")
348
349     def test_ip6_tx_p2p_subif_drop(self):
350         """drop tx ip6 packet not matching p2p subinterface"""
351         self.logger.info("FFP_TEST_START_0006")
352
353         self.packets.append(
354             self.create_stream(
355                 src_mac="02:03:00:00:ff:ff",
356                 dst_mac=self.pg0.local_mac,
357                 src_ip="a000::100",
358                 dst_ip="9000::100",
359             )
360         )
361
362         # no packet received
363         self.send_packets(self.pg0, self.pg1, count=0)
364         self.logger.info("FFP_TEST_FINISH_0006")
365
366
367 class P2PEthernetIPV4(VppTestCase):
368     """P2P Ethernet IPv4 tests"""
369
370     p2p_sub_ifs = []
371     packets = []
372
373     @classmethod
374     def setUpClass(cls):
375         super(P2PEthernetIPV4, cls).setUpClass()
376
377         # Create pg interfaces
378         cls.create_pg_interfaces(range(3))
379
380         # Packet sizes
381         cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
382
383         # Set up all interfaces
384         for i in cls.pg_interfaces:
385             i.admin_up()
386
387         cls.pg0.config_ip4()
388         cls.pg0.generate_remote_hosts(5)
389         cls.pg0.configure_ipv4_neighbors()
390
391         cls.pg1.config_ip4()
392         cls.pg1.generate_remote_hosts(5)
393         cls.pg1.configure_ipv4_neighbors()
394
395     @classmethod
396     def tearDownClass(cls):
397         super(P2PEthernetIPV4, cls).tearDownClass()
398
399     def setUp(self):
400         super(P2PEthernetIPV4, self).setUp()
401         for p in self.packets:
402             self.packets.remove(p)
403         self.p2p_sub_ifs.append(
404             self.create_p2p_ethernet(self.pg0, 1, self.pg0._remote_hosts[0].mac)
405         )
406         self.p2p_sub_ifs.append(
407             self.create_p2p_ethernet(self.pg0, 2, self.pg0._remote_hosts[1].mac)
408         )
409         self.vapi.cli("trace add p2p-ethernet-input 50")
410
411     def tearDown(self):
412         while len(self.p2p_sub_ifs):
413             p2p = self.p2p_sub_ifs.pop()
414             self.delete_p2p_ethernet(p2p)
415         super(P2PEthernetIPV4, self).tearDown()
416
417     def create_stream(
418         self, src_mac=None, dst_mac=None, src_ip=None, dst_ip=None, size=None
419     ):
420         pkt_size = size
421         if size is None:
422             pkt_size = random.choice(self.pg_if_packet_sizes)
423         p = Ether(src=src_mac, dst=dst_mac)
424         p /= IP(src=src_ip, dst=dst_ip)
425         p /= UDP(sport=1234, dport=4321) / Raw(b"\xa5" * 20)
426         self.extend_packet(p, pkt_size)
427         return p
428
429     def send_packets(self, src_if=None, dst_if=None, packets=None, count=None):
430         self.pg_enable_capture([dst_if])
431         if packets is None:
432             packets = self.packets
433         src_if.add_stream(packets)
434         self.pg_start()
435         if count is None:
436             count = len(packets)
437         return dst_if.get_capture(count)
438
439     def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
440         p2p = VppP2PSubint(self, parent_if, sub_id, mac_pton(remote_mac))
441         p2p.admin_up()
442         p2p.config_ip4()
443         return p2p
444
445     def delete_p2p_ethernet(self, p2p):
446         p2p.unconfig_ip4()
447         p2p.admin_down()
448         self.vapi.p2p_ethernet_del(p2p.parent.sw_if_index, p2p.p2p_remote_mac)
449
450     def test_ip4_rx_p2p_subif(self):
451         """receive ipv4 packet via p2p subinterface"""
452         self.logger.info("FFP_TEST_START_0002")
453
454         route_9000 = VppIpRoute(
455             self,
456             "9.0.0.0",
457             16,
458             [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
459         )
460         route_9000.add_vpp_config()
461
462         self.packets.append(
463             self.create_stream(
464                 src_mac=self.pg0._remote_hosts[0].mac,
465                 dst_mac=self.pg0.local_mac,
466                 src_ip=self.p2p_sub_ifs[0].remote_ip4,
467                 dst_ip="9.0.0.100",
468             )
469         )
470
471         self.send_packets(self.pg0, self.pg1, self.packets)
472
473         self.assert_packet_counter_equal("p2p-ethernet-input", 1)
474
475         route_9000.remove_vpp_config()
476         self.logger.info("FFP_TEST_FINISH_0002")
477
478     def test_ip4_rx_p2p_subif_route(self):
479         """route rx packet not matching p2p subinterface"""
480         self.logger.info("FFP_TEST_START_0003")
481
482         route_9001 = VppIpRoute(
483             self,
484             "9.0.0.0",
485             24,
486             [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)],
487         )
488         route_9001.add_vpp_config()
489
490         self.packets.append(
491             self.create_stream(
492                 src_mac="02:01:00:00:ff:ff",
493                 dst_mac=self.pg0.local_mac,
494                 src_ip="8.0.0.100",
495                 dst_ip="9.0.0.100",
496             )
497         )
498
499         self.send_packets(self.pg0, self.pg1)
500
501         route_9001.remove_vpp_config()
502
503         self.logger.info("FFP_TEST_FINISH_0003")
504
505     def test_ip4_tx_p2p_subif(self):
506         """send ip4 packet via p2p subinterface"""
507         self.logger.info("FFP_TEST_START_0005")
508
509         route_9100 = VppIpRoute(
510             self,
511             "9.1.0.100",
512             24,
513             [
514                 VppRoutePath(
515                     self.pg0.remote_ip4,
516                     self.pg0.sw_if_index,
517                 )
518             ],
519         )
520         route_9100.add_vpp_config()
521         route_9200 = VppIpRoute(
522             self,
523             "9.2.0.100",
524             24,
525             [
526                 VppRoutePath(
527                     self.p2p_sub_ifs[0].remote_ip4,
528                     self.p2p_sub_ifs[0].sw_if_index,
529                 )
530             ],
531         )
532         route_9200.add_vpp_config()
533         route_9300 = VppIpRoute(
534             self,
535             "9.3.0.100",
536             24,
537             [
538                 VppRoutePath(
539                     self.p2p_sub_ifs[1].remote_ip4, self.p2p_sub_ifs[1].sw_if_index
540                 )
541             ],
542         )
543         route_9300.add_vpp_config()
544
545         for i in range(0, 3):
546             self.packets.append(
547                 self.create_stream(
548                     src_mac=self.pg1.remote_mac,
549                     dst_mac=self.pg1.local_mac,
550                     src_ip=self.pg1.remote_ip4,
551                     dst_ip="9.%d.0.100" % (i + 1),
552                 )
553             )
554
555         self.send_packets(self.pg1, self.pg0)
556
557         # route_7000.remove_vpp_config()
558         route_9100.remove_vpp_config()
559         route_9200.remove_vpp_config()
560         route_9300.remove_vpp_config()
561
562         self.logger.info("FFP_TEST_FINISH_0005")
563
564     def test_ip4_tx_p2p_subif_drop(self):
565         """drop tx ip4 packet not matching p2p subinterface"""
566         self.logger.info("FFP_TEST_START_0006")
567
568         self.packets.append(
569             self.create_stream(
570                 src_mac="02:01:00:00:ff:ff",
571                 dst_mac=self.pg0.local_mac,
572                 src_ip="8.0.0.100",
573                 dst_ip="9.0.0.100",
574             )
575         )
576
577         # no packet received
578         self.send_packets(self.pg0, self.pg1, count=0)
579         self.logger.info("FFP_TEST_FINISH_0006")
580
581
582 if __name__ == "__main__":
583     unittest.main(testRunner=VppTestRunner)