8 from struct import unpack, unpack_from
11 import unittest2 as unittest
15 from util import ppp, ppc
16 from re import compile
18 from scapy.packet import Raw
19 from scapy.layers.l2 import Ether
20 from scapy.layers.inet import IP, UDP, ICMP
21 import scapy.layers.inet6 as inet6
22 from scapy.layers.inet6 import IPv6, ICMPv6DestUnreach
24 from framework import VppTestCase, VppTestRunner
26 from vpp_ip import DpoProto
27 from vpp_ip_route import VppIpRoute, VppRoutePath
33 def get_mac_addr(bytes_addr):
34 return ':'.join('%02x' % scapy.compat.orb(b) for b in bytes_addr)
39 return '.'.join('%d' % scapy.compat.orb(b) for b in bytes_addr)
42 # Unpack Ethernet Frame
43 def ethernet_frame(data):
44 dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])
45 return dest_mac, src_mac, socket.htons(proto), data[14:]
49 def ipv4_packet(data):
50 proto, src, target = struct.unpack('! 8x 1x B 2x 4s 4s', data[:20])
51 return proto, src, target, data[20:]
55 def ipv6_packet(data):
56 nh, src, target = struct.unpack('! 6x B 1x 16s 16s', data[:40])
57 return nh, src, target, data[40:]
60 # Unpacks any UDP Packet
62 src_port, dest_port, size = struct.unpack('! H H 2x H', data[:8])
63 return src_port, dest_port, size, data[8:]
66 # Unpacks any TCP Packet
68 src_port, dest_port, seq, flag = struct.unpack('! H H L 4x H', data[:14])
69 return src_port, dest_port, seq, data[((flag >> 12) * 4):]
72 def receivePackets(sock, counters):
73 # Wait for some packets on socket
75 data = sock.recv(65536)
77 # punt socket metadata
78 # packet_desc = data[0:8]
81 _, _, eth_proto, data = ethernet_frame(data[8:])
84 proto, _, _, data = ipv4_packet(data)
87 _, dst_port, _, data = udp_seg(data)
90 _, dst_port, _, data = udp_seg(data)
91 counters[dst_port] = 0
93 elif eth_proto == 0xdd86:
94 nh, _, _, data = ipv6_packet(data)
97 _, dst_port, _, data = udp_seg(data)
100 _, dst_port, _, data = udp_seg(data)
101 counters[dst_port] = 0
104 class serverSocketThread(threading.Thread):
105 """ Socket server thread"""
107 def __init__(self, threadID, sockName, counters):
108 threading.Thread.__init__(self)
109 self.threadID = threadID
110 self.sockName = sockName
112 self.counters = counters
115 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
117 os.unlink(self.sockName)
120 self.sock.bind(self.sockName)
122 receivePackets(self.sock, self.counters)
125 class TestPuntSocket(VppTestCase):
128 ports = [1111, 2222, 3333, 4444]
129 sock_servers = list()
135 super(TestPuntSocket, cls).setUpClass()
138 def tearDownClass(cls):
139 super(TestPuntSocket, cls).tearDownClass()
142 def setUpConstants(cls):
143 cls.extra_vpp_punt_config = [
144 "punt", "{", "socket", cls.tempdir+"/socket_punt", "}"]
145 super(TestPuntSocket, cls).setUpConstants()
148 super(TestPuntSocket, self).setUp()
151 self.create_pg_interfaces(range(2))
152 for i in self.pg_interfaces:
156 del self.sock_servers[:]
157 super(TestPuntSocket, self).tearDown()
159 def socket_client_create(self, sock_name, id=None):
160 thread = serverSocketThread(id, sock_name, self.portsCheck)
161 self.sock_servers.append(thread)
164 def socket_client_close(self):
165 for thread in self.sock_servers:
169 class TestIP4PuntSocket(TestPuntSocket):
170 """ Punt Socket for IPv4 """
174 super(TestIP4PuntSocket, cls).setUpClass()
177 def tearDownClass(cls):
178 super(TestIP4PuntSocket, cls).tearDownClass()
181 super(TestIP4PuntSocket, self).setUp()
183 for i in self.pg_interfaces:
188 super(TestIP4PuntSocket, self).tearDown()
189 for i in self.pg_interfaces:
193 def test_punt_socket_dump(self):
194 """ Punt socket registration/deregistration"""
196 punts = self.vapi.punt_socket_dump(is_ip6=0)
197 self.assertEqual(len(punts), 0)
200 # configure a punt socket
202 self.vapi.punt_socket_register(1111, b"%s/socket_punt_1111" %
203 six.ensure_binary(self.tempdir))
204 self.vapi.punt_socket_register(2222, b"%s/socket_punt_2222" %
205 six.ensure_binary(self.tempdir))
206 punts = self.vapi.punt_socket_dump(is_ip6=0)
207 self.assertEqual(len(punts), 2)
208 self.assertEqual(punts[0].punt.l4_port, 1111)
209 self.assertEqual(punts[1].punt.l4_port, 2222)
212 # deregister a punt socket
214 self.vapi.punt_socket_deregister(1111)
215 punts = self.vapi.punt_socket_dump(is_ip6=0)
216 self.assertEqual(len(punts), 1)
219 # configure a punt socket again
221 self.vapi.punt_socket_register(1111, b"%s/socket_punt_1111" %
222 six.ensure_binary(self.tempdir))
223 self.vapi.punt_socket_register(3333, b"%s/socket_punt_3333" %
224 six.ensure_binary(self.tempdir))
225 punts = self.vapi.punt_socket_dump(is_ip6=0)
226 self.assertEqual(len(punts), 3)
229 # deregister all punt socket
231 self.vapi.punt_socket_deregister(1111)
232 self.vapi.punt_socket_deregister(2222)
233 self.vapi.punt_socket_deregister(3333)
234 punts = self.vapi.punt_socket_dump(is_ip6=0)
235 self.assertEqual(len(punts), 0)
237 def test_punt_socket_traffic_single_port_single_socket(self):
238 """ Punt socket traffic single port single socket"""
242 p = (Ether(src=self.pg0.remote_mac,
243 dst=self.pg0.local_mac) /
244 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
245 UDP(sport=9876, dport=port) /
248 pkts = p * self.nr_packets
249 self.portsCheck[port] = self.nr_packets
251 punts = self.vapi.punt_socket_dump(is_ip6=0)
252 self.assertEqual(len(punts), 0)
255 # expect ICMP - port unreachable for all packets
257 self.vapi.cli("clear trace")
258 self.pg0.add_stream(pkts)
259 self.pg_enable_capture(self.pg_interfaces)
261 # FIXME - when punt socket deregister is implemented
262 # rx = self.pg0.get_capture(self.nr_packets)
264 # self.assertEqual(int(p[IP].proto), 1) # ICMP
265 # self.assertEqual(int(p[ICMP].code), 3) # unreachable
268 # configure a punt socket
270 self.socket_client_create(b"%s/socket_%d" % (
271 six.ensure_binary(self.tempdir), port))
272 self.vapi.punt_socket_register(port, b"%s/socket_%d" % (
273 six.ensure_binary(self.tempdir), port))
274 punts = self.vapi.punt_socket_dump(is_ip6=0)
275 self.assertEqual(len(punts), 1)
277 self.logger.debug("Sending %s packets to port %d",
278 str(self.portsCheck[port]), port)
280 # expect punt socket and no packets on pg0
282 self.vapi.cli("clear errors")
283 self.vapi.cli("clear trace")
284 self.pg0.add_stream(pkts)
285 self.pg_enable_capture(self.pg_interfaces)
287 self.pg0.get_capture(0)
288 self.logger.info(self.vapi.cli("show trace"))
289 self.socket_client_close()
290 self.assertEqual(self.portsCheck[port], 0)
293 # remove punt socket. expect ICMP - port unreachable for all packets
295 self.vapi.punt_socket_deregister(port)
296 punts = self.vapi.punt_socket_dump(is_ip6=0)
297 self.assertEqual(len(punts), 0)
298 self.pg0.add_stream(pkts)
299 self.pg_enable_capture(self.pg_interfaces)
301 # FIXME - when punt socket deregister is implemented
302 # self.pg0.get_capture(nr_packets)
304 def test_punt_socket_traffic_multi_port_multi_sockets(self):
305 """ Punt socket traffic multi ports and multi sockets"""
308 self.portsCheck[p] = 0
311 # create stream with random packets count per given ports
314 for _ in range(0, self.nr_packets):
315 # choose port from port list
316 p = random.choice(self.ports)
318 Ether(src=self.pg0.remote_mac,
319 dst=self.pg0.local_mac) /
320 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
321 UDP(sport=9876, dport=p) /
323 self.portsCheck[p] += 1
327 punts = self.vapi.punt_socket_dump(is_ip6=0)
328 self.assertEqual(len(punts), 0)
331 # configure a punt socket
334 self.socket_client_create(b"%s/socket_%d" % (
335 six.ensure_binary(self.tempdir), p))
336 self.vapi.punt_socket_register(p, b"%s/socket_%d" % (
337 six.ensure_binary(self.tempdir), p))
338 punts = self.vapi.punt_socket_dump(is_ip6=0)
339 self.assertEqual(len(punts), len(self.ports))
342 self.logger.debug("Sending %s packets to port %d",
343 str(self.portsCheck[p]), p)
346 # expect punt socket and no packets on pg0
348 self.vapi.cli("clear errors")
349 self.vapi.cli("clear trace")
350 self.pg0.add_stream(pkts)
351 self.pg_enable_capture(self.pg_interfaces)
353 self.pg0.get_capture(0)
354 self.logger.info(self.vapi.cli("show trace"))
355 self.socket_client_close()
358 self.assertEqual(self.portsCheck[p], 0)
359 self.vapi.punt_socket_deregister(p)
360 punts = self.vapi.punt_socket_dump(is_ip6=0)
361 self.assertEqual(len(punts), 0)
363 def test_punt_socket_traffic_multi_ports_single_socket(self):
364 """ Punt socket traffic multi ports and single socket"""
367 self.portsCheck[p] = 0
370 # create stream with random packets count per given ports
373 for _ in range(0, self.nr_packets):
374 # choose port from port list
375 p = random.choice(self.ports)
377 Ether(src=self.pg0.remote_mac,
378 dst=self.pg0.local_mac) /
379 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
380 UDP(sport=9876, dport=p) /
382 self.portsCheck[p] += 1
387 punts = self.vapi.punt_socket_dump(is_ip6=0)
388 self.assertEqual(len(punts), 0)
390 # configure a punt socket
392 self.socket_client_create(b"%s/socket_multi" %
393 six.ensure_binary(self.tempdir))
395 self.vapi.punt_socket_register(p,
397 six.ensure_binary(self.tempdir))
398 punts = self.vapi.punt_socket_dump(is_ip6=0)
399 self.assertEqual(len(punts), len(self.ports))
402 self.logger.debug("Sending %s packets to port %d",
403 str(self.portsCheck[p]), p)
405 # expect punt socket and no packets on pg0
407 self.vapi.cli("clear errors")
408 self.vapi.cli("clear trace")
409 self.pg0.add_stream(pkts)
410 self.pg_enable_capture(self.pg_interfaces)
412 self.pg0.get_capture(0)
413 self.logger.info(self.vapi.cli("show trace"))
414 self.socket_client_close()
417 self.assertEqual(self.portsCheck[p], 0)
418 self.vapi.punt_socket_deregister(p)
419 punts = self.vapi.punt_socket_dump(is_ip6=0)
420 self.assertEqual(len(punts), 0)
423 class TestIP6PuntSocket(TestPuntSocket):
424 """ Punt Socket for IPv6"""
428 super(TestIP6PuntSocket, cls).setUpClass()
431 def tearDownClass(cls):
432 super(TestIP6PuntSocket, cls).tearDownClass()
435 super(TestIP6PuntSocket, self).setUp()
437 for i in self.pg_interfaces:
442 super(TestIP6PuntSocket, self).tearDown()
443 for i in self.pg_interfaces:
447 def test_punt_socket_dump(self):
448 """ Punt socket registration """
450 punts = self.vapi.punt_socket_dump(is_ip6=1)
451 self.assertEqual(len(punts), 0)
454 # configure a punt socket
456 self.vapi.punt_socket_register(1111, b"%s/socket_1111" %
457 six.ensure_binary(self.tempdir),
459 self.vapi.punt_socket_register(2222, b"%s/socket_2222" %
460 six.ensure_binary(self.tempdir),
462 punts = self.vapi.punt_socket_dump(is_ip6=1)
463 self.assertEqual(len(punts), 2)
464 self.assertEqual(punts[0].punt.l4_port, 1111)
465 self.assertEqual(punts[1].punt.l4_port, 2222)
468 # deregister a punt socket
470 self.vapi.punt_socket_deregister(1111, is_ip4=0)
471 punts = self.vapi.punt_socket_dump(is_ip6=1)
472 self.assertEqual(len(punts), 1)
475 # configure a punt socket again
477 self.vapi.punt_socket_register(1111, b"%s/socket_1111" %
478 six.ensure_binary(self.tempdir),
480 punts = self.vapi.punt_socket_dump(is_ip6=1)
481 self.assertEqual(len(punts), 2)
484 # deregister all punt socket
486 self.vapi.punt_socket_deregister(1111, is_ip4=0)
487 self.vapi.punt_socket_deregister(2222, is_ip4=0)
488 self.vapi.punt_socket_deregister(3333, is_ip4=0)
489 punts = self.vapi.punt_socket_dump(is_ip6=1)
490 self.assertEqual(len(punts), 0)
492 def test_punt_socket_traffic_single_port_single_socket(self):
493 """ Punt socket traffic single port single socket"""
497 p = (Ether(src=self.pg0.remote_mac,
498 dst=self.pg0.local_mac) /
499 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
500 inet6.UDP(sport=9876, dport=port) /
503 pkts = p * self.nr_packets
504 self.portsCheck[port] = self.nr_packets
506 punts = self.vapi.punt_socket_dump(is_ip6=1)
507 self.assertEqual(len(punts), 0)
510 # expect ICMPv6 - destination unreachable for all packets
512 self.vapi.cli("clear trace")
513 self.pg0.add_stream(pkts)
514 self.pg_enable_capture(self.pg_interfaces)
516 # FIXME - when punt socket deregister is implemented
517 # rx = self.pg0.get_capture(self.nr_packets)
519 # self.assertEqual(int(p[IPv6].nh), 58) # ICMPv6
520 # self.assertEqual(int(p[ICMPv6DestUnreach].code),4) # unreachable
523 # configure a punt socket
525 self.socket_client_create(b"%s/socket_%d" % (
526 six.ensure_binary(self.tempdir), port))
527 self.vapi.punt_socket_register(port, b"%s/socket_%d" % (
528 six.ensure_binary(self.tempdir), port), is_ip4=0)
529 punts = self.vapi.punt_socket_dump(is_ip6=1)
530 self.assertEqual(len(punts), 1)
532 self.logger.debug("Sending %s packets to port %d",
533 str(self.portsCheck[port]), port)
535 # expect punt socket and no packets on pg0
537 self.vapi.cli("clear errors")
538 self.vapi.cli("clear trace")
539 self.pg0.add_stream(pkts)
540 self.pg_enable_capture(self.pg_interfaces)
542 self.pg0.get_capture(0)
543 self.logger.info(self.vapi.cli("show trace"))
544 self.socket_client_close()
545 self.assertEqual(self.portsCheck[port], 0)
548 # remove punt socket. expect ICMP - dest. unreachable for all packets
550 self.vapi.punt_socket_deregister(port, is_ip4=0)
551 punts = self.vapi.punt_socket_dump(is_ip6=1)
552 self.assertEqual(len(punts), 0)
553 self.pg0.add_stream(pkts)
554 self.pg_enable_capture(self.pg_interfaces)
556 # FIXME - when punt socket deregister is implemented
557 # self.pg0.get_capture(nr_packets)
559 def test_punt_socket_traffic_multi_port_multi_sockets(self):
560 """ Punt socket traffic multi ports and multi sockets"""
563 self.portsCheck[p] = 0
566 # create stream with random packets count per given ports
569 for _ in range(0, self.nr_packets):
570 # choose port from port list
571 p = random.choice(self.ports)
573 Ether(src=self.pg0.remote_mac,
574 dst=self.pg0.local_mac) /
575 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
576 inet6.UDP(sport=9876, dport=p) /
578 self.portsCheck[p] += 1
582 punts = self.vapi.punt_socket_dump(is_ip6=1)
583 self.assertEqual(len(punts), 0)
586 # configure a punt socket
589 self.socket_client_create(b"%s/socket_%d" % (
590 six.ensure_binary(self.tempdir), p))
591 self.vapi.punt_socket_register(p, b"%s/socket_%d" % (
592 six.ensure_binary(self.tempdir), p), is_ip4=0)
593 punts = self.vapi.punt_socket_dump(is_ip6=1)
594 self.assertEqual(len(punts), len(self.ports))
597 self.logger.debug("Sending %s packets to port %d",
598 str(self.portsCheck[p]), p)
601 # expect punt socket and no packets on pg0
603 self.vapi.cli("clear errors")
604 self.vapi.cli("clear trace")
605 self.pg0.add_stream(pkts)
606 self.pg_enable_capture(self.pg_interfaces)
608 self.pg0.get_capture(0)
609 self.logger.info(self.vapi.cli("show trace"))
610 self.socket_client_close()
613 self.assertEqual(self.portsCheck[p], 0)
614 self.vapi.punt_socket_deregister(p, is_ip4=0)
615 punts = self.vapi.punt_socket_dump(is_ip6=1)
616 self.assertEqual(len(punts), 0)
618 def test_punt_socket_traffic_multi_ports_single_socket(self):
619 """ Punt socket traffic multi ports and single socket"""
622 self.portsCheck[p] = 0
625 # create stream with random packets count per given ports
628 for _ in range(0, self.nr_packets):
629 # choose port from port list
630 p = random.choice(self.ports)
632 Ether(src=self.pg0.remote_mac,
633 dst=self.pg0.local_mac) /
634 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
635 inet6.UDP(sport=9876, dport=p) /
637 self.portsCheck[p] += 1
642 punts = self.vapi.punt_socket_dump(is_ip6=1)
643 self.assertEqual(len(punts), 0)
646 # configure a punt socket
648 self.socket_client_create(b"%s/socket_multi" %
649 six.ensure_binary(self.tempdir))
651 self.vapi.punt_socket_register(p,
653 six.ensure_binary(self.tempdir),
655 punts = self.vapi.punt_socket_dump(is_ip6=1)
656 self.assertEqual(len(punts), len(self.ports))
659 self.logger.debug("Send %s packets to port %d",
660 str(self.portsCheck[p]), p)
662 # expect punt socket and no packets on pg0
664 self.vapi.cli("clear errors")
665 self.vapi.cli("clear trace")
666 self.pg0.add_stream(pkts)
667 self.pg_enable_capture(self.pg_interfaces)
669 self.pg0.get_capture(0)
670 self.logger.info(self.vapi.cli("show trace"))
671 self.socket_client_close()
674 self.assertEqual(self.portsCheck[p], 0)
675 self.vapi.punt_socket_deregister(p, is_ip4=0)
676 punts = self.vapi.punt_socket_dump(is_ip6=1)
677 self.assertEqual(len(punts), 0)
680 class TestPunt(VppTestCase):
681 """ Punt Test Case """
685 super(TestPunt, cls).setUpClass()
688 def tearDownClass(cls):
689 super(TestPunt, cls).tearDownClass()
692 super(TestPunt, self).setUp()
694 self.create_pg_interfaces(range(4))
696 for i in self.pg_interfaces:
704 for i in self.pg_interfaces:
709 super(TestPunt, self).tearDown()
712 """ Excpetion Path testing """
715 # Using the test CLI we will hook in a exception path to
716 # send ACL deny packets out of pg0 and pg1.
717 # the ACL is src,dst = 1.1.1.1,1.1.1.2
719 ip_1_1_1_2 = VppIpRoute(self, "1.1.1.2", 32,
720 [VppRoutePath(self.pg3.remote_ip4,
721 self.pg3.sw_if_index)])
722 ip_1_1_1_2.add_vpp_config()
723 ip_1_2 = VppIpRoute(self, "1::2", 128,
724 [VppRoutePath(self.pg3.remote_ip6,
725 self.pg3.sw_if_index,
726 proto=DpoProto.DPO_PROTO_IP6)],
728 ip_1_2.add_vpp_config()
730 p4 = (Ether(src=self.pg2.remote_mac,
731 dst=self.pg2.local_mac) /
732 IP(src="1.1.1.1", dst="1.1.1.2") /
733 UDP(sport=1234, dport=1234) /
735 p6 = (Ether(src=self.pg2.remote_mac,
736 dst=self.pg2.local_mac) /
737 IPv6(src="1::1", dst="1::2") /
738 UDP(sport=1234, dport=1234) /
740 self.send_and_expect(self.pg2, p4*1, self.pg3)
741 self.send_and_expect(self.pg2, p6*1, self.pg3)
744 # apply the punting features
746 self.vapi.cli("test punt pg2")
751 self.send_and_assert_no_replies(self.pg2, p4*NUM_PKTS)
752 self.send_and_assert_no_replies(self.pg2, p6*NUM_PKTS)
756 # 1 - node error counters
757 # 2 - per-reason counters
758 # 2, 3 are the index of the assigned punt reason
760 stats = self.statistics.get_err_counter(
761 "/err/punt-dispatch/No registrations")
762 self.assertEqual(stats, 2*NUM_PKTS)
764 stats = self.statistics.get_counter("/net/punt")
765 self.assertEqual(stats[0][7]['packets'], NUM_PKTS)
766 self.assertEqual(stats[0][8]['packets'], NUM_PKTS)
769 # use the test CLI to test a client that punts exception
772 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip4)
773 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip6)
775 rx4s = self.send_and_expect(self.pg2, p4*NUM_PKTS, self.pg0)
776 rx6s = self.send_and_expect(self.pg2, p6*NUM_PKTS, self.pg0)
779 # check the packets come out IP unmodified but destined to pg0 host
782 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
783 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
784 self.assertEqual(p4[IP].dst, rx[IP].dst)
785 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
787 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
788 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
789 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
790 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
792 stats = self.statistics.get_counter("/net/punt")
793 self.assertEqual(stats[0][7]['packets'], 2*NUM_PKTS)
794 self.assertEqual(stats[0][8]['packets'], 2*NUM_PKTS)
797 # add another registration for the same reason to send packets
800 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip4)
801 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip6)
803 self.vapi.cli("clear trace")
804 self.pg2.add_stream(p4 * NUM_PKTS)
805 self.pg_enable_capture(self.pg_interfaces)
808 rxd = self.pg0.get_capture(NUM_PKTS)
810 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
811 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
812 self.assertEqual(p4[IP].dst, rx[IP].dst)
813 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
814 rxd = self.pg1.get_capture(NUM_PKTS)
816 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
817 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
818 self.assertEqual(p4[IP].dst, rx[IP].dst)
819 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
821 self.vapi.cli("clear trace")
822 self.pg2.add_stream(p6 * NUM_PKTS)
823 self.pg_enable_capture(self.pg_interfaces)
826 rxd = self.pg0.get_capture(NUM_PKTS)
828 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
829 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
830 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
831 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
832 rxd = self.pg1.get_capture(NUM_PKTS)
834 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
835 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
836 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
837 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
839 stats = self.statistics.get_counter("/net/punt")
840 self.assertEqual(stats[0][7]['packets'], 3*NUM_PKTS)
841 self.assertEqual(stats[0][8]['packets'], 3*NUM_PKTS)
843 self.logger.info(self.vapi.cli("show vlib graph punt-dispatch"))
844 self.logger.info(self.vapi.cli("show punt client"))
845 self.logger.info(self.vapi.cli("show punt reason"))
846 self.logger.info(self.vapi.cli("show punt stats"))
847 self.logger.info(self.vapi.cli("show punt db"))
850 if __name__ == '__main__':
851 unittest.main(testRunner=VppTestRunner)