blob: f33ab4ce3d5a2e649e0419eecb3d9bc687ea7843 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Pavel Kotuceke88865d2018-11-28 07:42:11 +01002import binascii
3import random
4import socket
Pavel Kotuceke88865d2018-11-28 07:42:11 +01005import os
Pavel Kotucek9edb83a2018-12-11 16:57:25 +01006import threading
7import struct
Neale Ranns50f0ac02019-05-15 02:13:37 -07008import copy
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +01009import fcntl
10import time
11
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010012from struct import unpack, unpack_from
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -080013
14try:
15 import unittest2 as unittest
16except ImportError:
17 import unittest
18
Pavel Kotuceke88865d2018-11-28 07:42:11 +010019from util import ppp, ppc
20from re import compile
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070021import scapy.compat
Pavel Kotuceke88865d2018-11-28 07:42:11 +010022from scapy.packet import Raw
23from scapy.layers.l2 import Ether
24from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -070025from scapy.layers.ipsec import ESP
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -080026import scapy.layers.inet6 as inet6
Pavel Kotuceke88865d2018-11-28 07:42:11 +010027from scapy.layers.inet6 import IPv6, ICMPv6DestUnreach
Neale Rannsb538dd82019-05-21 06:54:54 -070028from scapy.contrib.ospf import OSPF_Hdr, OSPFv3_Hello
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000029from framework import tag_fixme_vpp_workers
Pavel Kotuceke88865d2018-11-28 07:42:11 +010030from framework import VppTestCase, VppTestRunner
31
Neale Ranns76b56492018-09-28 15:16:14 +000032from vpp_ip import DpoProto
33from vpp_ip_route import VppIpRoute, VppRoutePath
Neale Rannsa9e27742020-12-23 16:22:28 +000034from vpp_ipsec import VppIpsecSA, VppIpsecTunProtect, VppIpsecInterface
Neale Ranns50f0ac02019-05-15 02:13:37 -070035from vpp_papi import VppEnum
Neale Ranns76b56492018-09-28 15:16:14 +000036
Paul Vinciguerra4271c972019-05-14 13:25:49 -040037NUM_PKTS = 67
38
Pavel Kotuceke88865d2018-11-28 07:42:11 +010039
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010040class serverSocketThread(threading.Thread):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020041 """Socket server thread"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010042
Neale Ranns50f0ac02019-05-15 02:13:37 -070043 def __init__(self, threadID, sockName):
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010044 threading.Thread.__init__(self)
45 self.threadID = threadID
46 self.sockName = sockName
47 self.sock = None
Neale Ranns50f0ac02019-05-15 02:13:37 -070048 self.rx_pkts = []
Dave Wallacec44402f2021-05-07 21:40:54 -040049 self.stop_running = False
Neale Ranns50f0ac02019-05-15 02:13:37 -070050
51 def rx_packets(self):
52 # Wait for some packets on socket
Dave Wallacec44402f2021-05-07 21:40:54 -040053 while True:
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010054 try:
55 data = self.sock.recv(65536)
Neale Ranns50f0ac02019-05-15 02:13:37 -070056
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010057 # punt socket metadata
58 # packet_desc = data[0:8]
Neale Ranns50f0ac02019-05-15 02:13:37 -070059
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010060 # Ethernet
61 self.rx_pkts.append(Ether(data[8:]))
62 except IOError as e:
63 if e.errno == 11:
Dave Wallacec44402f2021-05-07 21:40:54 -040064 # nothing to receive, stop running or sleep a little
65 if self.stop_running:
66 break
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010067 time.sleep(0.1)
68 pass
69 else:
70 raise
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010071
72 def run(self):
73 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
74 try:
75 os.unlink(self.sockName)
76 except:
77 pass
Neale Ranns50f0ac02019-05-15 02:13:37 -070078 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
79 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010080 fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010081 self.sock.bind(self.sockName)
82
Neale Ranns50f0ac02019-05-15 02:13:37 -070083 self.rx_packets()
84
85 def close(self):
Dave Wallacec44402f2021-05-07 21:40:54 -040086 self.stop_running = True
Dave Wallacef4d338f2021-05-06 15:59:59 -040087 threading.Thread.join(self)
Dave Wallacec44402f2021-05-07 21:40:54 -040088 self.sock.close()
Neale Ranns50f0ac02019-05-15 02:13:37 -070089 return self.rx_pkts
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010090
91
Pavel Kotuceke88865d2018-11-28 07:42:11 +010092class TestPuntSocket(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020093 """Punt Socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +010094
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010095 ports = [1111, 2222, 3333, 4444]
96 sock_servers = list()
Andrew Yourtchenkocb265c62019-07-25 10:03:51 +000097 # FIXME: nr_packets > 3 results in failure
98 # nr_packets = 3 makes the test unstable
99 nr_packets = 2
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100100
101 @classmethod
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800102 def setUpClass(cls):
103 super(TestPuntSocket, cls).setUpClass()
104
105 @classmethod
106 def tearDownClass(cls):
107 super(TestPuntSocket, cls).tearDownClass()
108
109 @classmethod
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100110 def setUpConstants(cls):
Ole Troana45dc072018-12-21 16:04:22 +0100111 cls.extra_vpp_punt_config = [
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200112 "punt",
113 "{",
114 "socket",
115 cls.tempdir + "/socket_punt",
116 "}",
117 ]
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100118 super(TestPuntSocket, cls).setUpConstants()
119
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100120 def setUp(self):
121 super(TestPuntSocket, self).setUp()
122 random.seed()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100123
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100124 self.create_pg_interfaces(range(2))
125 for i in self.pg_interfaces:
126 i.admin_up()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100127
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100128 def tearDown(self):
129 del self.sock_servers[:]
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800130 super(TestPuntSocket, self).tearDown()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100131
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100132 def socket_client_create(self, sock_name, id=None):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700133 thread = serverSocketThread(id, sock_name)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100134 self.sock_servers.append(thread)
135 thread.start()
Neale Ranns50f0ac02019-05-15 02:13:37 -0700136 return thread
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100137
138 def socket_client_close(self):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700139 rx_pkts = []
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100140 for thread in self.sock_servers:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700141 rx_pkts += thread.close()
142 return rx_pkts
143
144 def verify_port(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200145 self.assertEqual(vpr.punt.type, pr["type"])
146 self.assertEqual(vpr.punt.punt.l4.port, pr["punt"]["l4"]["port"])
147 self.assertEqual(vpr.punt.punt.l4.protocol, pr["punt"]["l4"]["protocol"])
148 self.assertEqual(vpr.punt.punt.l4.af, pr["punt"]["l4"]["af"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700149
150 def verify_exception(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200151 self.assertEqual(vpr.punt.type, pr["type"])
152 self.assertEqual(vpr.punt.punt.exception.id, pr["punt"]["exception"]["id"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700153
Neale Rannsb538dd82019-05-21 06:54:54 -0700154 def verify_ip_proto(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200155 self.assertEqual(vpr.punt.type, pr["type"])
156 self.assertEqual(vpr.punt.punt.ip_proto.af, pr["punt"]["ip_proto"]["af"])
157 self.assertEqual(
158 vpr.punt.punt.ip_proto.protocol, pr["punt"]["ip_proto"]["protocol"]
159 )
Neale Rannsb538dd82019-05-21 06:54:54 -0700160
Neale Ranns50f0ac02019-05-15 02:13:37 -0700161 def verify_udp_pkts(self, rxs, n_rx, port):
162 n_match = 0
163 for rx in rxs:
164 self.assertTrue(rx.haslayer(UDP))
165 if rx[UDP].dport == port:
166 n_match += 1
167 self.assertEqual(n_match, n_rx)
168
169
170def set_port(pr, port):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171 pr["punt"]["l4"]["port"] = port
Neale Ranns50f0ac02019-05-15 02:13:37 -0700172 return pr
173
174
175def set_reason(pr, reason):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200176 pr["punt"]["exception"]["id"] = reason
Neale Ranns50f0ac02019-05-15 02:13:37 -0700177 return pr
178
179
180def mk_vpp_cfg4():
181 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
182 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
183 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200184 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip4, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700185 return punt_l4
186
187
188def mk_vpp_cfg6():
189 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
190 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
191 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200192 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip6, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700193 return punt_l4
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100194
195
196class TestIP4PuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200197 """Punt Socket for IPv4 UDP"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100198
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800199 @classmethod
200 def setUpClass(cls):
201 super(TestIP4PuntSocket, cls).setUpClass()
202
203 @classmethod
204 def tearDownClass(cls):
205 super(TestIP4PuntSocket, cls).tearDownClass()
206
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100207 def setUp(self):
208 super(TestIP4PuntSocket, self).setUp()
209
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100210 for i in self.pg_interfaces:
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100211 i.config_ip4()
212 i.resolve_arp()
213
214 def tearDown(self):
215 super(TestIP4PuntSocket, self).tearDown()
216 for i in self.pg_interfaces:
217 i.unconfig_ip4()
218 i.admin_down()
219
220 def test_punt_socket_dump(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200221 """Punt socket registration/deregistration"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100222
Neale Ranns50f0ac02019-05-15 02:13:37 -0700223 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
224 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
225 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
226
227 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100228 self.assertEqual(len(punts), 0)
229
230 #
231 # configure a punt socket
232 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700233 punt_l4 = mk_vpp_cfg4()
234
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200235 self.vapi.punt_socket_register(
236 set_port(punt_l4, 1111), "%s/socket_punt_1111" % self.tempdir
237 )
238 self.vapi.punt_socket_register(
239 set_port(punt_l4, 2222), "%s/socket_punt_2222" % self.tempdir
240 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700241 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100242 self.assertEqual(len(punts), 2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700243 self.verify_port(set_port(punt_l4, 1111), punts[0])
244 self.verify_port(set_port(punt_l4, 2222), punts[1])
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100245
246 #
247 # deregister a punt socket
248 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700249 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
250 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100251 self.assertEqual(len(punts), 1)
252
253 #
254 # configure a punt socket again
255 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200256 self.vapi.punt_socket_register(
257 set_port(punt_l4, 1111), "%s/socket_punt_1111" % self.tempdir
258 )
259 self.vapi.punt_socket_register(
260 set_port(punt_l4, 3333), "%s/socket_punt_3333" % self.tempdir
261 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700262 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100263 self.assertEqual(len(punts), 3)
264
Neale Ranns50f0ac02019-05-15 02:13:37 -0700265 self.logger.info(self.vapi.cli("sh punt sock reg"))
266
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100267 #
268 # deregister all punt socket
269 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700270 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
271 self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
272 self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
273 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100274 self.assertEqual(len(punts), 0)
275
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100276 def test_punt_socket_traffic_single_port_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200277 """Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100278
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100279 port = self.ports[0]
Neale Ranns50f0ac02019-05-15 02:13:37 -0700280 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
281 punt_l4 = set_port(mk_vpp_cfg4(), port)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100282
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200283 p = (
284 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
285 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
286 / UDP(sport=9876, dport=port)
287 / Raw(b"\xa5" * 100)
288 )
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100289
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100290 pkts = p * self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100291
Neale Ranns50f0ac02019-05-15 02:13:37 -0700292 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100293 self.assertEqual(len(punts), 0)
294
295 #
296 # expect ICMP - port unreachable for all packets
297 #
Neale Ranns5c6dd172022-02-17 09:08:47 +0000298 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700299
300 for p in rx:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200301 self.assertEqual(int(p[IP].proto), 1) # ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -0700302 self.assertEqual(int(p[ICMP].code), 3) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100303
304 #
305 # configure a punt socket
306 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200307 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200308 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700309 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100310 self.assertEqual(len(punts), 1)
311
312 #
313 # expect punt socket and no packets on pg0
314 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700315 self.send_and_assert_no_replies(self.pg0, pkts)
316 rx = self.socket_client_close()
317 self.verify_udp_pkts(rx, len(pkts), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100318
319 #
320 # remove punt socket. expect ICMP - port unreachable for all packets
321 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700322 self.vapi.punt_socket_deregister(punt_l4)
323 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100324 self.assertEqual(len(punts), 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100325
Neale Ranns5c6dd172022-02-17 09:08:47 +0000326 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700327 for p in rx:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200328 self.assertEqual(int(p[IP].proto), 1) # ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -0700329 self.assertEqual(int(p[ICMP].code), 3) # unreachable
330
331 def test_punt_socket_traffic_multi_ports_multi_sockets(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200332 """Punt socket traffic multi ports and multi sockets"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100333
Neale Ranns50f0ac02019-05-15 02:13:37 -0700334 punt_l4 = mk_vpp_cfg4()
335
336 # configuration for each UDP port
337 cfgs = dict()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100338
339 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700340 # create stream of packets for each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100341 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700342 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100343 # choose port from port list
Neale Ranns50f0ac02019-05-15 02:13:37 -0700344 cfgs[port] = {}
345
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200346 pkt = (
347 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
348 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
349 / UDP(sport=9876, dport=port)
350 / Raw(b"\xa5" * 100)
351 )
352 cfgs[port]["pkts"] = pkt * self.nr_packets
353 cfgs[port]["port"] = port
354 cfgs[port]["vpp"] = copy.deepcopy(set_port(punt_l4, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700355
356 # configure punt sockets
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200357 cfgs[port]["sock"] = self.socket_client_create(
358 "%s/socket_%d" % (self.tempdir, port)
359 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700360 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200361 cfgs[port]["vpp"], "%s/socket_%d" % (self.tempdir, port)
362 )
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100363
364 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700365 # send the packets that get punted
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100366 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700367 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200368 self.send_and_assert_no_replies(self.pg0, cfg["pkts"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100369
370 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700371 # test that we got the excepted packets on the expected socket
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100372 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700373 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200374 rx = cfg["sock"].close()
375 self.verify_udp_pkts(rx, len(cfg["pkts"]), cfg["port"])
376 self.vapi.punt_socket_deregister(cfg["vpp"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100377
378 def test_punt_socket_traffic_multi_ports_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200379 """Punt socket traffic multi ports and single socket"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100380
Neale Ranns50f0ac02019-05-15 02:13:37 -0700381 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
382 punt_l4 = mk_vpp_cfg4()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100383
384 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700385 # create stream of packets with each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100386 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700387 pkts = []
388 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100389 # choose port from port list
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200390 pkt = (
391 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
392 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
393 / UDP(sport=9876, dport=port)
394 / Raw(b"\xa5" * 100)
395 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700396 pkts += pkt * self.nr_packets
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100397
398 #
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100399 # configure a punt socket
400 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200401 self.socket_client_create("%s/socket_multi" % self.tempdir)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100402 for p in self.ports:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200403 self.vapi.punt_socket_register(
404 set_port(punt_l4, p), "%s/socket_multi" % self.tempdir
405 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700406 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100407 self.assertEqual(len(punts), len(self.ports))
408
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100409 #
410 # expect punt socket and no packets on pg0
411 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700412 self.send_and_assert_no_replies(self.pg0, pkts)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100413 self.logger.info(self.vapi.cli("show trace"))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700414 rx = self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100415
416 for p in self.ports:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700417 self.verify_udp_pkts(rx, self.nr_packets, p)
418 self.vapi.punt_socket_deregister(set_port(punt_l4, p))
419 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100420 self.assertEqual(len(punts), 0)
421
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100422
423class TestIP6PuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200424 """Punt Socket for IPv6 UDP"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100425
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800426 @classmethod
427 def setUpClass(cls):
428 super(TestIP6PuntSocket, cls).setUpClass()
429
430 @classmethod
431 def tearDownClass(cls):
432 super(TestIP6PuntSocket, cls).tearDownClass()
433
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100434 def setUp(self):
435 super(TestIP6PuntSocket, self).setUp()
436
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100437 for i in self.pg_interfaces:
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100438 i.config_ip6()
439 i.resolve_ndp()
440
441 def tearDown(self):
442 super(TestIP6PuntSocket, self).tearDown()
443 for i in self.pg_interfaces:
444 i.unconfig_ip6()
445 i.admin_down()
446
447 def test_punt_socket_dump(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200448 """Punt socket registration"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100449
Neale Ranns50f0ac02019-05-15 02:13:37 -0700450 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
451 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
452 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
453 #
454 # configure a punt socket
455 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200456 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip6, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700457
458 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100459 self.assertEqual(len(punts), 0)
460
461 #
462 # configure a punt socket
463 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200464 self.vapi.punt_socket_register(
465 set_port(punt_l4, 1111), "%s/socket_1111" % self.tempdir
466 )
467 self.vapi.punt_socket_register(
468 set_port(punt_l4, 2222), "%s/socket_2222" % self.tempdir
469 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700470 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100471 self.assertEqual(len(punts), 2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700472 self.verify_port(set_port(punt_l4, 1111), punts[0])
473 self.verify_port(set_port(punt_l4, 2222), punts[1])
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100474
475 #
476 # deregister a punt socket
477 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700478 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
479 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100480 self.assertEqual(len(punts), 1)
481
482 #
483 # configure a punt socket again
484 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200485 self.vapi.punt_socket_register(
486 set_port(punt_l4, 1111), "%s/socket_1111" % self.tempdir
487 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700488 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100489 self.assertEqual(len(punts), 2)
490
491 #
492 # deregister all punt socket
493 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700494 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
495 self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
496 self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
497 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100498 self.assertEqual(len(punts), 0)
499
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100500 def test_punt_socket_traffic_single_port_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200501 """Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100502
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100503 port = self.ports[0]
Neale Ranns50f0ac02019-05-15 02:13:37 -0700504 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
505 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
506 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
507 punt_l4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200508 "type": pt_l4,
509 "punt": {
510 "l4": {
511 "af": af_ip6,
512 "protocol": udp_proto,
513 "port": port,
Neale Ranns50f0ac02019-05-15 02:13:37 -0700514 }
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200515 },
Neale Ranns50f0ac02019-05-15 02:13:37 -0700516 }
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100517
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200518 p = (
519 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
520 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
521 / inet6.UDP(sport=9876, dport=port)
522 / Raw(b"\xa5" * 100)
523 )
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100524
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100525 pkts = p * self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100526
Neale Ranns50f0ac02019-05-15 02:13:37 -0700527 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100528 self.assertEqual(len(punts), 0)
529
530 #
531 # expect ICMPv6 - destination unreachable for all packets
532 #
533 self.vapi.cli("clear trace")
534 self.pg0.add_stream(pkts)
535 self.pg_enable_capture(self.pg_interfaces)
536 self.pg_start()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100537 # FIXME - when punt socket deregister is implemented
538 # rx = self.pg0.get_capture(self.nr_packets)
539 # for p in rx:
540 # self.assertEqual(int(p[IPv6].nh), 58) # ICMPv6
541 # self.assertEqual(int(p[ICMPv6DestUnreach].code),4) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100542
543 #
544 # configure a punt socket
545 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200546 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200547 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700548 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100549 self.assertEqual(len(punts), 1)
550
551 #
552 # expect punt socket and no packets on pg0
553 #
554 self.vapi.cli("clear errors")
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100555 self.vapi.cli("clear trace")
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100556 self.pg0.add_stream(pkts)
557 self.pg_enable_capture(self.pg_interfaces)
558 self.pg_start()
559 self.pg0.get_capture(0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100560 self.logger.info(self.vapi.cli("show trace"))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700561 rx = self.socket_client_close()
562 self.verify_udp_pkts(rx, len(pkts), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100563
564 #
565 # remove punt socket. expect ICMP - dest. unreachable for all packets
566 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700567 self.vapi.punt_socket_deregister(punt_l4)
568 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100569 self.assertEqual(len(punts), 0)
570 self.pg0.add_stream(pkts)
571 self.pg_enable_capture(self.pg_interfaces)
572 self.pg_start()
573 # FIXME - when punt socket deregister is implemented
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100574 # self.pg0.get_capture(nr_packets)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100575
Neale Ranns50f0ac02019-05-15 02:13:37 -0700576 def test_punt_socket_traffic_multi_ports_multi_sockets(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200577 """Punt socket traffic multi ports and multi sockets"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100578
Neale Ranns50f0ac02019-05-15 02:13:37 -0700579 punt_l4 = mk_vpp_cfg6()
580
581 # configuration for each UDP port
582 cfgs = dict()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100583
584 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700585 # create stream of packets for each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100586 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700587 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100588 # choose port from port list
Neale Ranns50f0ac02019-05-15 02:13:37 -0700589 cfgs[port] = {}
590
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200591 pkt = (
592 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
593 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
594 / UDP(sport=9876, dport=port)
595 / Raw(b"\xa5" * 100)
596 )
597 cfgs[port]["pkts"] = pkt * self.nr_packets
598 cfgs[port]["port"] = port
599 cfgs[port]["vpp"] = copy.deepcopy(set_port(punt_l4, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700600
601 # configure punt sockets
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200602 cfgs[port]["sock"] = self.socket_client_create(
603 "%s/socket_%d" % (self.tempdir, port)
604 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700605 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200606 cfgs[port]["vpp"], "%s/socket_%d" % (self.tempdir, port)
607 )
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100608
609 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700610 # send the packets that get punted
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100611 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700612 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200613 self.send_and_assert_no_replies(self.pg0, cfg["pkts"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100614
615 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700616 # test that we got the excepted packets on the expected socket
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100617 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700618 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200619 rx = cfg["sock"].close()
620 self.verify_udp_pkts(rx, len(cfg["pkts"]), cfg["port"])
621 self.vapi.punt_socket_deregister(cfg["vpp"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100622
623 def test_punt_socket_traffic_multi_ports_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200624 """Punt socket traffic multi ports and single socket"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100625
Neale Ranns50f0ac02019-05-15 02:13:37 -0700626 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
627 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
628 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
629 punt_l4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200630 "type": pt_l4,
631 "punt": {
632 "l4": {
633 "af": af_ip6,
634 "protocol": udp_proto,
Neale Ranns50f0ac02019-05-15 02:13:37 -0700635 }
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200636 },
Neale Ranns50f0ac02019-05-15 02:13:37 -0700637 }
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100638
639 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700640 # create stream of packets with each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100641 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700642 pkts = []
643 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100644 # choose port from port list
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200645 pkt = (
646 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
647 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
648 / UDP(sport=9876, dport=port)
649 / Raw(b"\xa5" * 100)
650 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700651 pkts += pkt * self.nr_packets
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100652
653 #
654 # no punt socket
655 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700656 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100657 self.assertEqual(len(punts), 0)
658
659 #
660 # configure a punt socket
661 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200662 self.socket_client_create("%s/socket_multi" % self.tempdir)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100663 for p in self.ports:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200664 self.vapi.punt_socket_register(
665 set_port(punt_l4, p), "%s/socket_multi" % self.tempdir
666 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700667 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100668 self.assertEqual(len(punts), len(self.ports))
669
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100670 #
671 # expect punt socket and no packets on pg0
672 #
673 self.vapi.cli("clear errors")
674 self.vapi.cli("clear trace")
675 self.pg0.add_stream(pkts)
676 self.pg_enable_capture(self.pg_interfaces)
677 self.pg_start()
Andrew Yourtchenkocb265c62019-07-25 10:03:51 +0000678 # give a chance to punt socket to collect all packets
679 self.sleep(1)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100680 self.pg0.get_capture(0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700681 rx = self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100682
683 for p in self.ports:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700684 self.verify_udp_pkts(rx, self.nr_packets, p)
685 self.vapi.punt_socket_deregister(set_port(punt_l4, p))
686 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100687 self.assertEqual(len(punts), 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100688
Neale Ranns76b56492018-09-28 15:16:14 +0000689
Neale Ranns50f0ac02019-05-15 02:13:37 -0700690class TestExceptionPuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200691 """Punt Socket for Exceptions"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700692
693 @classmethod
694 def setUpClass(cls):
695 super(TestExceptionPuntSocket, cls).setUpClass()
696
697 @classmethod
698 def tearDownClass(cls):
699 super(TestExceptionPuntSocket, cls).tearDownClass()
700
701 def setUp(self):
702 super(TestExceptionPuntSocket, self).setUp()
703
Neale Ranns12989b52019-09-26 16:20:19 +0000704 self.create_pg_interfaces(range(2))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700705 for i in self.pg_interfaces:
706 i.config_ip4()
707 i.resolve_arp()
708
709 def tearDown(self):
710 super(TestExceptionPuntSocket, self).tearDown()
711 for i in self.pg_interfaces:
712 i.unconfig_ip4()
713 i.admin_down()
714
715 def test_registration(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200716 """Punt socket registration/deregistration"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700717
718 pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION
719
720 punts = self.vapi.punt_socket_dump(type=pt_ex)
721 self.assertEqual(len(punts), 0)
722
723 #
724 # configure a punt socket
725 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200726 punt_ex = {"type": pt_ex, "punt": {"exception": {}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700727
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200728 self.vapi.punt_socket_register(
729 set_reason(punt_ex, 1), "%s/socket_punt_1" % self.tempdir
730 )
731 self.vapi.punt_socket_register(
732 set_reason(punt_ex, 2), "%s/socket_punt_2" % self.tempdir
733 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700734 punts = self.vapi.punt_socket_dump(type=pt_ex)
735 self.assertEqual(len(punts), 2)
736 self.verify_exception(set_reason(punt_ex, 1), punts[0])
737 self.verify_exception(set_reason(punt_ex, 2), punts[1])
738
739 #
740 # deregister a punt socket
741 #
742 self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
743 punts = self.vapi.punt_socket_dump(type=pt_ex)
744 self.assertEqual(len(punts), 1)
745
746 #
747 # configure a punt socket again
748 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200749 self.vapi.punt_socket_register(
750 set_reason(punt_ex, 1), "%s/socket_punt_1" % self.tempdir
751 )
752 self.vapi.punt_socket_register(
753 set_reason(punt_ex, 3), "%s/socket_punt_3" % self.tempdir
754 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700755 punts = self.vapi.punt_socket_dump(type=pt_ex)
756 self.assertEqual(len(punts), 3)
757
758 self.logger.info(self.vapi.cli("sh punt sock reg exception"))
759
760 #
761 # deregister all punt socket
762 #
763 self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
764 self.vapi.punt_socket_deregister(set_reason(punt_ex, 2))
765 self.vapi.punt_socket_deregister(set_reason(punt_ex, 3))
766 punts = self.vapi.punt_socket_dump(type=pt_ex)
767 self.assertEqual(len(punts), 0)
768
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700769 def verify_esp_pkts(self, rxs, n_sent, spi, has_udp):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700770 self.assertEqual(len(rxs), n_sent)
771 for rx in rxs:
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700772 self.assertTrue(rx.haslayer(IP))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700773 self.assertTrue(rx.haslayer(ESP))
774 self.assertEqual(rx[ESP].spi, spi)
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700775 if has_udp:
776 self.assertTrue(rx.haslayer(UDP))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700777
778 def test_traffic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200779 """Punt socket traffic"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700780
781 port = self.ports[0]
782 pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200783 punt_ex = {"type": pt_ex, "punt": {"exception": {}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700784
785 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700786 # we're dealing with IPSec tunnels punting for no-such-tunnel
Filip Tehlar4362baa2020-04-02 13:13:39 +0000787 # (SPI=0 goes to ikev2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700788 #
789 cfgs = dict()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200790 cfgs["ipsec4-no-such-tunnel"] = {"spi": 99, "udp": False, "itf": self.pg0}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700791
792 #
793 # find the VPP ID for these punt exception reasin
794 #
795 rs = self.vapi.punt_reason_dump()
796 for key in cfgs:
797 for r in rs:
Jakub Grajciar2dbee932020-02-07 11:30:26 +0100798 print(r.reason.name)
799 print(key)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700800 if r.reason.name == key:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200801 cfgs[key]["id"] = r.reason.id
802 cfgs[key]["vpp"] = copy.deepcopy(
803 set_reason(punt_ex, cfgs[key]["id"])
804 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700805 break
806
807 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700808 # configure punt sockets
Neale Ranns50f0ac02019-05-15 02:13:37 -0700809 #
810 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200811 cfg["sock"] = self.socket_client_create(
812 "%s/socket_%d" % (self.tempdir, cfg["id"])
813 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700814 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200815 cfg["vpp"], "%s/socket_%d" % (self.tempdir, cfg["id"])
816 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700817
818 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700819 # create packet streams for 'no-such-tunnel' exception
820 #
821 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200822 pkt = Ether(src=cfg["itf"].remote_mac, dst=cfg["itf"].local_mac) / IP(
823 src=cfg["itf"].remote_ip4, dst=cfg["itf"].local_ip4
824 )
825 if cfg["udp"]:
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700826 pkt = pkt / UDP(sport=666, dport=4500)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200827 pkt = pkt / ESP(spi=cfg["spi"], seq=3) / Raw(b"\xa5" * 100)
828 cfg["pkts"] = [pkt]
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700829
830 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700831 # send packets for each SPI we expect to be punted
832 #
833 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200834 self.send_and_assert_no_replies(cfg["itf"], cfg["pkts"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700835
836 #
837 # verify the punted packets arrived on the associated socket
838 #
839 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200840 rx = cfg["sock"].close()
841 self.verify_esp_pkts(rx, len(cfg["pkts"]), cfg["spi"], cfg["udp"])
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700842
843 #
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000844 # add some tunnels, make sure it still punts
845 #
Neale Rannsa9e27742020-12-23 16:22:28 +0000846 tun = VppIpsecInterface(self).add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200847 sa_in = VppIpsecSA(
848 self,
849 11,
850 11,
851 (VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96),
852 b"0123456701234567",
853 (VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128),
854 b"0123456701234567",
855 50,
856 self.pg0.local_ip4,
857 self.pg0.remote_ip4,
858 ).add_vpp_config()
859 sa_out = VppIpsecSA(
860 self,
861 22,
862 22,
863 (VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96),
864 b"0123456701234567",
865 (VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128),
866 b"0123456701234567",
867 50,
868 self.pg0.local_ip4,
869 self.pg0.remote_ip4,
870 ).add_vpp_config()
871 protect = VppIpsecTunProtect(self, tun, sa_out, [sa_in]).add_vpp_config()
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000872
873 #
874 # send packets for each SPI we expect to be punted
875 #
876 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200877 self.send_and_assert_no_replies(cfg["itf"], cfg["pkts"])
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000878
879 #
880 # verify the punted packets arrived on the associated socket
881 #
882 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200883 rx = cfg["sock"].close()
884 self.verify_esp_pkts(rx, len(cfg["pkts"]), cfg["spi"], cfg["udp"])
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000885 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700886 # socket deregister
887 #
888 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200889 self.vapi.punt_socket_deregister(cfg["vpp"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700890
891
Neale Rannsb538dd82019-05-21 06:54:54 -0700892class TestIpProtoPuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200893 """Punt Socket for IP packets"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700894
895 @classmethod
896 def setUpClass(cls):
897 super(TestIpProtoPuntSocket, cls).setUpClass()
898
899 @classmethod
900 def tearDownClass(cls):
901 super(TestIpProtoPuntSocket, cls).tearDownClass()
902
903 def setUp(self):
904 super(TestIpProtoPuntSocket, self).setUp()
905
906 for i in self.pg_interfaces:
907 i.config_ip4()
908 i.resolve_arp()
909
910 def tearDown(self):
911 super(TestIpProtoPuntSocket, self).tearDown()
912 for i in self.pg_interfaces:
913 i.unconfig_ip4()
914 i.admin_down()
915
916 def test_registration(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200917 """Punt socket registration/deregistration"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700918
919 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
920 pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
921 proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF
922 proto_eigrp = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_EIGRP
923
924 punts = self.vapi.punt_socket_dump(type=pt_ip)
925 self.assertEqual(len(punts), 0)
926
927 #
928 # configure a punt socket
929 #
930 punt_ospf = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200931 "type": pt_ip,
932 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_ospf}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700933 }
934 punt_eigrp = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200935 "type": pt_ip,
936 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_eigrp}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700937 }
938
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200939 self.vapi.punt_socket_register(punt_ospf, "%s/socket_punt_1" % self.tempdir)
940 self.vapi.punt_socket_register(punt_eigrp, "%s/socket_punt_2" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -0700941 self.logger.info(self.vapi.cli("sh punt sock reg ip"))
942 punts = self.vapi.punt_socket_dump(type=pt_ip)
943 self.assertEqual(len(punts), 2)
944 self.verify_ip_proto(punt_ospf, punts[0])
945 self.verify_ip_proto(punt_eigrp, punts[1])
946
947 #
948 # deregister a punt socket
949 #
950 self.vapi.punt_socket_deregister(punt_ospf)
951 punts = self.vapi.punt_socket_dump(type=pt_ip)
952 self.assertEqual(len(punts), 1)
953
954 #
955 # configure a punt socket again
956 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200957 self.vapi.punt_socket_register(punt_ospf, "%s/socket_punt_3" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -0700958 punts = self.vapi.punt_socket_dump(type=pt_ip)
959 self.assertEqual(len(punts), 2)
960
961 self.logger.info(self.vapi.cli("sh punt sock reg exception"))
962
963 #
964 # deregister all punt socket
965 #
966 self.vapi.punt_socket_deregister(punt_eigrp)
967 self.vapi.punt_socket_deregister(punt_ospf)
968 punts = self.vapi.punt_socket_dump(type=pt_ip)
969 self.assertEqual(len(punts), 0)
970
971 def verify_ospf_pkts(self, rxs, n_sent):
972 self.assertEqual(len(rxs), n_sent)
973 for rx in rxs:
974 self.assertTrue(rx.haslayer(OSPF_Hdr))
975
976 def test_traffic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200977 """Punt socket traffic"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700978
979 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
980 pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
981 proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF
982
983 #
984 # configure a punt socket to capture OSPF packets
985 #
986 punt_ospf = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200987 "type": pt_ip,
988 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_ospf}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700989 }
990
991 #
992 # create packet streams and configure a punt sockets
993 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200994 pkt = (
995 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
996 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
997 / OSPF_Hdr()
998 / OSPFv3_Hello()
999 )
Neale Rannsb538dd82019-05-21 06:54:54 -07001000 pkts = pkt * 7
1001
Ole Troan9cd8f332019-10-18 15:57:56 +02001002 sock = self.socket_client_create("%s/socket_1" % self.tempdir)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001003 self.vapi.punt_socket_register(punt_ospf, "%s/socket_1" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -07001004
1005 #
1006 # send packets for each SPI we expect to be punted
1007 #
1008 self.send_and_assert_no_replies(self.pg0, pkts)
1009
1010 #
1011 # verify the punted packets arrived on the associated socket
1012 #
1013 rx = sock.close()
1014 self.verify_ospf_pkts(rx, len(pkts))
1015 self.vapi.punt_socket_deregister(punt_ospf)
1016
1017
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001018@tag_fixme_vpp_workers
Neale Ranns76b56492018-09-28 15:16:14 +00001019class TestPunt(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001020 """Exception Punt Test Case"""
Neale Ranns76b56492018-09-28 15:16:14 +00001021
1022 @classmethod
1023 def setUpClass(cls):
1024 super(TestPunt, cls).setUpClass()
1025
1026 @classmethod
1027 def tearDownClass(cls):
1028 super(TestPunt, cls).tearDownClass()
1029
1030 def setUp(self):
1031 super(TestPunt, self).setUp()
1032
1033 self.create_pg_interfaces(range(4))
1034
1035 for i in self.pg_interfaces:
1036 i.admin_up()
1037 i.config_ip4()
1038 i.resolve_arp()
1039 i.config_ip6()
1040 i.resolve_ndp()
1041
1042 def tearDown(self):
1043 for i in self.pg_interfaces:
1044 i.unconfig_ip4()
1045 i.unconfig_ip6()
Neale Ranns76b56492018-09-28 15:16:14 +00001046 i.admin_down()
1047 super(TestPunt, self).tearDown()
1048
1049 def test_punt(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001050 """Exception Path testing"""
Neale Ranns76b56492018-09-28 15:16:14 +00001051
1052 #
Neale Ranns719beb72019-07-10 07:10:25 +00001053 # dump the punt registered reasons
1054 # search for a few we know should be there
1055 #
1056 rs = self.vapi.punt_reason_dump()
1057
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001058 reasons = [
1059 "ipsec6-no-such-tunnel",
1060 "ipsec4-no-such-tunnel",
1061 "ipsec4-spi-o-udp-0",
1062 ]
Neale Ranns719beb72019-07-10 07:10:25 +00001063
1064 for reason in reasons:
1065 found = False
1066 for r in rs:
1067 if r.reason.name == reason:
1068 found = True
1069 break
1070 self.assertTrue(found)
1071
1072 #
Neale Ranns76b56492018-09-28 15:16:14 +00001073 # Using the test CLI we will hook in a exception path to
1074 # send ACL deny packets out of pg0 and pg1.
1075 # the ACL is src,dst = 1.1.1.1,1.1.1.2
1076 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001077 ip_1_1_1_2 = VppIpRoute(
1078 self,
1079 "1.1.1.2",
1080 32,
1081 [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)],
1082 )
Neale Ranns76b56492018-09-28 15:16:14 +00001083 ip_1_1_1_2.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001084 ip_1_2 = VppIpRoute(
1085 self,
1086 "1::2",
1087 128,
1088 [
1089 VppRoutePath(
1090 self.pg3.remote_ip6,
1091 self.pg3.sw_if_index,
1092 proto=DpoProto.DPO_PROTO_IP6,
1093 )
1094 ],
1095 )
Neale Ranns76b56492018-09-28 15:16:14 +00001096 ip_1_2.add_vpp_config()
1097
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001098 p4 = (
1099 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
1100 / IP(src="1.1.1.1", dst="1.1.1.2")
1101 / UDP(sport=1234, dport=1234)
1102 / Raw(b"\xa5" * 100)
1103 )
1104 p6 = (
1105 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
1106 / IPv6(src="1::1", dst="1::2")
1107 / UDP(sport=1234, dport=1234)
1108 / Raw(b"\xa5" * 100)
1109 )
1110 self.send_and_expect(self.pg2, p4 * 1, self.pg3)
1111 self.send_and_expect(self.pg2, p6 * 1, self.pg3)
Neale Ranns76b56492018-09-28 15:16:14 +00001112
1113 #
1114 # apply the punting features
1115 #
1116 self.vapi.cli("test punt pg2")
1117
1118 #
Neale Ranns719beb72019-07-10 07:10:25 +00001119 # dump the punt reasons to learn the IDs assigned
1120 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001121 rs = self.vapi.punt_reason_dump(reason={"name": "reason-v4"})
Neale Ranns719beb72019-07-10 07:10:25 +00001122 r4 = rs[0].reason.id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001123 rs = self.vapi.punt_reason_dump(reason={"name": "reason-v6"})
Neale Ranns719beb72019-07-10 07:10:25 +00001124 r6 = rs[0].reason.id
1125
1126 #
Neale Ranns76b56492018-09-28 15:16:14 +00001127 # pkts now dropped
1128 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001129 self.send_and_assert_no_replies(self.pg2, p4 * NUM_PKTS)
1130 self.send_and_assert_no_replies(self.pg2, p6 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001131
1132 #
1133 # Check state:
1134 # 1 - node error counters
1135 # 2 - per-reason counters
1136 # 2, 3 are the index of the assigned punt reason
1137 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001138 stats = self.statistics.get_err_counter("/err/punt-dispatch/No registrations")
1139 self.assertEqual(stats, 2 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001140
1141 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001142 self.assertEqual(stats[0][r4]["packets"], NUM_PKTS)
1143 self.assertEqual(stats[0][r6]["packets"], NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001144
1145 #
1146 # use the test CLI to test a client that punts exception
1147 # packets out of pg0
1148 #
1149 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip4)
1150 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip6)
1151
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001152 rx4s = self.send_and_expect(self.pg2, p4 * NUM_PKTS, self.pg0)
1153 rx6s = self.send_and_expect(self.pg2, p6 * NUM_PKTS, self.pg0)
Neale Ranns76b56492018-09-28 15:16:14 +00001154
1155 #
1156 # check the packets come out IP unmodified but destined to pg0 host
1157 #
1158 for rx in rx4s:
1159 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1160 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1161 self.assertEqual(p4[IP].dst, rx[IP].dst)
1162 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
1163 for rx in rx6s:
1164 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1165 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1166 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1167 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
1168
1169 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001170 self.assertEqual(stats[0][r4]["packets"], 2 * NUM_PKTS)
1171 self.assertEqual(stats[0][r6]["packets"], 2 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001172
1173 #
1174 # add another registration for the same reason to send packets
1175 # out of pg1
1176 #
1177 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip4)
1178 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip6)
1179
1180 self.vapi.cli("clear trace")
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001181 self.pg2.add_stream(p4 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001182 self.pg_enable_capture(self.pg_interfaces)
1183 self.pg_start()
1184
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001185 rxd = self.pg0.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001186 for rx in rxd:
1187 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1188 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1189 self.assertEqual(p4[IP].dst, rx[IP].dst)
1190 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001191 rxd = self.pg1.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001192 for rx in rxd:
1193 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
1194 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
1195 self.assertEqual(p4[IP].dst, rx[IP].dst)
1196 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
1197
1198 self.vapi.cli("clear trace")
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001199 self.pg2.add_stream(p6 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001200 self.pg_enable_capture(self.pg_interfaces)
1201 self.pg_start()
1202
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001203 rxd = self.pg0.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001204 for rx in rxd:
1205 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1206 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1207 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1208 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001209 rxd = self.pg1.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001210 for rx in rxd:
1211 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
1212 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
1213 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1214 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
1215
1216 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001217 self.assertEqual(stats[0][r4]["packets"], 3 * NUM_PKTS)
1218 self.assertEqual(stats[0][r6]["packets"], 3 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001219
1220 self.logger.info(self.vapi.cli("show vlib graph punt-dispatch"))
1221 self.logger.info(self.vapi.cli("show punt client"))
1222 self.logger.info(self.vapi.cli("show punt reason"))
1223 self.logger.info(self.vapi.cli("show punt stats"))
1224 self.logger.info(self.vapi.cli("show punt db"))
1225
Neale Ranns76b56492018-09-28 15:16:14 +00001226
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001227if __name__ == "__main__":
Pavel Kotuceke88865d2018-11-28 07:42:11 +01001228 unittest.main(testRunner=VppTestRunner)