blob: e6829d42bb3cc3684f66f9bef39f5123dabed27e [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 random
3import socket
Pavel Kotuceke88865d2018-11-28 07:42:11 +01004import os
Pavel Kotucek9edb83a2018-12-11 16:57:25 +01005import threading
Neale Ranns50f0ac02019-05-15 02:13:37 -07006import copy
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +01007import fcntl
8import time
9
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -080010try:
11 import unittest2 as unittest
12except ImportError:
13 import unittest
14
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015from scapy.packet import Raw
16from scapy.layers.l2 import Ether
Andrew Yourtchenkofeb77422023-03-17 01:47:58 +000017from scapy.layers.l2 import Dot1Q
Pavel Kotuceke88865d2018-11-28 07:42:11 +010018from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -070019from scapy.layers.ipsec import ESP
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -080020import scapy.layers.inet6 as inet6
Dave Wallace8800f732023-08-31 00:47:44 -040021from scapy.layers.inet6 import IPv6
Neale Rannsb538dd82019-05-21 06:54:54 -070022from scapy.contrib.ospf import OSPF_Hdr, OSPFv3_Hello
Dave Wallace8800f732023-08-31 00:47:44 -040023from framework import VppTestCase
24from asfframework import VppTestRunner, tag_fixme_vpp_workers
25from vpp_sub_interface import VppDot1QSubint
Pavel Kotuceke88865d2018-11-28 07:42:11 +010026
Neale Ranns76b56492018-09-28 15:16:14 +000027from vpp_ip import DpoProto
28from vpp_ip_route import VppIpRoute, VppRoutePath
Neale Rannsa9e27742020-12-23 16:22:28 +000029from vpp_ipsec import VppIpsecSA, VppIpsecTunProtect, VppIpsecInterface
Neale Ranns50f0ac02019-05-15 02:13:37 -070030from vpp_papi import VppEnum
Neale Ranns76b56492018-09-28 15:16:14 +000031
Paul Vinciguerra4271c972019-05-14 13:25:49 -040032NUM_PKTS = 67
33
Pavel Kotuceke88865d2018-11-28 07:42:11 +010034
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010035class serverSocketThread(threading.Thread):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020036 """Socket server thread"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010037
Neale Ranns50f0ac02019-05-15 02:13:37 -070038 def __init__(self, threadID, sockName):
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010039 threading.Thread.__init__(self)
40 self.threadID = threadID
41 self.sockName = sockName
42 self.sock = None
Neale Ranns50f0ac02019-05-15 02:13:37 -070043 self.rx_pkts = []
Dave Wallacec44402f2021-05-07 21:40:54 -040044 self.stop_running = False
Neale Ranns50f0ac02019-05-15 02:13:37 -070045
46 def rx_packets(self):
47 # Wait for some packets on socket
Dave Wallacec44402f2021-05-07 21:40:54 -040048 while True:
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010049 try:
50 data = self.sock.recv(65536)
Neale Ranns50f0ac02019-05-15 02:13:37 -070051
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010052 # punt socket metadata
53 # packet_desc = data[0:8]
Neale Ranns50f0ac02019-05-15 02:13:37 -070054
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010055 # Ethernet
56 self.rx_pkts.append(Ether(data[8:]))
57 except IOError as e:
58 if e.errno == 11:
Dave Wallacec44402f2021-05-07 21:40:54 -040059 # nothing to receive, stop running or sleep a little
60 if self.stop_running:
61 break
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010062 time.sleep(0.1)
63 pass
64 else:
65 raise
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010066
67 def run(self):
68 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
69 try:
70 os.unlink(self.sockName)
71 except:
72 pass
Neale Ranns50f0ac02019-05-15 02:13:37 -070073 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
74 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010075 fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010076 self.sock.bind(self.sockName)
77
Neale Ranns50f0ac02019-05-15 02:13:37 -070078 self.rx_packets()
79
80 def close(self):
Dave Wallacec44402f2021-05-07 21:40:54 -040081 self.stop_running = True
Dave Wallacef4d338f2021-05-06 15:59:59 -040082 threading.Thread.join(self)
Dave Wallacec44402f2021-05-07 21:40:54 -040083 self.sock.close()
Neale Ranns50f0ac02019-05-15 02:13:37 -070084 return self.rx_pkts
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010085
86
Pavel Kotuceke88865d2018-11-28 07:42:11 +010087class TestPuntSocket(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020088 """Punt Socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +010089
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010090 ports = [1111, 2222, 3333, 4444]
91 sock_servers = list()
Andrew Yourtchenkocb265c62019-07-25 10:03:51 +000092 # FIXME: nr_packets > 3 results in failure
93 # nr_packets = 3 makes the test unstable
94 nr_packets = 2
Pavel Kotuceke88865d2018-11-28 07:42:11 +010095
96 @classmethod
Paul Vinciguerra8d991d92019-01-25 14:05:48 -080097 def setUpClass(cls):
98 super(TestPuntSocket, cls).setUpClass()
99
100 @classmethod
101 def tearDownClass(cls):
102 super(TestPuntSocket, cls).tearDownClass()
103
104 @classmethod
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100105 def setUpConstants(cls):
Klement Sekerad3e0d102023-01-26 12:35:35 +0100106 cls.extra_vpp_config = [
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200107 "punt",
108 "{",
109 "socket",
110 cls.tempdir + "/socket_punt",
111 "}",
112 ]
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100113 super(TestPuntSocket, cls).setUpConstants()
114
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100115 def setUp(self):
116 super(TestPuntSocket, self).setUp()
117 random.seed()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100118
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100119 self.create_pg_interfaces(range(2))
120 for i in self.pg_interfaces:
121 i.admin_up()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100122
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100123 def tearDown(self):
124 del self.sock_servers[:]
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800125 super(TestPuntSocket, self).tearDown()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100126
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100127 def socket_client_create(self, sock_name, id=None):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700128 thread = serverSocketThread(id, sock_name)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100129 self.sock_servers.append(thread)
130 thread.start()
Neale Ranns50f0ac02019-05-15 02:13:37 -0700131 return thread
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100132
133 def socket_client_close(self):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700134 rx_pkts = []
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100135 for thread in self.sock_servers:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700136 rx_pkts += thread.close()
137 return rx_pkts
138
139 def verify_port(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200140 self.assertEqual(vpr.punt.type, pr["type"])
141 self.assertEqual(vpr.punt.punt.l4.port, pr["punt"]["l4"]["port"])
142 self.assertEqual(vpr.punt.punt.l4.protocol, pr["punt"]["l4"]["protocol"])
143 self.assertEqual(vpr.punt.punt.l4.af, pr["punt"]["l4"]["af"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700144
145 def verify_exception(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200146 self.assertEqual(vpr.punt.type, pr["type"])
147 self.assertEqual(vpr.punt.punt.exception.id, pr["punt"]["exception"]["id"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700148
Neale Rannsb538dd82019-05-21 06:54:54 -0700149 def verify_ip_proto(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200150 self.assertEqual(vpr.punt.type, pr["type"])
151 self.assertEqual(vpr.punt.punt.ip_proto.af, pr["punt"]["ip_proto"]["af"])
152 self.assertEqual(
153 vpr.punt.punt.ip_proto.protocol, pr["punt"]["ip_proto"]["protocol"]
154 )
Neale Rannsb538dd82019-05-21 06:54:54 -0700155
Neale Ranns50f0ac02019-05-15 02:13:37 -0700156 def verify_udp_pkts(self, rxs, n_rx, port):
157 n_match = 0
158 for rx in rxs:
159 self.assertTrue(rx.haslayer(UDP))
160 if rx[UDP].dport == port:
161 n_match += 1
162 self.assertEqual(n_match, n_rx)
163
164
165def set_port(pr, port):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200166 pr["punt"]["l4"]["port"] = port
Neale Ranns50f0ac02019-05-15 02:13:37 -0700167 return pr
168
169
170def set_reason(pr, reason):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171 pr["punt"]["exception"]["id"] = reason
Neale Ranns50f0ac02019-05-15 02:13:37 -0700172 return pr
173
174
175def mk_vpp_cfg4():
176 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
177 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
178 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200179 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip4, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700180 return punt_l4
181
182
183def mk_vpp_cfg6():
184 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
185 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
186 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200187 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip6, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700188 return punt_l4
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100189
190
191class TestIP4PuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200192 """Punt Socket for IPv4 UDP"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100193
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800194 @classmethod
195 def setUpClass(cls):
196 super(TestIP4PuntSocket, cls).setUpClass()
197
198 @classmethod
199 def tearDownClass(cls):
200 super(TestIP4PuntSocket, cls).tearDownClass()
201
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100202 def setUp(self):
203 super(TestIP4PuntSocket, self).setUp()
204
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100205 for i in self.pg_interfaces:
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100206 i.config_ip4()
207 i.resolve_arp()
208
209 def tearDown(self):
210 super(TestIP4PuntSocket, self).tearDown()
211 for i in self.pg_interfaces:
212 i.unconfig_ip4()
213 i.admin_down()
214
215 def test_punt_socket_dump(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200216 """Punt socket registration/deregistration"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100217
Neale Ranns50f0ac02019-05-15 02:13:37 -0700218 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
219 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
220 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
221
222 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100223 self.assertEqual(len(punts), 0)
224
225 #
226 # configure a punt socket
227 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700228 punt_l4 = mk_vpp_cfg4()
229
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200230 self.vapi.punt_socket_register(
231 set_port(punt_l4, 1111), "%s/socket_punt_1111" % self.tempdir
232 )
233 self.vapi.punt_socket_register(
234 set_port(punt_l4, 2222), "%s/socket_punt_2222" % self.tempdir
235 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700236 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100237 self.assertEqual(len(punts), 2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700238 self.verify_port(set_port(punt_l4, 1111), punts[0])
239 self.verify_port(set_port(punt_l4, 2222), punts[1])
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100240
241 #
242 # deregister a punt socket
243 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700244 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
245 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100246 self.assertEqual(len(punts), 1)
247
248 #
249 # configure a punt socket again
250 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200251 self.vapi.punt_socket_register(
252 set_port(punt_l4, 1111), "%s/socket_punt_1111" % self.tempdir
253 )
254 self.vapi.punt_socket_register(
255 set_port(punt_l4, 3333), "%s/socket_punt_3333" % self.tempdir
256 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700257 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100258 self.assertEqual(len(punts), 3)
259
Neale Ranns50f0ac02019-05-15 02:13:37 -0700260 self.logger.info(self.vapi.cli("sh punt sock reg"))
261
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100262 #
263 # deregister all punt socket
264 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700265 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
266 self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
267 self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
268 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100269 self.assertEqual(len(punts), 0)
270
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100271 def test_punt_socket_traffic_single_port_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200272 """Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100273
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100274 port = self.ports[0]
Neale Ranns50f0ac02019-05-15 02:13:37 -0700275 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
276 punt_l4 = set_port(mk_vpp_cfg4(), port)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100277
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200278 p = (
279 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
280 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
281 / UDP(sport=9876, dport=port)
282 / Raw(b"\xa5" * 100)
283 )
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100284
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100285 pkts = p * self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100286
Neale Ranns50f0ac02019-05-15 02:13:37 -0700287 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100288 self.assertEqual(len(punts), 0)
289
290 #
291 # expect ICMP - port unreachable for all packets
292 #
Neale Ranns5c6dd172022-02-17 09:08:47 +0000293 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700294
295 for p in rx:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200296 self.assertEqual(int(p[IP].proto), 1) # ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -0700297 self.assertEqual(int(p[ICMP].code), 3) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100298
299 #
300 # configure a punt socket
301 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200302 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200303 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700304 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100305 self.assertEqual(len(punts), 1)
306
307 #
308 # expect punt socket and no packets on pg0
309 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700310 self.send_and_assert_no_replies(self.pg0, pkts)
311 rx = self.socket_client_close()
312 self.verify_udp_pkts(rx, len(pkts), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100313
314 #
315 # remove punt socket. expect ICMP - port unreachable for all packets
316 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700317 self.vapi.punt_socket_deregister(punt_l4)
318 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100319 self.assertEqual(len(punts), 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100320
Neale Ranns5c6dd172022-02-17 09:08:47 +0000321 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700322 for p in rx:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200323 self.assertEqual(int(p[IP].proto), 1) # ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -0700324 self.assertEqual(int(p[ICMP].code), 3) # unreachable
325
326 def test_punt_socket_traffic_multi_ports_multi_sockets(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200327 """Punt socket traffic multi ports and multi sockets"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100328
Neale Ranns50f0ac02019-05-15 02:13:37 -0700329 punt_l4 = mk_vpp_cfg4()
330
331 # configuration for each UDP port
332 cfgs = dict()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100333
334 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700335 # create stream of packets for each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100336 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700337 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100338 # choose port from port list
Neale Ranns50f0ac02019-05-15 02:13:37 -0700339 cfgs[port] = {}
340
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200341 pkt = (
342 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
343 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
344 / UDP(sport=9876, dport=port)
345 / Raw(b"\xa5" * 100)
346 )
347 cfgs[port]["pkts"] = pkt * self.nr_packets
348 cfgs[port]["port"] = port
349 cfgs[port]["vpp"] = copy.deepcopy(set_port(punt_l4, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700350
351 # configure punt sockets
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200352 cfgs[port]["sock"] = self.socket_client_create(
353 "%s/socket_%d" % (self.tempdir, port)
354 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700355 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200356 cfgs[port]["vpp"], "%s/socket_%d" % (self.tempdir, port)
357 )
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100358
359 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700360 # send the packets that get punted
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100361 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700362 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200363 self.send_and_assert_no_replies(self.pg0, cfg["pkts"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100364
365 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700366 # test that we got the excepted packets on the expected socket
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100367 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700368 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200369 rx = cfg["sock"].close()
370 self.verify_udp_pkts(rx, len(cfg["pkts"]), cfg["port"])
371 self.vapi.punt_socket_deregister(cfg["vpp"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100372
373 def test_punt_socket_traffic_multi_ports_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200374 """Punt socket traffic multi ports and single socket"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100375
Neale Ranns50f0ac02019-05-15 02:13:37 -0700376 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
377 punt_l4 = mk_vpp_cfg4()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100378
379 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700380 # create stream of packets with each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100381 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700382 pkts = []
383 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100384 # choose port from port list
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200385 pkt = (
386 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
387 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
388 / UDP(sport=9876, dport=port)
389 / Raw(b"\xa5" * 100)
390 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700391 pkts += pkt * self.nr_packets
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100392
393 #
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100394 # configure a punt socket
395 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200396 self.socket_client_create("%s/socket_multi" % self.tempdir)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100397 for p in self.ports:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200398 self.vapi.punt_socket_register(
399 set_port(punt_l4, p), "%s/socket_multi" % self.tempdir
400 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700401 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100402 self.assertEqual(len(punts), len(self.ports))
403
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100404 #
405 # expect punt socket and no packets on pg0
406 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700407 self.send_and_assert_no_replies(self.pg0, pkts)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100408 self.logger.info(self.vapi.cli("show trace"))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700409 rx = self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100410
411 for p in self.ports:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700412 self.verify_udp_pkts(rx, self.nr_packets, p)
413 self.vapi.punt_socket_deregister(set_port(punt_l4, p))
414 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100415 self.assertEqual(len(punts), 0)
416
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100417
418class TestIP6PuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200419 """Punt Socket for IPv6 UDP"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100420
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800421 @classmethod
422 def setUpClass(cls):
423 super(TestIP6PuntSocket, cls).setUpClass()
424
425 @classmethod
426 def tearDownClass(cls):
427 super(TestIP6PuntSocket, cls).tearDownClass()
428
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100429 def setUp(self):
430 super(TestIP6PuntSocket, self).setUp()
431
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100432 for i in self.pg_interfaces:
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100433 i.config_ip6()
434 i.resolve_ndp()
435
436 def tearDown(self):
437 super(TestIP6PuntSocket, self).tearDown()
438 for i in self.pg_interfaces:
439 i.unconfig_ip6()
440 i.admin_down()
441
442 def test_punt_socket_dump(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200443 """Punt socket registration"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100444
Neale Ranns50f0ac02019-05-15 02:13:37 -0700445 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
446 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
447 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
448 #
449 # configure a punt socket
450 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200451 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip6, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700452
453 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100454 self.assertEqual(len(punts), 0)
455
456 #
457 # configure a punt socket
458 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200459 self.vapi.punt_socket_register(
460 set_port(punt_l4, 1111), "%s/socket_1111" % self.tempdir
461 )
462 self.vapi.punt_socket_register(
463 set_port(punt_l4, 2222), "%s/socket_2222" % self.tempdir
464 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700465 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100466 self.assertEqual(len(punts), 2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700467 self.verify_port(set_port(punt_l4, 1111), punts[0])
468 self.verify_port(set_port(punt_l4, 2222), punts[1])
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100469
470 #
471 # deregister a punt socket
472 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700473 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
474 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100475 self.assertEqual(len(punts), 1)
476
477 #
478 # configure a punt socket again
479 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200480 self.vapi.punt_socket_register(
481 set_port(punt_l4, 1111), "%s/socket_1111" % self.tempdir
482 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700483 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100484 self.assertEqual(len(punts), 2)
485
486 #
487 # deregister all punt socket
488 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700489 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
490 self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
491 self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
492 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100493 self.assertEqual(len(punts), 0)
494
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100495 def test_punt_socket_traffic_single_port_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200496 """Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100497
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100498 port = self.ports[0]
Neale Ranns50f0ac02019-05-15 02:13:37 -0700499 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
500 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
501 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
502 punt_l4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200503 "type": pt_l4,
504 "punt": {
505 "l4": {
506 "af": af_ip6,
507 "protocol": udp_proto,
508 "port": port,
Neale Ranns50f0ac02019-05-15 02:13:37 -0700509 }
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200510 },
Neale Ranns50f0ac02019-05-15 02:13:37 -0700511 }
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100512
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200513 p = (
514 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
515 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
516 / inet6.UDP(sport=9876, dport=port)
517 / Raw(b"\xa5" * 100)
518 )
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100519
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100520 pkts = p * self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100521
Neale Ranns50f0ac02019-05-15 02:13:37 -0700522 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100523 self.assertEqual(len(punts), 0)
524
525 #
526 # expect ICMPv6 - destination unreachable for all packets
527 #
528 self.vapi.cli("clear trace")
529 self.pg0.add_stream(pkts)
530 self.pg_enable_capture(self.pg_interfaces)
531 self.pg_start()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100532 # FIXME - when punt socket deregister is implemented
533 # rx = self.pg0.get_capture(self.nr_packets)
534 # for p in rx:
535 # self.assertEqual(int(p[IPv6].nh), 58) # ICMPv6
536 # self.assertEqual(int(p[ICMPv6DestUnreach].code),4) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100537
538 #
539 # configure a punt socket
540 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200541 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200542 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700543 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100544 self.assertEqual(len(punts), 1)
545
546 #
547 # expect punt socket and no packets on pg0
548 #
549 self.vapi.cli("clear errors")
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100550 self.vapi.cli("clear trace")
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100551 self.pg0.add_stream(pkts)
552 self.pg_enable_capture(self.pg_interfaces)
553 self.pg_start()
554 self.pg0.get_capture(0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100555 self.logger.info(self.vapi.cli("show trace"))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700556 rx = self.socket_client_close()
557 self.verify_udp_pkts(rx, len(pkts), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100558
559 #
560 # remove punt socket. expect ICMP - dest. unreachable for all packets
561 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700562 self.vapi.punt_socket_deregister(punt_l4)
563 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100564 self.assertEqual(len(punts), 0)
565 self.pg0.add_stream(pkts)
566 self.pg_enable_capture(self.pg_interfaces)
567 self.pg_start()
568 # FIXME - when punt socket deregister is implemented
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100569 # self.pg0.get_capture(nr_packets)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100570
Neale Ranns50f0ac02019-05-15 02:13:37 -0700571 def test_punt_socket_traffic_multi_ports_multi_sockets(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200572 """Punt socket traffic multi ports and multi sockets"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100573
Neale Ranns50f0ac02019-05-15 02:13:37 -0700574 punt_l4 = mk_vpp_cfg6()
575
576 # configuration for each UDP port
577 cfgs = dict()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100578
579 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700580 # create stream of packets for each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100581 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700582 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100583 # choose port from port list
Neale Ranns50f0ac02019-05-15 02:13:37 -0700584 cfgs[port] = {}
585
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200586 pkt = (
587 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
588 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
589 / UDP(sport=9876, dport=port)
590 / Raw(b"\xa5" * 100)
591 )
592 cfgs[port]["pkts"] = pkt * self.nr_packets
593 cfgs[port]["port"] = port
594 cfgs[port]["vpp"] = copy.deepcopy(set_port(punt_l4, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700595
596 # configure punt sockets
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200597 cfgs[port]["sock"] = self.socket_client_create(
598 "%s/socket_%d" % (self.tempdir, port)
599 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700600 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200601 cfgs[port]["vpp"], "%s/socket_%d" % (self.tempdir, port)
602 )
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100603
604 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700605 # send the packets that get punted
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100606 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700607 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200608 self.send_and_assert_no_replies(self.pg0, cfg["pkts"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100609
610 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700611 # test that we got the excepted packets on the expected socket
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100612 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700613 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200614 rx = cfg["sock"].close()
615 self.verify_udp_pkts(rx, len(cfg["pkts"]), cfg["port"])
616 self.vapi.punt_socket_deregister(cfg["vpp"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100617
618 def test_punt_socket_traffic_multi_ports_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200619 """Punt socket traffic multi ports and single socket"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100620
Neale Ranns50f0ac02019-05-15 02:13:37 -0700621 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
622 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
623 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
624 punt_l4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200625 "type": pt_l4,
626 "punt": {
627 "l4": {
628 "af": af_ip6,
629 "protocol": udp_proto,
Neale Ranns50f0ac02019-05-15 02:13:37 -0700630 }
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200631 },
Neale Ranns50f0ac02019-05-15 02:13:37 -0700632 }
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100633
634 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700635 # create stream of packets with each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100636 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700637 pkts = []
638 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100639 # choose port from port list
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200640 pkt = (
641 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
642 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
643 / UDP(sport=9876, dport=port)
644 / Raw(b"\xa5" * 100)
645 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700646 pkts += pkt * self.nr_packets
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100647
648 #
649 # no punt socket
650 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700651 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100652 self.assertEqual(len(punts), 0)
653
654 #
655 # configure a punt socket
656 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200657 self.socket_client_create("%s/socket_multi" % self.tempdir)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100658 for p in self.ports:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200659 self.vapi.punt_socket_register(
660 set_port(punt_l4, p), "%s/socket_multi" % self.tempdir
661 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700662 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100663 self.assertEqual(len(punts), len(self.ports))
664
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100665 #
666 # expect punt socket and no packets on pg0
667 #
668 self.vapi.cli("clear errors")
669 self.vapi.cli("clear trace")
670 self.pg0.add_stream(pkts)
671 self.pg_enable_capture(self.pg_interfaces)
672 self.pg_start()
Andrew Yourtchenkocb265c62019-07-25 10:03:51 +0000673 # give a chance to punt socket to collect all packets
674 self.sleep(1)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100675 self.pg0.get_capture(0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700676 rx = self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100677
678 for p in self.ports:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700679 self.verify_udp_pkts(rx, self.nr_packets, p)
680 self.vapi.punt_socket_deregister(set_port(punt_l4, p))
681 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100682 self.assertEqual(len(punts), 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100683
Neale Ranns76b56492018-09-28 15:16:14 +0000684
Neale Ranns50f0ac02019-05-15 02:13:37 -0700685class TestExceptionPuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200686 """Punt Socket for Exceptions"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700687
688 @classmethod
689 def setUpClass(cls):
690 super(TestExceptionPuntSocket, cls).setUpClass()
691
692 @classmethod
693 def tearDownClass(cls):
694 super(TestExceptionPuntSocket, cls).tearDownClass()
695
696 def setUp(self):
697 super(TestExceptionPuntSocket, self).setUp()
698
Neale Ranns12989b52019-09-26 16:20:19 +0000699 self.create_pg_interfaces(range(2))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700700 for i in self.pg_interfaces:
701 i.config_ip4()
702 i.resolve_arp()
703
704 def tearDown(self):
705 super(TestExceptionPuntSocket, self).tearDown()
706 for i in self.pg_interfaces:
707 i.unconfig_ip4()
708 i.admin_down()
709
710 def test_registration(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200711 """Punt socket registration/deregistration"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700712
713 pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION
714
715 punts = self.vapi.punt_socket_dump(type=pt_ex)
716 self.assertEqual(len(punts), 0)
717
718 #
719 # configure a punt socket
720 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200721 punt_ex = {"type": pt_ex, "punt": {"exception": {}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700722
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200723 self.vapi.punt_socket_register(
724 set_reason(punt_ex, 1), "%s/socket_punt_1" % self.tempdir
725 )
726 self.vapi.punt_socket_register(
727 set_reason(punt_ex, 2), "%s/socket_punt_2" % self.tempdir
728 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700729 punts = self.vapi.punt_socket_dump(type=pt_ex)
730 self.assertEqual(len(punts), 2)
731 self.verify_exception(set_reason(punt_ex, 1), punts[0])
732 self.verify_exception(set_reason(punt_ex, 2), punts[1])
733
734 #
735 # deregister a punt socket
736 #
737 self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
738 punts = self.vapi.punt_socket_dump(type=pt_ex)
739 self.assertEqual(len(punts), 1)
740
741 #
742 # configure a punt socket again
743 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200744 self.vapi.punt_socket_register(
745 set_reason(punt_ex, 1), "%s/socket_punt_1" % self.tempdir
746 )
747 self.vapi.punt_socket_register(
748 set_reason(punt_ex, 3), "%s/socket_punt_3" % self.tempdir
749 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700750 punts = self.vapi.punt_socket_dump(type=pt_ex)
751 self.assertEqual(len(punts), 3)
752
753 self.logger.info(self.vapi.cli("sh punt sock reg exception"))
754
755 #
756 # deregister all punt socket
757 #
758 self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
759 self.vapi.punt_socket_deregister(set_reason(punt_ex, 2))
760 self.vapi.punt_socket_deregister(set_reason(punt_ex, 3))
761 punts = self.vapi.punt_socket_dump(type=pt_ex)
762 self.assertEqual(len(punts), 0)
763
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700764 def verify_esp_pkts(self, rxs, n_sent, spi, has_udp):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700765 self.assertEqual(len(rxs), n_sent)
766 for rx in rxs:
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700767 self.assertTrue(rx.haslayer(IP))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700768 self.assertTrue(rx.haslayer(ESP))
769 self.assertEqual(rx[ESP].spi, spi)
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700770 if has_udp:
771 self.assertTrue(rx.haslayer(UDP))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700772
773 def test_traffic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200774 """Punt socket traffic"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700775
776 port = self.ports[0]
777 pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200778 punt_ex = {"type": pt_ex, "punt": {"exception": {}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700779
780 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700781 # we're dealing with IPSec tunnels punting for no-such-tunnel
Filip Tehlar4362baa2020-04-02 13:13:39 +0000782 # (SPI=0 goes to ikev2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700783 #
784 cfgs = dict()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200785 cfgs["ipsec4-no-such-tunnel"] = {"spi": 99, "udp": False, "itf": self.pg0}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700786
787 #
788 # find the VPP ID for these punt exception reasin
789 #
790 rs = self.vapi.punt_reason_dump()
791 for key in cfgs:
792 for r in rs:
Jakub Grajciar2dbee932020-02-07 11:30:26 +0100793 print(r.reason.name)
794 print(key)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700795 if r.reason.name == key:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200796 cfgs[key]["id"] = r.reason.id
797 cfgs[key]["vpp"] = copy.deepcopy(
798 set_reason(punt_ex, cfgs[key]["id"])
799 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700800 break
801
802 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700803 # configure punt sockets
Neale Ranns50f0ac02019-05-15 02:13:37 -0700804 #
805 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200806 cfg["sock"] = self.socket_client_create(
807 "%s/socket_%d" % (self.tempdir, cfg["id"])
808 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700809 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200810 cfg["vpp"], "%s/socket_%d" % (self.tempdir, cfg["id"])
811 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700812
813 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700814 # create packet streams for 'no-such-tunnel' exception
815 #
816 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200817 pkt = Ether(src=cfg["itf"].remote_mac, dst=cfg["itf"].local_mac) / IP(
818 src=cfg["itf"].remote_ip4, dst=cfg["itf"].local_ip4
819 )
820 if cfg["udp"]:
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700821 pkt = pkt / UDP(sport=666, dport=4500)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200822 pkt = pkt / ESP(spi=cfg["spi"], seq=3) / Raw(b"\xa5" * 100)
823 cfg["pkts"] = [pkt]
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700824
825 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700826 # send packets for each SPI we expect to be punted
827 #
828 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200829 self.send_and_assert_no_replies(cfg["itf"], cfg["pkts"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700830
831 #
832 # verify the punted packets arrived on the associated socket
833 #
834 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200835 rx = cfg["sock"].close()
836 self.verify_esp_pkts(rx, len(cfg["pkts"]), cfg["spi"], cfg["udp"])
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700837
838 #
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000839 # add some tunnels, make sure it still punts
840 #
Neale Rannsa9e27742020-12-23 16:22:28 +0000841 tun = VppIpsecInterface(self).add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200842 sa_in = VppIpsecSA(
843 self,
844 11,
845 11,
846 (VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96),
847 b"0123456701234567",
848 (VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128),
849 b"0123456701234567",
850 50,
851 self.pg0.local_ip4,
852 self.pg0.remote_ip4,
853 ).add_vpp_config()
854 sa_out = VppIpsecSA(
855 self,
856 22,
857 22,
858 (VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96),
859 b"0123456701234567",
860 (VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128),
861 b"0123456701234567",
862 50,
863 self.pg0.local_ip4,
864 self.pg0.remote_ip4,
865 ).add_vpp_config()
866 protect = VppIpsecTunProtect(self, tun, sa_out, [sa_in]).add_vpp_config()
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000867
868 #
869 # send packets for each SPI we expect to be punted
870 #
871 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200872 self.send_and_assert_no_replies(cfg["itf"], cfg["pkts"])
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000873
874 #
875 # verify the punted packets arrived on the associated socket
876 #
877 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200878 rx = cfg["sock"].close()
879 self.verify_esp_pkts(rx, len(cfg["pkts"]), cfg["spi"], cfg["udp"])
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000880 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700881 # socket deregister
882 #
883 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200884 self.vapi.punt_socket_deregister(cfg["vpp"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700885
886
Neale Rannsb538dd82019-05-21 06:54:54 -0700887class TestIpProtoPuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200888 """Punt Socket for IP packets"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700889
890 @classmethod
891 def setUpClass(cls):
892 super(TestIpProtoPuntSocket, cls).setUpClass()
893
894 @classmethod
895 def tearDownClass(cls):
896 super(TestIpProtoPuntSocket, cls).tearDownClass()
897
898 def setUp(self):
899 super(TestIpProtoPuntSocket, self).setUp()
900
901 for i in self.pg_interfaces:
902 i.config_ip4()
903 i.resolve_arp()
904
905 def tearDown(self):
906 super(TestIpProtoPuntSocket, self).tearDown()
907 for i in self.pg_interfaces:
908 i.unconfig_ip4()
909 i.admin_down()
910
911 def test_registration(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200912 """Punt socket registration/deregistration"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700913
914 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
915 pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
916 proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF
917 proto_eigrp = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_EIGRP
918
919 punts = self.vapi.punt_socket_dump(type=pt_ip)
920 self.assertEqual(len(punts), 0)
921
922 #
923 # configure a punt socket
924 #
925 punt_ospf = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200926 "type": pt_ip,
927 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_ospf}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700928 }
929 punt_eigrp = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200930 "type": pt_ip,
931 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_eigrp}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700932 }
933
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200934 self.vapi.punt_socket_register(punt_ospf, "%s/socket_punt_1" % self.tempdir)
935 self.vapi.punt_socket_register(punt_eigrp, "%s/socket_punt_2" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -0700936 self.logger.info(self.vapi.cli("sh punt sock reg ip"))
937 punts = self.vapi.punt_socket_dump(type=pt_ip)
938 self.assertEqual(len(punts), 2)
939 self.verify_ip_proto(punt_ospf, punts[0])
940 self.verify_ip_proto(punt_eigrp, punts[1])
941
942 #
943 # deregister a punt socket
944 #
945 self.vapi.punt_socket_deregister(punt_ospf)
946 punts = self.vapi.punt_socket_dump(type=pt_ip)
947 self.assertEqual(len(punts), 1)
948
949 #
950 # configure a punt socket again
951 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200952 self.vapi.punt_socket_register(punt_ospf, "%s/socket_punt_3" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -0700953 punts = self.vapi.punt_socket_dump(type=pt_ip)
954 self.assertEqual(len(punts), 2)
955
956 self.logger.info(self.vapi.cli("sh punt sock reg exception"))
957
958 #
959 # deregister all punt socket
960 #
961 self.vapi.punt_socket_deregister(punt_eigrp)
962 self.vapi.punt_socket_deregister(punt_ospf)
963 punts = self.vapi.punt_socket_dump(type=pt_ip)
964 self.assertEqual(len(punts), 0)
965
966 def verify_ospf_pkts(self, rxs, n_sent):
967 self.assertEqual(len(rxs), n_sent)
968 for rx in rxs:
969 self.assertTrue(rx.haslayer(OSPF_Hdr))
970
971 def test_traffic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200972 """Punt socket traffic"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700973
974 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
975 pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
976 proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF
977
978 #
979 # configure a punt socket to capture OSPF packets
980 #
981 punt_ospf = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200982 "type": pt_ip,
983 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_ospf}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700984 }
985
986 #
987 # create packet streams and configure a punt sockets
988 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200989 pkt = (
990 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
991 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
992 / OSPF_Hdr()
993 / OSPFv3_Hello()
994 )
Neale Rannsb538dd82019-05-21 06:54:54 -0700995 pkts = pkt * 7
996
Ole Troan9cd8f332019-10-18 15:57:56 +0200997 sock = self.socket_client_create("%s/socket_1" % self.tempdir)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200998 self.vapi.punt_socket_register(punt_ospf, "%s/socket_1" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -0700999
1000 #
1001 # send packets for each SPI we expect to be punted
1002 #
1003 self.send_and_assert_no_replies(self.pg0, pkts)
1004
1005 #
1006 # verify the punted packets arrived on the associated socket
1007 #
1008 rx = sock.close()
1009 self.verify_ospf_pkts(rx, len(pkts))
1010 self.vapi.punt_socket_deregister(punt_ospf)
1011
1012
Andrew Yourtchenkofeb77422023-03-17 01:47:58 +00001013class TestDot1QPuntSocket(TestPuntSocket):
1014 """Punt Socket for 802.1Q (dot1q)"""
1015
1016 def setUp(self):
1017 super(TestDot1QPuntSocket, self).setUp()
1018
1019 for i in self.pg_interfaces:
1020 i.admin_up()
1021 i.config_ip4()
1022 i.resolve_arp()
1023
1024 def tearDown(self):
1025 super(TestDot1QPuntSocket, self).tearDown()
1026 for i in self.pg_interfaces:
1027 i.unconfig_ip4()
1028 i.admin_down()
1029
1030 def test_dot1q_header_punt(self):
1031 """Punt socket traffic with Dot1q header"""
1032
1033 port = self.ports[0]
1034 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
1035 punt_l4 = set_port(mk_vpp_cfg4(), port)
1036
1037 # VLAN ID
1038 vlan_id = 100
1039
1040 # Create a subinterface with the VLAN ID
1041 subif = VppDot1QSubint(self, self.pg0, vlan_id)
1042 subif.admin_up()
1043 subif.config_ip4()
1044
1045 # Configure an IP address on the subinterface
1046 subif_ip4 = subif.local_ip4
1047
1048 p = (
1049 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
1050 / Dot1Q(vlan=vlan_id)
1051 / IP(src=self.pg0.remote_ip4, dst=subif_ip4)
1052 / UDP(sport=9876, dport=port)
1053 / Raw(b"\xa5" * 100)
1054 )
1055
1056 pkts = p * self.nr_packets
1057
1058 # Expect ICMP - port unreachable for all packets
1059 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
1060
1061 for p in rx:
1062 self.assertEqual(int(p[IP].proto), 1) # ICMP
1063 self.assertEqual(int(p[ICMP].code), 3) # unreachable
1064
1065 # Configure a punt socket
1066 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
1067 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
1068 punts = self.vapi.punt_socket_dump(type=pt_l4)
1069 self.assertEqual(len(punts), 1)
1070
1071 # Expect punt socket and no packets on pg0
1072 self.send_and_assert_no_replies(self.pg0, pkts)
1073 rx = self.socket_client_close()
1074 self.logger.info("RXPKT")
1075 self.logger.info(rx)
1076 self.verify_udp_pkts(rx, len(pkts), port)
1077 for pkt in rx:
1078 self.assertEqual(pkt[Ether].src, self.pg0.remote_mac)
1079 self.assertEqual(pkt[Ether].dst, self.pg0.local_mac)
1080 self.assertEqual(pkt[Dot1Q].vlan, 100)
1081
1082 # Remove punt socket. Expect ICMP - port unreachable for all packets
1083 self.vapi.punt_socket_deregister(punt_l4)
1084 punts = self.vapi.punt_socket_dump(type=pt_l4)
1085 self.assertEqual(len(punts), 0)
1086
1087 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
1088 for p in rx:
1089 self.assertEqual(int(p[IP].proto), 1) # ICMP
1090 self.assertEqual(int(p[ICMP].code), 3) # unreachable
1091
1092
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001093@tag_fixme_vpp_workers
Neale Ranns76b56492018-09-28 15:16:14 +00001094class TestPunt(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001095 """Exception Punt Test Case"""
Neale Ranns76b56492018-09-28 15:16:14 +00001096
1097 @classmethod
1098 def setUpClass(cls):
1099 super(TestPunt, cls).setUpClass()
1100
1101 @classmethod
1102 def tearDownClass(cls):
1103 super(TestPunt, cls).tearDownClass()
1104
1105 def setUp(self):
1106 super(TestPunt, self).setUp()
1107
1108 self.create_pg_interfaces(range(4))
1109
1110 for i in self.pg_interfaces:
1111 i.admin_up()
1112 i.config_ip4()
1113 i.resolve_arp()
1114 i.config_ip6()
1115 i.resolve_ndp()
1116
1117 def tearDown(self):
1118 for i in self.pg_interfaces:
1119 i.unconfig_ip4()
1120 i.unconfig_ip6()
Neale Ranns76b56492018-09-28 15:16:14 +00001121 i.admin_down()
1122 super(TestPunt, self).tearDown()
1123
1124 def test_punt(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001125 """Exception Path testing"""
Neale Ranns76b56492018-09-28 15:16:14 +00001126
1127 #
Neale Ranns719beb72019-07-10 07:10:25 +00001128 # dump the punt registered reasons
1129 # search for a few we know should be there
1130 #
1131 rs = self.vapi.punt_reason_dump()
1132
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001133 reasons = [
1134 "ipsec6-no-such-tunnel",
1135 "ipsec4-no-such-tunnel",
1136 "ipsec4-spi-o-udp-0",
1137 ]
Neale Ranns719beb72019-07-10 07:10:25 +00001138
1139 for reason in reasons:
1140 found = False
1141 for r in rs:
1142 if r.reason.name == reason:
1143 found = True
1144 break
1145 self.assertTrue(found)
1146
1147 #
Neale Ranns76b56492018-09-28 15:16:14 +00001148 # Using the test CLI we will hook in a exception path to
1149 # send ACL deny packets out of pg0 and pg1.
1150 # the ACL is src,dst = 1.1.1.1,1.1.1.2
1151 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001152 ip_1_1_1_2 = VppIpRoute(
1153 self,
1154 "1.1.1.2",
1155 32,
1156 [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)],
1157 )
Neale Ranns76b56492018-09-28 15:16:14 +00001158 ip_1_1_1_2.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001159 ip_1_2 = VppIpRoute(
1160 self,
1161 "1::2",
1162 128,
1163 [
1164 VppRoutePath(
1165 self.pg3.remote_ip6,
1166 self.pg3.sw_if_index,
1167 proto=DpoProto.DPO_PROTO_IP6,
1168 )
1169 ],
1170 )
Neale Ranns76b56492018-09-28 15:16:14 +00001171 ip_1_2.add_vpp_config()
1172
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001173 p4 = (
1174 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
1175 / IP(src="1.1.1.1", dst="1.1.1.2")
1176 / UDP(sport=1234, dport=1234)
1177 / Raw(b"\xa5" * 100)
1178 )
1179 p6 = (
1180 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
1181 / IPv6(src="1::1", dst="1::2")
1182 / UDP(sport=1234, dport=1234)
1183 / Raw(b"\xa5" * 100)
1184 )
1185 self.send_and_expect(self.pg2, p4 * 1, self.pg3)
1186 self.send_and_expect(self.pg2, p6 * 1, self.pg3)
Neale Ranns76b56492018-09-28 15:16:14 +00001187
1188 #
1189 # apply the punting features
1190 #
1191 self.vapi.cli("test punt pg2")
1192
1193 #
Neale Ranns719beb72019-07-10 07:10:25 +00001194 # dump the punt reasons to learn the IDs assigned
1195 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001196 rs = self.vapi.punt_reason_dump(reason={"name": "reason-v4"})
Neale Ranns719beb72019-07-10 07:10:25 +00001197 r4 = rs[0].reason.id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001198 rs = self.vapi.punt_reason_dump(reason={"name": "reason-v6"})
Neale Ranns719beb72019-07-10 07:10:25 +00001199 r6 = rs[0].reason.id
1200
1201 #
Neale Ranns76b56492018-09-28 15:16:14 +00001202 # pkts now dropped
1203 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001204 self.send_and_assert_no_replies(self.pg2, p4 * NUM_PKTS)
1205 self.send_and_assert_no_replies(self.pg2, p6 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001206
1207 #
1208 # Check state:
1209 # 1 - node error counters
1210 # 2 - per-reason counters
1211 # 2, 3 are the index of the assigned punt reason
1212 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001213 stats = self.statistics.get_err_counter("/err/punt-dispatch/No registrations")
1214 self.assertEqual(stats, 2 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001215
1216 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001217 self.assertEqual(stats[0][r4]["packets"], NUM_PKTS)
1218 self.assertEqual(stats[0][r6]["packets"], NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001219
1220 #
1221 # use the test CLI to test a client that punts exception
1222 # packets out of pg0
1223 #
1224 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip4)
1225 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip6)
1226
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001227 rx4s = self.send_and_expect(self.pg2, p4 * NUM_PKTS, self.pg0)
1228 rx6s = self.send_and_expect(self.pg2, p6 * NUM_PKTS, self.pg0)
Neale Ranns76b56492018-09-28 15:16:14 +00001229
1230 #
1231 # check the packets come out IP unmodified but destined to pg0 host
1232 #
1233 for rx in rx4s:
1234 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1235 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1236 self.assertEqual(p4[IP].dst, rx[IP].dst)
1237 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
1238 for rx in rx6s:
1239 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1240 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1241 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1242 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
1243
1244 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001245 self.assertEqual(stats[0][r4]["packets"], 2 * NUM_PKTS)
1246 self.assertEqual(stats[0][r6]["packets"], 2 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001247
1248 #
1249 # add another registration for the same reason to send packets
1250 # out of pg1
1251 #
1252 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip4)
1253 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip6)
1254
1255 self.vapi.cli("clear trace")
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001256 self.pg2.add_stream(p4 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001257 self.pg_enable_capture(self.pg_interfaces)
1258 self.pg_start()
1259
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001260 rxd = self.pg0.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001261 for rx in rxd:
1262 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1263 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1264 self.assertEqual(p4[IP].dst, rx[IP].dst)
1265 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001266 rxd = self.pg1.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001267 for rx in rxd:
1268 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
1269 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
1270 self.assertEqual(p4[IP].dst, rx[IP].dst)
1271 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
1272
1273 self.vapi.cli("clear trace")
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001274 self.pg2.add_stream(p6 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001275 self.pg_enable_capture(self.pg_interfaces)
1276 self.pg_start()
1277
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001278 rxd = self.pg0.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001279 for rx in rxd:
1280 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1281 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1282 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1283 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001284 rxd = self.pg1.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001285 for rx in rxd:
1286 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
1287 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
1288 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1289 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
1290
1291 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001292 self.assertEqual(stats[0][r4]["packets"], 3 * NUM_PKTS)
1293 self.assertEqual(stats[0][r6]["packets"], 3 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001294
1295 self.logger.info(self.vapi.cli("show vlib graph punt-dispatch"))
1296 self.logger.info(self.vapi.cli("show punt client"))
1297 self.logger.info(self.vapi.cli("show punt reason"))
1298 self.logger.info(self.vapi.cli("show punt stats"))
1299 self.logger.info(self.vapi.cli("show punt db"))
1300
Neale Ranns76b56492018-09-28 15:16:14 +00001301
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001302if __name__ == "__main__":
Pavel Kotuceke88865d2018-11-28 07:42:11 +01001303 unittest.main(testRunner=VppTestRunner)