blob: a4eeee0e47d8a8ba253abc149cbf440ffa3be23b [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
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020016from util import mactobinary
17
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):
36 p2p = VppP2PSubint(self, parent_if, sub_id, mactobinary(remote_mac))
37 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,
41 mactobinary(remote_mac))
42
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,
82 mactobinary(macs[i-1]),
83 i)
84 except Exception:
85 print "Failed to create subif %d %s" % (i, macs[i-1])
86 raise
87
88 intfs = self.vapi.cli("show interface").split("\n")
89 count = 0
90 for intf in intfs:
91 if intf.startswith('pg2.'):
92 count += 1
93 self.assertEqual(count, clients)
94
95 self.logger.info("FFP_TEST_FINISH_0001")
96
Pavel Kotucek15ac81c2017-06-20 14:00:26 +020097
98class P2PEthernetIPV6(VppTestCase):
99 """P2P Ethernet IPv6 tests"""
100
101 p2p_sub_ifs = []
102 packets = []
103
104 @classmethod
105 def setUpClass(cls):
106 super(P2PEthernetIPV6, cls).setUpClass()
107
108 # Create pg interfaces
109 cls.create_pg_interfaces(range(3))
110
111 # Packet sizes
112 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
113
114 # Set up all interfaces
115 for i in cls.pg_interfaces:
116 i.admin_up()
117
118 cls.pg0.generate_remote_hosts(3)
119 cls.pg0.configure_ipv6_neighbors()
120
121 cls.pg1.config_ip6()
122 cls.pg1.generate_remote_hosts(3)
123 cls.pg1.configure_ipv6_neighbors()
124 cls.pg1.disable_ipv6_ra()
125
126 def setUp(self):
127 super(P2PEthernetIPV6, self).setUp()
128 for p in self.packets:
129 self.packets.remove(p)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700130 self.p2p_sub_ifs.append(
131 self.create_p2p_ethernet(self.pg0, 1,
132 self.pg0._remote_hosts[0].mac))
133 self.p2p_sub_ifs.append(
134 self.create_p2p_ethernet(self.pg0, 2,
135 self.pg0._remote_hosts[1].mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200136 self.vapi.cli("trace add p2p-ethernet-input 50")
137
138 def tearDown(self):
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700139 while len(self.p2p_sub_ifs):
140 p2p = self.p2p_sub_ifs.pop()
141 self.delete_p2p_ethernet(p2p)
142
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200143 super(P2PEthernetIPV6, self).tearDown()
144
145 def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
146 p2p = VppP2PSubint(self, parent_if, sub_id, mactobinary(remote_mac))
147 p2p.admin_up()
148 p2p.config_ip6()
149 p2p.disable_ipv6_ra()
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700150 return p2p
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200151
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700152 def delete_p2p_ethernet(self, p2p):
153 p2p.unconfig_ip6()
154 p2p.admin_down()
155 self.vapi.delete_p2pethernet_subif(p2p.parent.sw_if_index,
156 p2p.p2p_remote_mac)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200157
158 def create_stream(self, src_mac=None, dst_mac=None,
159 src_ip=None, dst_ip=None, size=None):
160 pkt_size = size
161 if size is None:
162 pkt_size = random.choice(self.pg_if_packet_sizes)
163 p = Ether(src=src_mac, dst=dst_mac)
164 p /= IPv6(src=src_ip, dst=dst_ip)
165 p /= (UDP(sport=1234, dport=4321) / Raw('\xa5' * 20))
166 self.extend_packet(p, pkt_size)
167 return p
168
169 def send_packets(self, src_if=None, dst_if=None, packets=None, count=None):
170 self.pg_enable_capture([dst_if])
171 if packets is None:
172 packets = self.packets
173 src_if.add_stream(packets)
174 self.pg_start()
175 if count is None:
176 count = len(packets)
177 return dst_if.get_capture(count)
178
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200179 def test_no_p2p_subif(self):
180 """standard routing without p2p subinterfaces"""
181 self.logger.info("FFP_TEST_START_0001")
182
183 route_8000 = VppIpRoute(self, "8000::", 64,
184 [VppRoutePath(self.pg0.remote_ip6,
185 self.pg0.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700186 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200187 is_ip6=1)
188 route_8000.add_vpp_config()
189
190 self.packets = [(Ether(dst=self.pg1.local_mac,
191 src=self.pg1.remote_mac) /
192 IPv6(src="3001::1", dst="8000::100") /
193 UDP(sport=1234, dport=1234) /
194 Raw('\xa5' * 100))]
195 self.send_packets(self.pg1, self.pg0)
196
197 self.logger.info("FFP_TEST_FINISH_0001")
198
199 def test_ip6_rx_p2p_subif(self):
200 """receive ipv6 packet via p2p subinterface"""
201 self.logger.info("FFP_TEST_START_0002")
202
203 route_9001 = VppIpRoute(self, "9001::", 64,
204 [VppRoutePath(self.pg1.remote_ip6,
205 self.pg1.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700206 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200207 is_ip6=1)
208 route_9001.add_vpp_config()
209
210 self.packets.append(
211 self.create_stream(src_mac=self.pg0._remote_hosts[0].mac,
212 dst_mac=self.pg0.local_mac,
213 src_ip=self.p2p_sub_ifs[0].remote_ip6,
214 dst_ip="9001::100"))
215
216 self.send_packets(self.pg0, self.pg1, self.packets)
Klement Sekeraf37c3ba2018-11-08 11:24:34 +0100217 self.assert_packet_counter_equal('p2p-ethernet-input', 1)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200218
219 route_9001.remove_vpp_config()
220 self.logger.info("FFP_TEST_FINISH_0002")
221
222 def test_ip6_rx_p2p_subif_route(self):
223 """route rx ip6 packet not matching p2p subinterface"""
224 self.logger.info("FFP_TEST_START_0003")
225
226 self.pg0.config_ip6()
227
228 route_3 = VppIpRoute(self, "9000::", 64,
229 [VppRoutePath(self.pg1._remote_hosts[0].ip6,
230 self.pg1.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700231 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200232 is_ip6=1)
233 route_3.add_vpp_config()
234
235 self.packets.append(
236 self.create_stream(src_mac="02:03:00:00:ff:ff",
237 dst_mac=self.pg0.local_mac,
238 src_ip="a000::100",
239 dst_ip="9000::100"))
240
241 self.send_packets(self.pg0, self.pg1)
242
243 self.pg0.unconfig_ip6()
244
245 route_3.remove_vpp_config()
246
247 self.logger.info("FFP_TEST_FINISH_0003")
248
249 def test_ip6_rx_p2p_subif_drop(self):
250 """drop rx packet not matching p2p subinterface"""
251 self.logger.info("FFP_TEST_START_0004")
252
253 route_9001 = VppIpRoute(self, "9000::", 64,
254 [VppRoutePath(self.pg1._remote_hosts[0].ip6,
255 self.pg1.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700256 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200257 is_ip6=1)
258 route_9001.add_vpp_config()
259
260 self.packets.append(
261 self.create_stream(src_mac="02:03:00:00:ff:ff",
262 dst_mac=self.pg0.local_mac,
263 src_ip="a000::100",
264 dst_ip="9000::100"))
265
266 # no packet received
267 self.send_packets(self.pg0, self.pg1, count=0)
268 self.logger.info("FFP_TEST_FINISH_0004")
269
270 def test_ip6_tx_p2p_subif(self):
271 """send packet via p2p subinterface"""
272 self.logger.info("FFP_TEST_START_0005")
273
274 route_8000 = VppIpRoute(self, "8000::", 64,
275 [VppRoutePath(self.pg0.remote_ip6,
276 self.pg0.sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700277 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200278 is_ip6=1)
279 route_8000.add_vpp_config()
280 route_8001 = VppIpRoute(self, "8001::", 64,
281 [VppRoutePath(self.p2p_sub_ifs[0].remote_ip6,
282 self.p2p_sub_ifs[0].sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700283 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200284 is_ip6=1)
285 route_8001.add_vpp_config()
286 route_8002 = VppIpRoute(self, "8002::", 64,
287 [VppRoutePath(self.p2p_sub_ifs[1].remote_ip6,
288 self.p2p_sub_ifs[1].sw_if_index,
Neale Rannsda78f952017-05-24 09:15:43 -0700289 proto=DpoProto.DPO_PROTO_IP6)],
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200290 is_ip6=1)
291 route_8002.add_vpp_config()
292
293 for i in range(0, 3):
294 self.packets.append(
295 self.create_stream(src_mac=self.pg1.remote_mac,
296 dst_mac=self.pg1.local_mac,
297 src_ip=self.pg1.remote_ip6,
298 dst_ip="800%d::100" % i))
299
300 self.send_packets(self.pg1, self.pg0, count=3)
301
302 route_8000.remove_vpp_config()
303 route_8001.remove_vpp_config()
304 route_8002.remove_vpp_config()
305
306 self.logger.info("FFP_TEST_FINISH_0005")
307
308 def test_ip6_tx_p2p_subif_drop(self):
309 """drop tx ip6 packet not matching p2p subinterface"""
310 self.logger.info("FFP_TEST_START_0006")
311
312 self.packets.append(
313 self.create_stream(src_mac="02:03:00:00:ff:ff",
314 dst_mac=self.pg0.local_mac,
315 src_ip="a000::100",
316 dst_ip="9000::100"))
317
318 # no packet received
319 self.send_packets(self.pg0, self.pg1, count=0)
320 self.logger.info("FFP_TEST_FINISH_0006")
321
322
323class P2PEthernetIPV4(VppTestCase):
324 """P2P Ethernet IPv4 tests"""
325
326 p2p_sub_ifs = []
327 packets = []
328
329 @classmethod
330 def setUpClass(cls):
331 super(P2PEthernetIPV4, cls).setUpClass()
332
333 # Create pg interfaces
334 cls.create_pg_interfaces(range(3))
335
336 # Packet sizes
337 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
338
339 # Set up all interfaces
340 for i in cls.pg_interfaces:
341 i.admin_up()
342
343 cls.pg0.config_ip4()
344 cls.pg0.generate_remote_hosts(5)
345 cls.pg0.configure_ipv4_neighbors()
346
347 cls.pg1.config_ip4()
348 cls.pg1.generate_remote_hosts(5)
349 cls.pg1.configure_ipv4_neighbors()
350
351 def setUp(self):
352 super(P2PEthernetIPV4, self).setUp()
353 for p in self.packets:
354 self.packets.remove(p)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700355 self.p2p_sub_ifs.append(
356 self.create_p2p_ethernet(self.pg0, 1,
357 self.pg0._remote_hosts[0].mac))
358 self.p2p_sub_ifs.append(
359 self.create_p2p_ethernet(self.pg0, 2,
360 self.pg0._remote_hosts[1].mac))
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200361 self.vapi.cli("trace add p2p-ethernet-input 50")
362
363 def tearDown(self):
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700364 while len(self.p2p_sub_ifs):
365 p2p = self.p2p_sub_ifs.pop()
366 self.delete_p2p_ethernet(p2p)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200367 super(P2PEthernetIPV4, self).tearDown()
368
369 def create_stream(self, src_mac=None, dst_mac=None,
370 src_ip=None, dst_ip=None, size=None):
371 pkt_size = size
372 if size is None:
373 pkt_size = random.choice(self.pg_if_packet_sizes)
374 p = Ether(src=src_mac, dst=dst_mac)
375 p /= IP(src=src_ip, dst=dst_ip)
376 p /= (UDP(sport=1234, dport=4321) / Raw('\xa5' * 20))
377 self.extend_packet(p, pkt_size)
378 return p
379
380 def send_packets(self, src_if=None, dst_if=None, packets=None, count=None):
381 self.pg_enable_capture([dst_if])
382 if packets is None:
383 packets = self.packets
384 src_if.add_stream(packets)
385 self.pg_start()
386 if count is None:
387 count = len(packets)
388 return dst_if.get_capture(count)
389
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200390 def create_p2p_ethernet(self, parent_if, sub_id, remote_mac):
391 p2p = VppP2PSubint(self, parent_if, sub_id, mactobinary(remote_mac))
392 p2p.admin_up()
393 p2p.config_ip4()
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700394 return p2p
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200395
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700396 def delete_p2p_ethernet(self, p2p):
397 p2p.unconfig_ip4()
398 p2p.admin_down()
399 self.vapi.delete_p2pethernet_subif(p2p.parent.sw_if_index,
400 p2p.p2p_remote_mac)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200401
402 def test_ip4_rx_p2p_subif(self):
403 """receive ipv4 packet via p2p subinterface"""
404 self.logger.info("FFP_TEST_START_0002")
405
406 route_9000 = VppIpRoute(self, "9.0.0.0", 16,
407 [VppRoutePath(self.pg1.remote_ip4,
408 self.pg1.sw_if_index)])
409 route_9000.add_vpp_config()
410
411 self.packets.append(
412 self.create_stream(src_mac=self.pg0._remote_hosts[0].mac,
413 dst_mac=self.pg0.local_mac,
414 src_ip=self.p2p_sub_ifs[0].remote_ip4,
415 dst_ip="9.0.0.100"))
416
417 self.send_packets(self.pg0, self.pg1, self.packets)
418
Klement Sekeraf37c3ba2018-11-08 11:24:34 +0100419 self.assert_packet_counter_equal('p2p-ethernet-input', 1)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200420
421 route_9000.remove_vpp_config()
422 self.logger.info("FFP_TEST_FINISH_0002")
423
424 def test_ip4_rx_p2p_subif_route(self):
425 """route rx packet not matching p2p subinterface"""
426 self.logger.info("FFP_TEST_START_0003")
427
428 route_9001 = VppIpRoute(self, "9.0.0.0", 24,
429 [VppRoutePath(self.pg1.remote_ip4,
430 self.pg1.sw_if_index)])
431 route_9001.add_vpp_config()
432
433 self.packets.append(
434 self.create_stream(src_mac="02:01:00:00:ff:ff",
435 dst_mac=self.pg0.local_mac,
436 src_ip="8.0.0.100",
437 dst_ip="9.0.0.100"))
438
439 self.send_packets(self.pg0, self.pg1)
440
441 route_9001.remove_vpp_config()
442
443 self.logger.info("FFP_TEST_FINISH_0003")
444
445 def test_ip4_tx_p2p_subif(self):
446 """send ip4 packet via p2p subinterface"""
447 self.logger.info("FFP_TEST_START_0005")
448
449 route_9100 = VppIpRoute(self, "9.1.0.100", 24,
450 [VppRoutePath(self.pg0.remote_ip4,
451 self.pg0.sw_if_index,
452 )])
453 route_9100.add_vpp_config()
454 route_9200 = VppIpRoute(self, "9.2.0.100", 24,
455 [VppRoutePath(self.p2p_sub_ifs[0].remote_ip4,
456 self.p2p_sub_ifs[0].sw_if_index,
457 )])
458 route_9200.add_vpp_config()
459 route_9300 = VppIpRoute(self, "9.3.0.100", 24,
460 [VppRoutePath(self.p2p_sub_ifs[1].remote_ip4,
461 self.p2p_sub_ifs[1].sw_if_index
462 )])
463 route_9300.add_vpp_config()
464
465 for i in range(0, 3):
466 self.packets.append(
467 self.create_stream(src_mac=self.pg1.remote_mac,
468 dst_mac=self.pg1.local_mac,
469 src_ip=self.pg1.remote_ip4,
470 dst_ip="9.%d.0.100" % (i+1)))
471
472 self.send_packets(self.pg1, self.pg0)
473
474 # route_7000.remove_vpp_config()
475 route_9100.remove_vpp_config()
476 route_9200.remove_vpp_config()
477 route_9300.remove_vpp_config()
478
479 self.logger.info("FFP_TEST_FINISH_0005")
480
481 def test_ip4_tx_p2p_subif_drop(self):
482 """drop tx ip4 packet not matching p2p subinterface"""
483 self.logger.info("FFP_TEST_START_0006")
484
485 self.packets.append(
486 self.create_stream(src_mac="02:01:00:00:ff:ff",
487 dst_mac=self.pg0.local_mac,
488 src_ip="8.0.0.100",
489 dst_ip="9.0.0.100"))
490
491 # no packet received
492 self.send_packets(self.pg0, self.pg1, count=0)
493 self.logger.info("FFP_TEST_FINISH_0006")
494
495
496if __name__ == '__main__':
497 unittest.main(testRunner=VppTestRunner)