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