blob: 34a4c24f65586417e89ed654f81ab61825c091c7 [file] [log] [blame]
Pavel Kotucek15ac81c2017-06-20 14:00:26 +02001#!/usr/bin/env python
2import random
3import unittest
4import datetime
5import re
6
7from scapy.packet import Raw
8from scapy.layers.l2 import Ether
9from scapy.layers.inet import IP, UDP
10from scapy.layers.inet6 import IPv6
11
Gabriel Ganne7e665d62017-11-17 09:18:53 +010012from framework import VppTestCase, VppTestRunner
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020013from vpp_sub_interface import VppP2PSubint
Neale Rannsc0a93142018-09-05 15:42:26 -070014from vpp_ip import DpoProto
15from vpp_ip_route import VppIpRoute, VppRoutePath
Ole Troan8006c6a2018-12-17 12:02:26 +010016from vpp_papi import mac_pton
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020017
18
19class P2PEthernetAPI(VppTestCase):
20 """P2P Ethernet tests"""
21
22 p2p_sub_ifs = []
23
24 @classmethod
25 def setUpClass(cls):
26 super(P2PEthernetAPI, cls).setUpClass()
27
28 # Create pg interfaces
29 cls.create_pg_interfaces(range(4))
30
31 # Set up all interfaces
32 for i in cls.pg_interfaces:
33 i.admin_up()
34
35 def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
Ole Troan8006c6a2018-12-17 12:02:26 +010036 p2p = VppP2PSubint(self, parent_if, sub_id, mac_pton(remote_mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020037 self.p2p_sub_ifs.append(p2p)
38
39 def delete_p2p_ethernet(self, parent_if, remote_mac):
40 self.vapi.delete_p2pethernet_subif(parent_if.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +010041 mac_pton(remote_mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020042
43 def test_api(self):
44 """delete/create p2p subif"""
45 self.logger.info("FFP_TEST_START_0000")
46
47 self.create_p2p_ethernet(self.pg0, 1, "de:ad:00:00:00:01")
48 self.create_p2p_ethernet(self.pg0, 2, "de:ad:00:00:00:02")
49 intfs = self.vapi.cli("show interface")
50
51 self.assertNotEqual(intfs.find('pg0.1'), -1)
52 self.assertNotEqual(intfs.find('pg0.2'), -1)
53 self.assertEqual(intfs.find('pg0.5'), -1)
54
55 # create pg2.5 subif
56 self.create_p2p_ethernet(self.pg0, 5, "de:ad:00:00:00:ff")
57 intfs = self.vapi.cli("show interface")
58 self.assertNotEqual(intfs.find('pg0.5'), -1)
59 # delete pg2.5 subif
60 self.delete_p2p_ethernet(self.pg0, "de:ad:00:00:00:ff")
61
62 intfs = self.vapi.cli("show interface")
63
64 self.assertNotEqual(intfs.find('pg0.1'), -1)
65 self.assertNotEqual(intfs.find('pg0.2'), -1)
66 self.assertEqual(intfs.find('pg0.5'), -1)
67
68 self.logger.info("FFP_TEST_FINISH_0000")
69
70 def test_p2p_subif_creation_1k(self):
71 """create 1k of p2p subifs"""
72 self.logger.info("FFP_TEST_START_0001")
73
74 macs = []
75 clients = 1000
76 mac = int("dead00000000", 16)
77
78 for i in range(1, clients+1):
79 try:
80 macs.append(':'.join(re.findall('..', '{:02x}'.format(mac+i))))
81 self.vapi.create_p2pethernet_subif(self.pg2.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +010082 mac_pton(macs[i-1]),
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020083 i)
84 except Exception:
Paul Vinciguerra661f91f2018-11-28 19:06:41 -080085 self.logger.info("Failed to create subif %d %s" % (
86 i, macs[i-1]))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020087 raise
88
89 intfs = self.vapi.cli("show interface").split("\n")
90 count = 0
91 for intf in intfs:
92 if intf.startswith('pg2.'):
93 count += 1
94 self.assertEqual(count, clients)
95
96 self.logger.info("FFP_TEST_FINISH_0001")
97
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020098
99class P2PEthernetIPV6(VppTestCase):
100 """P2P Ethernet IPv6 tests"""
101
102 p2p_sub_ifs = []
103 packets = []
104
105 @classmethod
106 def setUpClass(cls):
107 super(P2PEthernetIPV6, cls).setUpClass()
108
109 # Create pg interfaces
110 cls.create_pg_interfaces(range(3))
111
112 # Packet sizes
113 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
114
115 # Set up all interfaces
116 for i in cls.pg_interfaces:
117 i.admin_up()
118
119 cls.pg0.generate_remote_hosts(3)
120 cls.pg0.configure_ipv6_neighbors()
121
122 cls.pg1.config_ip6()
123 cls.pg1.generate_remote_hosts(3)
124 cls.pg1.configure_ipv6_neighbors()
125 cls.pg1.disable_ipv6_ra()
126
127 def setUp(self):
128 super(P2PEthernetIPV6, self).setUp()
129 for p in self.packets:
130 self.packets.remove(p)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700131 self.p2p_sub_ifs.append(
132 self.create_p2p_ethernet(self.pg0, 1,
133 self.pg0._remote_hosts[0].mac))
134 self.p2p_sub_ifs.append(
135 self.create_p2p_ethernet(self.pg0, 2,
136 self.pg0._remote_hosts[1].mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200137 self.vapi.cli("trace add p2p-ethernet-input 50")
138
139 def tearDown(self):
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700140 while len(self.p2p_sub_ifs):
141 p2p = self.p2p_sub_ifs.pop()
142 self.delete_p2p_ethernet(p2p)
143
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200144 super(P2PEthernetIPV6, self).tearDown()
145
146 def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
Ole Troan8006c6a2018-12-17 12:02:26 +0100147 p2p = VppP2PSubint(self, parent_if, sub_id, mac_pton(remote_mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200148 p2p.admin_up()
149 p2p.config_ip6()
150 p2p.disable_ipv6_ra()
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700151 return p2p
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200152
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700153 def delete_p2p_ethernet(self, p2p):
154 p2p.unconfig_ip6()
155 p2p.admin_down()
156 self.vapi.delete_p2pethernet_subif(p2p.parent.sw_if_index,
157 p2p.p2p_remote_mac)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200158
159 def create_stream(self, src_mac=None, dst_mac=None,
160 src_ip=None, dst_ip=None, size=None):
161 pkt_size = size
162 if size is None:
163 pkt_size = random.choice(self.pg_if_packet_sizes)
164 p = Ether(src=src_mac, dst=dst_mac)
165 p /= IPv6(src=src_ip, dst=dst_ip)
166 p /= (UDP(sport=1234, dport=4321) / Raw('\xa5' * 20))
167 self.extend_packet(p, pkt_size)
168 return p
169
170 def send_packets(self, src_if=None, dst_if=None, packets=None, count=None):
171 self.pg_enable_capture([dst_if])
172 if packets is None:
173 packets = self.packets
174 src_if.add_stream(packets)
175 self.pg_start()
176 if count is None:
177 count = len(packets)
178 return dst_if.get_capture(count)
179
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200180 def test_no_p2p_subif(self):
181 """standard routing without p2p subinterfaces"""
182 self.logger.info("FFP_TEST_START_0001")
183
184 route_8000 = VppIpRoute(self, "8000::", 64,
185 [VppRoutePath(self.pg0.remote_ip6,
186 self.pg0.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700187 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200188 is_ip6=1)
189 route_8000.add_vpp_config()
190
191 self.packets = [(Ether(dst=self.pg1.local_mac,
192 src=self.pg1.remote_mac) /
193 IPv6(src="3001::1", dst="8000::100") /
194 UDP(sport=1234, dport=1234) /
195 Raw('\xa5' * 100))]
196 self.send_packets(self.pg1, self.pg0)
197
198 self.logger.info("FFP_TEST_FINISH_0001")
199
200 def test_ip6_rx_p2p_subif(self):
201 """receive ipv6 packet via p2p subinterface"""
202 self.logger.info("FFP_TEST_START_0002")
203
204 route_9001 = VppIpRoute(self, "9001::", 64,
205 [VppRoutePath(self.pg1.remote_ip6,
206 self.pg1.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700207 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200208 is_ip6=1)
209 route_9001.add_vpp_config()
210
211 self.packets.append(
212 self.create_stream(src_mac=self.pg0._remote_hosts[0].mac,
213 dst_mac=self.pg0.local_mac,
214 src_ip=self.p2p_sub_ifs[0].remote_ip6,
215 dst_ip="9001::100"))
216
217 self.send_packets(self.pg0, self.pg1, self.packets)
Klement Sekeraf37c3ba2018-11-08 11:24:34 +0100218 self.assert_packet_counter_equal('p2p-ethernet-input', 1)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200219
220 route_9001.remove_vpp_config()
221 self.logger.info("FFP_TEST_FINISH_0002")
222
223 def test_ip6_rx_p2p_subif_route(self):
224 """route rx ip6 packet not matching p2p subinterface"""
225 self.logger.info("FFP_TEST_START_0003")
226
227 self.pg0.config_ip6()
228
229 route_3 = VppIpRoute(self, "9000::", 64,
230 [VppRoutePath(self.pg1._remote_hosts[0].ip6,
231 self.pg1.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700232 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200233 is_ip6=1)
234 route_3.add_vpp_config()
235
236 self.packets.append(
237 self.create_stream(src_mac="02:03:00:00:ff:ff",
238 dst_mac=self.pg0.local_mac,
239 src_ip="a000::100",
240 dst_ip="9000::100"))
241
242 self.send_packets(self.pg0, self.pg1)
243
244 self.pg0.unconfig_ip6()
245
246 route_3.remove_vpp_config()
247
248 self.logger.info("FFP_TEST_FINISH_0003")
249
250 def test_ip6_rx_p2p_subif_drop(self):
251 """drop rx packet not matching p2p subinterface"""
252 self.logger.info("FFP_TEST_START_0004")
253
254 route_9001 = VppIpRoute(self, "9000::", 64,
255 [VppRoutePath(self.pg1._remote_hosts[0].ip6,
256 self.pg1.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700257 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200258 is_ip6=1)
259 route_9001.add_vpp_config()
260
261 self.packets.append(
262 self.create_stream(src_mac="02:03:00:00:ff:ff",
263 dst_mac=self.pg0.local_mac,
264 src_ip="a000::100",
265 dst_ip="9000::100"))
266
267 # no packet received
268 self.send_packets(self.pg0, self.pg1, count=0)
269 self.logger.info("FFP_TEST_FINISH_0004")
270
271 def test_ip6_tx_p2p_subif(self):
272 """send packet via p2p subinterface"""
273 self.logger.info("FFP_TEST_START_0005")
274
275 route_8000 = VppIpRoute(self, "8000::", 64,
276 [VppRoutePath(self.pg0.remote_ip6,
277 self.pg0.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700278 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200279 is_ip6=1)
280 route_8000.add_vpp_config()
281 route_8001 = VppIpRoute(self, "8001::", 64,
282 [VppRoutePath(self.p2p_sub_ifs[0].remote_ip6,
283 self.p2p_sub_ifs[0].sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700284 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200285 is_ip6=1)
286 route_8001.add_vpp_config()
287 route_8002 = VppIpRoute(self, "8002::", 64,
288 [VppRoutePath(self.p2p_sub_ifs[1].remote_ip6,
289 self.p2p_sub_ifs[1].sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700290 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200291 is_ip6=1)
292 route_8002.add_vpp_config()
293
294 for i in range(0, 3):
295 self.packets.append(
296 self.create_stream(src_mac=self.pg1.remote_mac,
297 dst_mac=self.pg1.local_mac,
298 src_ip=self.pg1.remote_ip6,
299 dst_ip="800%d::100" % i))
300
301 self.send_packets(self.pg1, self.pg0, count=3)
302
303 route_8000.remove_vpp_config()
304 route_8001.remove_vpp_config()
305 route_8002.remove_vpp_config()
306
307 self.logger.info("FFP_TEST_FINISH_0005")
308
309 def test_ip6_tx_p2p_subif_drop(self):
310 """drop tx ip6 packet not matching p2p subinterface"""
311 self.logger.info("FFP_TEST_START_0006")
312
313 self.packets.append(
314 self.create_stream(src_mac="02:03:00:00:ff:ff",
315 dst_mac=self.pg0.local_mac,
316 src_ip="a000::100",
317 dst_ip="9000::100"))
318
319 # no packet received
320 self.send_packets(self.pg0, self.pg1, count=0)
321 self.logger.info("FFP_TEST_FINISH_0006")
322
323
324class P2PEthernetIPV4(VppTestCase):
325 """P2P Ethernet IPv4 tests"""
326
327 p2p_sub_ifs = []
328 packets = []
329
330 @classmethod
331 def setUpClass(cls):
332 super(P2PEthernetIPV4, cls).setUpClass()
333
334 # Create pg interfaces
335 cls.create_pg_interfaces(range(3))
336
337 # Packet sizes
338 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
339
340 # Set up all interfaces
341 for i in cls.pg_interfaces:
342 i.admin_up()
343
344 cls.pg0.config_ip4()
345 cls.pg0.generate_remote_hosts(5)
346 cls.pg0.configure_ipv4_neighbors()
347
348 cls.pg1.config_ip4()
349 cls.pg1.generate_remote_hosts(5)
350 cls.pg1.configure_ipv4_neighbors()
351
352 def setUp(self):
353 super(P2PEthernetIPV4, self).setUp()
354 for p in self.packets:
355 self.packets.remove(p)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700356 self.p2p_sub_ifs.append(
357 self.create_p2p_ethernet(self.pg0, 1,
358 self.pg0._remote_hosts[0].mac))
359 self.p2p_sub_ifs.append(
360 self.create_p2p_ethernet(self.pg0, 2,
361 self.pg0._remote_hosts[1].mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200362 self.vapi.cli("trace add p2p-ethernet-input 50")
363
364 def tearDown(self):
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700365 while len(self.p2p_sub_ifs):
366 p2p = self.p2p_sub_ifs.pop()
367 self.delete_p2p_ethernet(p2p)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200368 super(P2PEthernetIPV4, self).tearDown()
369
370 def create_stream(self, src_mac=None, dst_mac=None,
371 src_ip=None, dst_ip=None, size=None):
372 pkt_size = size
373 if size is None:
374 pkt_size = random.choice(self.pg_if_packet_sizes)
375 p = Ether(src=src_mac, dst=dst_mac)
376 p /= IP(src=src_ip, dst=dst_ip)
377 p /= (UDP(sport=1234, dport=4321) / Raw('\xa5' * 20))
378 self.extend_packet(p, pkt_size)
379 return p
380
381 def send_packets(self, src_if=None, dst_if=None, packets=None, count=None):
382 self.pg_enable_capture([dst_if])
383 if packets is None:
384 packets = self.packets
385 src_if.add_stream(packets)
386 self.pg_start()
387 if count is None:
388 count = len(packets)
389 return dst_if.get_capture(count)
390
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200391 def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
Ole Troan8006c6a2018-12-17 12:02:26 +0100392 p2p = VppP2PSubint(self, parent_if, sub_id, mac_pton(remote_mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200393 p2p.admin_up()
394 p2p.config_ip4()
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700395 return p2p
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200396
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700397 def delete_p2p_ethernet(self, p2p):
398 p2p.unconfig_ip4()
399 p2p.admin_down()
400 self.vapi.delete_p2pethernet_subif(p2p.parent.sw_if_index,
401 p2p.p2p_remote_mac)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200402
403 def test_ip4_rx_p2p_subif(self):
404 """receive ipv4 packet via p2p subinterface"""
405 self.logger.info("FFP_TEST_START_0002")
406
407 route_9000 = VppIpRoute(self, "9.0.0.0", 16,
408 [VppRoutePath(self.pg1.remote_ip4,
409 self.pg1.sw_if_index)])
410 route_9000.add_vpp_config()
411
412 self.packets.append(
413 self.create_stream(src_mac=self.pg0._remote_hosts[0].mac,
414 dst_mac=self.pg0.local_mac,
415 src_ip=self.p2p_sub_ifs[0].remote_ip4,
416 dst_ip="9.0.0.100"))
417
418 self.send_packets(self.pg0, self.pg1, self.packets)
419
Klement Sekeraf37c3ba2018-11-08 11:24:34 +0100420 self.assert_packet_counter_equal('p2p-ethernet-input', 1)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200421
422 route_9000.remove_vpp_config()
423 self.logger.info("FFP_TEST_FINISH_0002")
424
425 def test_ip4_rx_p2p_subif_route(self):
426 """route rx packet not matching p2p subinterface"""
427 self.logger.info("FFP_TEST_START_0003")
428
429 route_9001 = VppIpRoute(self, "9.0.0.0", 24,
430 [VppRoutePath(self.pg1.remote_ip4,
431 self.pg1.sw_if_index)])
432 route_9001.add_vpp_config()
433
434 self.packets.append(
435 self.create_stream(src_mac="02:01:00:00:ff:ff",
436 dst_mac=self.pg0.local_mac,
437 src_ip="8.0.0.100",
438 dst_ip="9.0.0.100"))
439
440 self.send_packets(self.pg0, self.pg1)
441
442 route_9001.remove_vpp_config()
443
444 self.logger.info("FFP_TEST_FINISH_0003")
445
446 def test_ip4_tx_p2p_subif(self):
447 """send ip4 packet via p2p subinterface"""
448 self.logger.info("FFP_TEST_START_0005")
449
450 route_9100 = VppIpRoute(self, "9.1.0.100", 24,
451 [VppRoutePath(self.pg0.remote_ip4,
452 self.pg0.sw_if_index,
453 )])
454 route_9100.add_vpp_config()
455 route_9200 = VppIpRoute(self, "9.2.0.100", 24,
456 [VppRoutePath(self.p2p_sub_ifs[0].remote_ip4,
457 self.p2p_sub_ifs[0].sw_if_index,
458 )])
459 route_9200.add_vpp_config()
460 route_9300 = VppIpRoute(self, "9.3.0.100", 24,
461 [VppRoutePath(self.p2p_sub_ifs[1].remote_ip4,
462 self.p2p_sub_ifs[1].sw_if_index
463 )])
464 route_9300.add_vpp_config()
465
466 for i in range(0, 3):
467 self.packets.append(
468 self.create_stream(src_mac=self.pg1.remote_mac,
469 dst_mac=self.pg1.local_mac,
470 src_ip=self.pg1.remote_ip4,
471 dst_ip="9.%d.0.100" % (i+1)))
472
473 self.send_packets(self.pg1, self.pg0)
474
475 # route_7000.remove_vpp_config()
476 route_9100.remove_vpp_config()
477 route_9200.remove_vpp_config()
478 route_9300.remove_vpp_config()
479
480 self.logger.info("FFP_TEST_FINISH_0005")
481
482 def test_ip4_tx_p2p_subif_drop(self):
483 """drop tx ip4 packet not matching p2p subinterface"""
484 self.logger.info("FFP_TEST_START_0006")
485
486 self.packets.append(
487 self.create_stream(src_mac="02:01:00:00:ff:ff",
488 dst_mac=self.pg0.local_mac,
489 src_ip="8.0.0.100",
490 dst_ip="9.0.0.100"))
491
492 # no packet received
493 self.send_packets(self.pg0, self.pg1, count=0)
494 self.logger.info("FFP_TEST_FINISH_0006")
495
496
497if __name__ == '__main__':
498 unittest.main(testRunner=VppTestRunner)