blob: 75d5d99e9c91fcb2cf8f1611e461f203986dafa7 [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
Andrew Yourtchenkofeb77422023-03-17 01:47:58 +000024from scapy.layers.l2 import Dot1Q
Pavel Kotuceke88865d2018-11-28 07:42:11 +010025from scapy.layers.inet import IP, UDP, ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -070026from scapy.layers.ipsec import ESP
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -080027import scapy.layers.inet6 as inet6
Pavel Kotuceke88865d2018-11-28 07:42:11 +010028from scapy.layers.inet6 import IPv6, ICMPv6DestUnreach
Neale Rannsb538dd82019-05-21 06:54:54 -070029from scapy.contrib.ospf import OSPF_Hdr, OSPFv3_Hello
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000030from framework import tag_fixme_vpp_workers
Pavel Kotuceke88865d2018-11-28 07:42:11 +010031from framework import VppTestCase, VppTestRunner
Andrew Yourtchenkofeb77422023-03-17 01:47:58 +000032from vpp_sub_interface import VppSubInterface, VppDot1QSubint
Pavel Kotuceke88865d2018-11-28 07:42:11 +010033
Neale Ranns76b56492018-09-28 15:16:14 +000034from vpp_ip import DpoProto
35from vpp_ip_route import VppIpRoute, VppRoutePath
Neale Rannsa9e27742020-12-23 16:22:28 +000036from vpp_ipsec import VppIpsecSA, VppIpsecTunProtect, VppIpsecInterface
Neale Ranns50f0ac02019-05-15 02:13:37 -070037from vpp_papi import VppEnum
Neale Ranns76b56492018-09-28 15:16:14 +000038
Paul Vinciguerra4271c972019-05-14 13:25:49 -040039NUM_PKTS = 67
40
Pavel Kotuceke88865d2018-11-28 07:42:11 +010041
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010042class serverSocketThread(threading.Thread):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020043 """Socket server thread"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010044
Neale Ranns50f0ac02019-05-15 02:13:37 -070045 def __init__(self, threadID, sockName):
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010046 threading.Thread.__init__(self)
47 self.threadID = threadID
48 self.sockName = sockName
49 self.sock = None
Neale Ranns50f0ac02019-05-15 02:13:37 -070050 self.rx_pkts = []
Dave Wallacec44402f2021-05-07 21:40:54 -040051 self.stop_running = False
Neale Ranns50f0ac02019-05-15 02:13:37 -070052
53 def rx_packets(self):
54 # Wait for some packets on socket
Dave Wallacec44402f2021-05-07 21:40:54 -040055 while True:
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010056 try:
57 data = self.sock.recv(65536)
Neale Ranns50f0ac02019-05-15 02:13:37 -070058
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010059 # punt socket metadata
60 # packet_desc = data[0:8]
Neale Ranns50f0ac02019-05-15 02:13:37 -070061
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010062 # Ethernet
63 self.rx_pkts.append(Ether(data[8:]))
64 except IOError as e:
65 if e.errno == 11:
Dave Wallacec44402f2021-05-07 21:40:54 -040066 # nothing to receive, stop running or sleep a little
67 if self.stop_running:
68 break
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010069 time.sleep(0.1)
70 pass
71 else:
72 raise
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010073
74 def run(self):
75 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
76 try:
77 os.unlink(self.sockName)
78 except:
79 pass
Neale Ranns50f0ac02019-05-15 02:13:37 -070080 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
81 self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
Andrew Yourtchenko3f8c8712019-11-05 19:38:08 +010082 fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010083 self.sock.bind(self.sockName)
84
Neale Ranns50f0ac02019-05-15 02:13:37 -070085 self.rx_packets()
86
87 def close(self):
Dave Wallacec44402f2021-05-07 21:40:54 -040088 self.stop_running = True
Dave Wallacef4d338f2021-05-06 15:59:59 -040089 threading.Thread.join(self)
Dave Wallacec44402f2021-05-07 21:40:54 -040090 self.sock.close()
Neale Ranns50f0ac02019-05-15 02:13:37 -070091 return self.rx_pkts
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010092
93
Pavel Kotuceke88865d2018-11-28 07:42:11 +010094class TestPuntSocket(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020095 """Punt Socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +010096
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010097 ports = [1111, 2222, 3333, 4444]
98 sock_servers = list()
Andrew Yourtchenkocb265c62019-07-25 10:03:51 +000099 # FIXME: nr_packets > 3 results in failure
100 # nr_packets = 3 makes the test unstable
101 nr_packets = 2
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100102
103 @classmethod
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800104 def setUpClass(cls):
105 super(TestPuntSocket, cls).setUpClass()
106
107 @classmethod
108 def tearDownClass(cls):
109 super(TestPuntSocket, cls).tearDownClass()
110
111 @classmethod
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100112 def setUpConstants(cls):
Klement Sekerad3e0d102023-01-26 12:35:35 +0100113 cls.extra_vpp_config = [
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200114 "punt",
115 "{",
116 "socket",
117 cls.tempdir + "/socket_punt",
118 "}",
119 ]
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100120 super(TestPuntSocket, cls).setUpConstants()
121
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100122 def setUp(self):
123 super(TestPuntSocket, self).setUp()
124 random.seed()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100125
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100126 self.create_pg_interfaces(range(2))
127 for i in self.pg_interfaces:
128 i.admin_up()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100129
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100130 def tearDown(self):
131 del self.sock_servers[:]
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800132 super(TestPuntSocket, self).tearDown()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100133
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100134 def socket_client_create(self, sock_name, id=None):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700135 thread = serverSocketThread(id, sock_name)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100136 self.sock_servers.append(thread)
137 thread.start()
Neale Ranns50f0ac02019-05-15 02:13:37 -0700138 return thread
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100139
140 def socket_client_close(self):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700141 rx_pkts = []
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100142 for thread in self.sock_servers:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700143 rx_pkts += thread.close()
144 return rx_pkts
145
146 def verify_port(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200147 self.assertEqual(vpr.punt.type, pr["type"])
148 self.assertEqual(vpr.punt.punt.l4.port, pr["punt"]["l4"]["port"])
149 self.assertEqual(vpr.punt.punt.l4.protocol, pr["punt"]["l4"]["protocol"])
150 self.assertEqual(vpr.punt.punt.l4.af, pr["punt"]["l4"]["af"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700151
152 def verify_exception(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200153 self.assertEqual(vpr.punt.type, pr["type"])
154 self.assertEqual(vpr.punt.punt.exception.id, pr["punt"]["exception"]["id"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700155
Neale Rannsb538dd82019-05-21 06:54:54 -0700156 def verify_ip_proto(self, pr, vpr):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200157 self.assertEqual(vpr.punt.type, pr["type"])
158 self.assertEqual(vpr.punt.punt.ip_proto.af, pr["punt"]["ip_proto"]["af"])
159 self.assertEqual(
160 vpr.punt.punt.ip_proto.protocol, pr["punt"]["ip_proto"]["protocol"]
161 )
Neale Rannsb538dd82019-05-21 06:54:54 -0700162
Neale Ranns50f0ac02019-05-15 02:13:37 -0700163 def verify_udp_pkts(self, rxs, n_rx, port):
164 n_match = 0
165 for rx in rxs:
166 self.assertTrue(rx.haslayer(UDP))
167 if rx[UDP].dport == port:
168 n_match += 1
169 self.assertEqual(n_match, n_rx)
170
171
172def set_port(pr, port):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200173 pr["punt"]["l4"]["port"] = port
Neale Ranns50f0ac02019-05-15 02:13:37 -0700174 return pr
175
176
177def set_reason(pr, reason):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200178 pr["punt"]["exception"]["id"] = reason
Neale Ranns50f0ac02019-05-15 02:13:37 -0700179 return pr
180
181
182def mk_vpp_cfg4():
183 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
184 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
185 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200186 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip4, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700187 return punt_l4
188
189
190def mk_vpp_cfg6():
191 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
192 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
193 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200194 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip6, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700195 return punt_l4
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100196
197
198class TestIP4PuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200199 """Punt Socket for IPv4 UDP"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100200
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800201 @classmethod
202 def setUpClass(cls):
203 super(TestIP4PuntSocket, cls).setUpClass()
204
205 @classmethod
206 def tearDownClass(cls):
207 super(TestIP4PuntSocket, cls).tearDownClass()
208
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100209 def setUp(self):
210 super(TestIP4PuntSocket, self).setUp()
211
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100212 for i in self.pg_interfaces:
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100213 i.config_ip4()
214 i.resolve_arp()
215
216 def tearDown(self):
217 super(TestIP4PuntSocket, self).tearDown()
218 for i in self.pg_interfaces:
219 i.unconfig_ip4()
220 i.admin_down()
221
222 def test_punt_socket_dump(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200223 """Punt socket registration/deregistration"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100224
Neale Ranns50f0ac02019-05-15 02:13:37 -0700225 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
226 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
227 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
228
229 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100230 self.assertEqual(len(punts), 0)
231
232 #
233 # configure a punt socket
234 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700235 punt_l4 = mk_vpp_cfg4()
236
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200237 self.vapi.punt_socket_register(
238 set_port(punt_l4, 1111), "%s/socket_punt_1111" % self.tempdir
239 )
240 self.vapi.punt_socket_register(
241 set_port(punt_l4, 2222), "%s/socket_punt_2222" % self.tempdir
242 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700243 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100244 self.assertEqual(len(punts), 2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700245 self.verify_port(set_port(punt_l4, 1111), punts[0])
246 self.verify_port(set_port(punt_l4, 2222), punts[1])
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100247
248 #
249 # deregister a punt socket
250 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700251 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
252 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100253 self.assertEqual(len(punts), 1)
254
255 #
256 # configure a punt socket again
257 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200258 self.vapi.punt_socket_register(
259 set_port(punt_l4, 1111), "%s/socket_punt_1111" % self.tempdir
260 )
261 self.vapi.punt_socket_register(
262 set_port(punt_l4, 3333), "%s/socket_punt_3333" % self.tempdir
263 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700264 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100265 self.assertEqual(len(punts), 3)
266
Neale Ranns50f0ac02019-05-15 02:13:37 -0700267 self.logger.info(self.vapi.cli("sh punt sock reg"))
268
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100269 #
270 # deregister all punt socket
271 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700272 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
273 self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
274 self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
275 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100276 self.assertEqual(len(punts), 0)
277
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100278 def test_punt_socket_traffic_single_port_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200279 """Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100280
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100281 port = self.ports[0]
Neale Ranns50f0ac02019-05-15 02:13:37 -0700282 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
283 punt_l4 = set_port(mk_vpp_cfg4(), port)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100284
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200285 p = (
286 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
287 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
288 / UDP(sport=9876, dport=port)
289 / Raw(b"\xa5" * 100)
290 )
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100291
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100292 pkts = p * self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100293
Neale Ranns50f0ac02019-05-15 02:13:37 -0700294 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100295 self.assertEqual(len(punts), 0)
296
297 #
298 # expect ICMP - port unreachable for all packets
299 #
Neale Ranns5c6dd172022-02-17 09:08:47 +0000300 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700301
302 for p in rx:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200303 self.assertEqual(int(p[IP].proto), 1) # ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -0700304 self.assertEqual(int(p[ICMP].code), 3) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100305
306 #
307 # configure a punt socket
308 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200309 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200310 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700311 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100312 self.assertEqual(len(punts), 1)
313
314 #
315 # expect punt socket and no packets on pg0
316 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700317 self.send_and_assert_no_replies(self.pg0, pkts)
318 rx = self.socket_client_close()
319 self.verify_udp_pkts(rx, len(pkts), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100320
321 #
322 # remove punt socket. expect ICMP - port unreachable for all packets
323 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700324 self.vapi.punt_socket_deregister(punt_l4)
325 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100326 self.assertEqual(len(punts), 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100327
Neale Ranns5c6dd172022-02-17 09:08:47 +0000328 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700329 for p in rx:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200330 self.assertEqual(int(p[IP].proto), 1) # ICMP
Neale Ranns50f0ac02019-05-15 02:13:37 -0700331 self.assertEqual(int(p[ICMP].code), 3) # unreachable
332
333 def test_punt_socket_traffic_multi_ports_multi_sockets(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200334 """Punt socket traffic multi ports and multi sockets"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100335
Neale Ranns50f0ac02019-05-15 02:13:37 -0700336 punt_l4 = mk_vpp_cfg4()
337
338 # configuration for each UDP port
339 cfgs = dict()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100340
341 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700342 # create stream of packets for each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100343 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700344 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100345 # choose port from port list
Neale Ranns50f0ac02019-05-15 02:13:37 -0700346 cfgs[port] = {}
347
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200348 pkt = (
349 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
350 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
351 / UDP(sport=9876, dport=port)
352 / Raw(b"\xa5" * 100)
353 )
354 cfgs[port]["pkts"] = pkt * self.nr_packets
355 cfgs[port]["port"] = port
356 cfgs[port]["vpp"] = copy.deepcopy(set_port(punt_l4, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700357
358 # configure punt sockets
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200359 cfgs[port]["sock"] = self.socket_client_create(
360 "%s/socket_%d" % (self.tempdir, port)
361 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700362 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200363 cfgs[port]["vpp"], "%s/socket_%d" % (self.tempdir, port)
364 )
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100365
366 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700367 # send the packets that get punted
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100368 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700369 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200370 self.send_and_assert_no_replies(self.pg0, cfg["pkts"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100371
372 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700373 # test that we got the excepted packets on the expected socket
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100374 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700375 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200376 rx = cfg["sock"].close()
377 self.verify_udp_pkts(rx, len(cfg["pkts"]), cfg["port"])
378 self.vapi.punt_socket_deregister(cfg["vpp"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100379
380 def test_punt_socket_traffic_multi_ports_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200381 """Punt socket traffic multi ports and single socket"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100382
Neale Ranns50f0ac02019-05-15 02:13:37 -0700383 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
384 punt_l4 = mk_vpp_cfg4()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100385
386 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700387 # create stream of packets with each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100388 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700389 pkts = []
390 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100391 # choose port from port list
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200392 pkt = (
393 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
394 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
395 / UDP(sport=9876, dport=port)
396 / Raw(b"\xa5" * 100)
397 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700398 pkts += pkt * self.nr_packets
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100399
400 #
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100401 # configure a punt socket
402 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200403 self.socket_client_create("%s/socket_multi" % self.tempdir)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100404 for p in self.ports:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200405 self.vapi.punt_socket_register(
406 set_port(punt_l4, p), "%s/socket_multi" % self.tempdir
407 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700408 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100409 self.assertEqual(len(punts), len(self.ports))
410
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100411 #
412 # expect punt socket and no packets on pg0
413 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700414 self.send_and_assert_no_replies(self.pg0, pkts)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100415 self.logger.info(self.vapi.cli("show trace"))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700416 rx = self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100417
418 for p in self.ports:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700419 self.verify_udp_pkts(rx, self.nr_packets, p)
420 self.vapi.punt_socket_deregister(set_port(punt_l4, p))
421 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100422 self.assertEqual(len(punts), 0)
423
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100424
425class TestIP6PuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200426 """Punt Socket for IPv6 UDP"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100427
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800428 @classmethod
429 def setUpClass(cls):
430 super(TestIP6PuntSocket, cls).setUpClass()
431
432 @classmethod
433 def tearDownClass(cls):
434 super(TestIP6PuntSocket, cls).tearDownClass()
435
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100436 def setUp(self):
437 super(TestIP6PuntSocket, self).setUp()
438
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100439 for i in self.pg_interfaces:
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100440 i.config_ip6()
441 i.resolve_ndp()
442
443 def tearDown(self):
444 super(TestIP6PuntSocket, self).tearDown()
445 for i in self.pg_interfaces:
446 i.unconfig_ip6()
447 i.admin_down()
448
449 def test_punt_socket_dump(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200450 """Punt socket registration"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100451
Neale Ranns50f0ac02019-05-15 02:13:37 -0700452 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
453 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
454 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
455 #
456 # configure a punt socket
457 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200458 punt_l4 = {"type": pt_l4, "punt": {"l4": {"af": af_ip6, "protocol": udp_proto}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700459
460 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100461 self.assertEqual(len(punts), 0)
462
463 #
464 # configure a punt socket
465 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200466 self.vapi.punt_socket_register(
467 set_port(punt_l4, 1111), "%s/socket_1111" % self.tempdir
468 )
469 self.vapi.punt_socket_register(
470 set_port(punt_l4, 2222), "%s/socket_2222" % self.tempdir
471 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700472 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100473 self.assertEqual(len(punts), 2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700474 self.verify_port(set_port(punt_l4, 1111), punts[0])
475 self.verify_port(set_port(punt_l4, 2222), punts[1])
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100476
477 #
478 # deregister a punt socket
479 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700480 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
481 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100482 self.assertEqual(len(punts), 1)
483
484 #
485 # configure a punt socket again
486 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200487 self.vapi.punt_socket_register(
488 set_port(punt_l4, 1111), "%s/socket_1111" % self.tempdir
489 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700490 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100491 self.assertEqual(len(punts), 2)
492
493 #
494 # deregister all punt socket
495 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700496 self.vapi.punt_socket_deregister(set_port(punt_l4, 1111))
497 self.vapi.punt_socket_deregister(set_port(punt_l4, 2222))
498 self.vapi.punt_socket_deregister(set_port(punt_l4, 3333))
499 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100500 self.assertEqual(len(punts), 0)
501
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100502 def test_punt_socket_traffic_single_port_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200503 """Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100504
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100505 port = self.ports[0]
Neale Ranns50f0ac02019-05-15 02:13:37 -0700506 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
507 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
508 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
509 punt_l4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200510 "type": pt_l4,
511 "punt": {
512 "l4": {
513 "af": af_ip6,
514 "protocol": udp_proto,
515 "port": port,
Neale Ranns50f0ac02019-05-15 02:13:37 -0700516 }
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200517 },
Neale Ranns50f0ac02019-05-15 02:13:37 -0700518 }
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100519
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200520 p = (
521 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
522 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
523 / inet6.UDP(sport=9876, dport=port)
524 / Raw(b"\xa5" * 100)
525 )
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100526
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100527 pkts = p * self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100528
Neale Ranns50f0ac02019-05-15 02:13:37 -0700529 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100530 self.assertEqual(len(punts), 0)
531
532 #
533 # expect ICMPv6 - destination unreachable for all packets
534 #
535 self.vapi.cli("clear trace")
536 self.pg0.add_stream(pkts)
537 self.pg_enable_capture(self.pg_interfaces)
538 self.pg_start()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100539 # FIXME - when punt socket deregister is implemented
540 # rx = self.pg0.get_capture(self.nr_packets)
541 # for p in rx:
542 # self.assertEqual(int(p[IPv6].nh), 58) # ICMPv6
543 # self.assertEqual(int(p[ICMPv6DestUnreach].code),4) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100544
545 #
546 # configure a punt socket
547 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200548 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200549 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700550 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100551 self.assertEqual(len(punts), 1)
552
553 #
554 # expect punt socket and no packets on pg0
555 #
556 self.vapi.cli("clear errors")
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100557 self.vapi.cli("clear trace")
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100558 self.pg0.add_stream(pkts)
559 self.pg_enable_capture(self.pg_interfaces)
560 self.pg_start()
561 self.pg0.get_capture(0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100562 self.logger.info(self.vapi.cli("show trace"))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700563 rx = self.socket_client_close()
564 self.verify_udp_pkts(rx, len(pkts), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100565
566 #
567 # remove punt socket. expect ICMP - dest. unreachable for all packets
568 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700569 self.vapi.punt_socket_deregister(punt_l4)
570 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100571 self.assertEqual(len(punts), 0)
572 self.pg0.add_stream(pkts)
573 self.pg_enable_capture(self.pg_interfaces)
574 self.pg_start()
575 # FIXME - when punt socket deregister is implemented
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100576 # self.pg0.get_capture(nr_packets)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100577
Neale Ranns50f0ac02019-05-15 02:13:37 -0700578 def test_punt_socket_traffic_multi_ports_multi_sockets(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200579 """Punt socket traffic multi ports and multi sockets"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100580
Neale Ranns50f0ac02019-05-15 02:13:37 -0700581 punt_l4 = mk_vpp_cfg6()
582
583 # configuration for each UDP port
584 cfgs = dict()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100585
586 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700587 # create stream of packets for each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100588 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700589 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100590 # choose port from port list
Neale Ranns50f0ac02019-05-15 02:13:37 -0700591 cfgs[port] = {}
592
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200593 pkt = (
594 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
595 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
596 / UDP(sport=9876, dport=port)
597 / Raw(b"\xa5" * 100)
598 )
599 cfgs[port]["pkts"] = pkt * self.nr_packets
600 cfgs[port]["port"] = port
601 cfgs[port]["vpp"] = copy.deepcopy(set_port(punt_l4, port))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700602
603 # configure punt sockets
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200604 cfgs[port]["sock"] = self.socket_client_create(
605 "%s/socket_%d" % (self.tempdir, port)
606 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700607 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200608 cfgs[port]["vpp"], "%s/socket_%d" % (self.tempdir, port)
609 )
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100610
611 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700612 # send the packets that get punted
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100613 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700614 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200615 self.send_and_assert_no_replies(self.pg0, cfg["pkts"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100616
617 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700618 # test that we got the excepted packets on the expected socket
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100619 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700620 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200621 rx = cfg["sock"].close()
622 self.verify_udp_pkts(rx, len(cfg["pkts"]), cfg["port"])
623 self.vapi.punt_socket_deregister(cfg["vpp"])
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100624
625 def test_punt_socket_traffic_multi_ports_single_socket(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200626 """Punt socket traffic multi ports and single socket"""
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100627
Neale Ranns50f0ac02019-05-15 02:13:37 -0700628 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
629 af_ip6 = VppEnum.vl_api_address_family_t.ADDRESS_IP6
630 udp_proto = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_UDP
631 punt_l4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200632 "type": pt_l4,
633 "punt": {
634 "l4": {
635 "af": af_ip6,
636 "protocol": udp_proto,
Neale Ranns50f0ac02019-05-15 02:13:37 -0700637 }
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200638 },
Neale Ranns50f0ac02019-05-15 02:13:37 -0700639 }
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100640
641 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700642 # create stream of packets with each port
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100643 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700644 pkts = []
645 for port in self.ports:
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100646 # choose port from port list
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200647 pkt = (
648 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
649 / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
650 / UDP(sport=9876, dport=port)
651 / Raw(b"\xa5" * 100)
652 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700653 pkts += pkt * self.nr_packets
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100654
655 #
656 # no punt socket
657 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700658 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100659 self.assertEqual(len(punts), 0)
660
661 #
662 # configure a punt socket
663 #
Ole Troan9cd8f332019-10-18 15:57:56 +0200664 self.socket_client_create("%s/socket_multi" % self.tempdir)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100665 for p in self.ports:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200666 self.vapi.punt_socket_register(
667 set_port(punt_l4, p), "%s/socket_multi" % self.tempdir
668 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700669 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100670 self.assertEqual(len(punts), len(self.ports))
671
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100672 #
673 # expect punt socket and no packets on pg0
674 #
675 self.vapi.cli("clear errors")
676 self.vapi.cli("clear trace")
677 self.pg0.add_stream(pkts)
678 self.pg_enable_capture(self.pg_interfaces)
679 self.pg_start()
Andrew Yourtchenkocb265c62019-07-25 10:03:51 +0000680 # give a chance to punt socket to collect all packets
681 self.sleep(1)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100682 self.pg0.get_capture(0)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700683 rx = self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100684
685 for p in self.ports:
Neale Ranns50f0ac02019-05-15 02:13:37 -0700686 self.verify_udp_pkts(rx, self.nr_packets, p)
687 self.vapi.punt_socket_deregister(set_port(punt_l4, p))
688 punts = self.vapi.punt_socket_dump(type=pt_l4)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100689 self.assertEqual(len(punts), 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100690
Neale Ranns76b56492018-09-28 15:16:14 +0000691
Neale Ranns50f0ac02019-05-15 02:13:37 -0700692class TestExceptionPuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200693 """Punt Socket for Exceptions"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700694
695 @classmethod
696 def setUpClass(cls):
697 super(TestExceptionPuntSocket, cls).setUpClass()
698
699 @classmethod
700 def tearDownClass(cls):
701 super(TestExceptionPuntSocket, cls).tearDownClass()
702
703 def setUp(self):
704 super(TestExceptionPuntSocket, self).setUp()
705
Neale Ranns12989b52019-09-26 16:20:19 +0000706 self.create_pg_interfaces(range(2))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700707 for i in self.pg_interfaces:
708 i.config_ip4()
709 i.resolve_arp()
710
711 def tearDown(self):
712 super(TestExceptionPuntSocket, self).tearDown()
713 for i in self.pg_interfaces:
714 i.unconfig_ip4()
715 i.admin_down()
716
717 def test_registration(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200718 """Punt socket registration/deregistration"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700719
720 pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION
721
722 punts = self.vapi.punt_socket_dump(type=pt_ex)
723 self.assertEqual(len(punts), 0)
724
725 #
726 # configure a punt socket
727 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200728 punt_ex = {"type": pt_ex, "punt": {"exception": {}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700729
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200730 self.vapi.punt_socket_register(
731 set_reason(punt_ex, 1), "%s/socket_punt_1" % self.tempdir
732 )
733 self.vapi.punt_socket_register(
734 set_reason(punt_ex, 2), "%s/socket_punt_2" % self.tempdir
735 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700736 punts = self.vapi.punt_socket_dump(type=pt_ex)
737 self.assertEqual(len(punts), 2)
738 self.verify_exception(set_reason(punt_ex, 1), punts[0])
739 self.verify_exception(set_reason(punt_ex, 2), punts[1])
740
741 #
742 # deregister a punt socket
743 #
744 self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
745 punts = self.vapi.punt_socket_dump(type=pt_ex)
746 self.assertEqual(len(punts), 1)
747
748 #
749 # configure a punt socket again
750 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200751 self.vapi.punt_socket_register(
752 set_reason(punt_ex, 1), "%s/socket_punt_1" % self.tempdir
753 )
754 self.vapi.punt_socket_register(
755 set_reason(punt_ex, 3), "%s/socket_punt_3" % self.tempdir
756 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700757 punts = self.vapi.punt_socket_dump(type=pt_ex)
758 self.assertEqual(len(punts), 3)
759
760 self.logger.info(self.vapi.cli("sh punt sock reg exception"))
761
762 #
763 # deregister all punt socket
764 #
765 self.vapi.punt_socket_deregister(set_reason(punt_ex, 1))
766 self.vapi.punt_socket_deregister(set_reason(punt_ex, 2))
767 self.vapi.punt_socket_deregister(set_reason(punt_ex, 3))
768 punts = self.vapi.punt_socket_dump(type=pt_ex)
769 self.assertEqual(len(punts), 0)
770
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700771 def verify_esp_pkts(self, rxs, n_sent, spi, has_udp):
Neale Ranns50f0ac02019-05-15 02:13:37 -0700772 self.assertEqual(len(rxs), n_sent)
773 for rx in rxs:
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700774 self.assertTrue(rx.haslayer(IP))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700775 self.assertTrue(rx.haslayer(ESP))
776 self.assertEqual(rx[ESP].spi, spi)
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700777 if has_udp:
778 self.assertTrue(rx.haslayer(UDP))
Neale Ranns50f0ac02019-05-15 02:13:37 -0700779
780 def test_traffic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200781 """Punt socket traffic"""
Neale Ranns50f0ac02019-05-15 02:13:37 -0700782
783 port = self.ports[0]
784 pt_ex = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_EXCEPTION
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200785 punt_ex = {"type": pt_ex, "punt": {"exception": {}}}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700786
787 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700788 # we're dealing with IPSec tunnels punting for no-such-tunnel
Filip Tehlar4362baa2020-04-02 13:13:39 +0000789 # (SPI=0 goes to ikev2)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700790 #
791 cfgs = dict()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200792 cfgs["ipsec4-no-such-tunnel"] = {"spi": 99, "udp": False, "itf": self.pg0}
Neale Ranns50f0ac02019-05-15 02:13:37 -0700793
794 #
795 # find the VPP ID for these punt exception reasin
796 #
797 rs = self.vapi.punt_reason_dump()
798 for key in cfgs:
799 for r in rs:
Jakub Grajciar2dbee932020-02-07 11:30:26 +0100800 print(r.reason.name)
801 print(key)
Neale Ranns50f0ac02019-05-15 02:13:37 -0700802 if r.reason.name == key:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200803 cfgs[key]["id"] = r.reason.id
804 cfgs[key]["vpp"] = copy.deepcopy(
805 set_reason(punt_ex, cfgs[key]["id"])
806 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700807 break
808
809 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700810 # configure punt sockets
Neale Ranns50f0ac02019-05-15 02:13:37 -0700811 #
812 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200813 cfg["sock"] = self.socket_client_create(
814 "%s/socket_%d" % (self.tempdir, cfg["id"])
815 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700816 self.vapi.punt_socket_register(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200817 cfg["vpp"], "%s/socket_%d" % (self.tempdir, cfg["id"])
818 )
Neale Ranns50f0ac02019-05-15 02:13:37 -0700819
820 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700821 # create packet streams for 'no-such-tunnel' exception
822 #
823 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200824 pkt = Ether(src=cfg["itf"].remote_mac, dst=cfg["itf"].local_mac) / IP(
825 src=cfg["itf"].remote_ip4, dst=cfg["itf"].local_ip4
826 )
827 if cfg["udp"]:
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700828 pkt = pkt / UDP(sport=666, dport=4500)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200829 pkt = pkt / ESP(spi=cfg["spi"], seq=3) / Raw(b"\xa5" * 100)
830 cfg["pkts"] = [pkt]
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700831
832 #
Neale Ranns50f0ac02019-05-15 02:13:37 -0700833 # send packets for each SPI we expect to be punted
834 #
835 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200836 self.send_and_assert_no_replies(cfg["itf"], cfg["pkts"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700837
838 #
839 # verify the punted packets arrived on the associated socket
840 #
841 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200842 rx = cfg["sock"].close()
843 self.verify_esp_pkts(rx, len(cfg["pkts"]), cfg["spi"], cfg["udp"])
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700844
845 #
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000846 # add some tunnels, make sure it still punts
847 #
Neale Rannsa9e27742020-12-23 16:22:28 +0000848 tun = VppIpsecInterface(self).add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200849 sa_in = VppIpsecSA(
850 self,
851 11,
852 11,
853 (VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96),
854 b"0123456701234567",
855 (VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128),
856 b"0123456701234567",
857 50,
858 self.pg0.local_ip4,
859 self.pg0.remote_ip4,
860 ).add_vpp_config()
861 sa_out = VppIpsecSA(
862 self,
863 22,
864 22,
865 (VppEnum.vl_api_ipsec_integ_alg_t.IPSEC_API_INTEG_ALG_SHA1_96),
866 b"0123456701234567",
867 (VppEnum.vl_api_ipsec_crypto_alg_t.IPSEC_API_CRYPTO_ALG_AES_CBC_128),
868 b"0123456701234567",
869 50,
870 self.pg0.local_ip4,
871 self.pg0.remote_ip4,
872 ).add_vpp_config()
873 protect = VppIpsecTunProtect(self, tun, sa_out, [sa_in]).add_vpp_config()
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000874
875 #
876 # send packets for each SPI we expect to be punted
877 #
878 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200879 self.send_and_assert_no_replies(cfg["itf"], cfg["pkts"])
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000880
881 #
882 # verify the punted packets arrived on the associated socket
883 #
884 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200885 rx = cfg["sock"].close()
886 self.verify_esp_pkts(rx, len(cfg["pkts"]), cfg["spi"], cfg["udp"])
Neale Ranns8d6d74c2020-02-20 09:45:16 +0000887 #
Neale Rannsa6bee0a2019-06-14 01:13:25 -0700888 # socket deregister
889 #
890 for cfg in cfgs.values():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200891 self.vapi.punt_socket_deregister(cfg["vpp"])
Neale Ranns50f0ac02019-05-15 02:13:37 -0700892
893
Neale Rannsb538dd82019-05-21 06:54:54 -0700894class TestIpProtoPuntSocket(TestPuntSocket):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200895 """Punt Socket for IP packets"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700896
897 @classmethod
898 def setUpClass(cls):
899 super(TestIpProtoPuntSocket, cls).setUpClass()
900
901 @classmethod
902 def tearDownClass(cls):
903 super(TestIpProtoPuntSocket, cls).tearDownClass()
904
905 def setUp(self):
906 super(TestIpProtoPuntSocket, self).setUp()
907
908 for i in self.pg_interfaces:
909 i.config_ip4()
910 i.resolve_arp()
911
912 def tearDown(self):
913 super(TestIpProtoPuntSocket, self).tearDown()
914 for i in self.pg_interfaces:
915 i.unconfig_ip4()
916 i.admin_down()
917
918 def test_registration(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200919 """Punt socket registration/deregistration"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700920
921 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
922 pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
923 proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF
924 proto_eigrp = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_EIGRP
925
926 punts = self.vapi.punt_socket_dump(type=pt_ip)
927 self.assertEqual(len(punts), 0)
928
929 #
930 # configure a punt socket
931 #
932 punt_ospf = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200933 "type": pt_ip,
934 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_ospf}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700935 }
936 punt_eigrp = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200937 "type": pt_ip,
938 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_eigrp}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700939 }
940
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200941 self.vapi.punt_socket_register(punt_ospf, "%s/socket_punt_1" % self.tempdir)
942 self.vapi.punt_socket_register(punt_eigrp, "%s/socket_punt_2" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -0700943 self.logger.info(self.vapi.cli("sh punt sock reg ip"))
944 punts = self.vapi.punt_socket_dump(type=pt_ip)
945 self.assertEqual(len(punts), 2)
946 self.verify_ip_proto(punt_ospf, punts[0])
947 self.verify_ip_proto(punt_eigrp, punts[1])
948
949 #
950 # deregister a punt socket
951 #
952 self.vapi.punt_socket_deregister(punt_ospf)
953 punts = self.vapi.punt_socket_dump(type=pt_ip)
954 self.assertEqual(len(punts), 1)
955
956 #
957 # configure a punt socket again
958 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200959 self.vapi.punt_socket_register(punt_ospf, "%s/socket_punt_3" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -0700960 punts = self.vapi.punt_socket_dump(type=pt_ip)
961 self.assertEqual(len(punts), 2)
962
963 self.logger.info(self.vapi.cli("sh punt sock reg exception"))
964
965 #
966 # deregister all punt socket
967 #
968 self.vapi.punt_socket_deregister(punt_eigrp)
969 self.vapi.punt_socket_deregister(punt_ospf)
970 punts = self.vapi.punt_socket_dump(type=pt_ip)
971 self.assertEqual(len(punts), 0)
972
973 def verify_ospf_pkts(self, rxs, n_sent):
974 self.assertEqual(len(rxs), n_sent)
975 for rx in rxs:
976 self.assertTrue(rx.haslayer(OSPF_Hdr))
977
978 def test_traffic(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200979 """Punt socket traffic"""
Neale Rannsb538dd82019-05-21 06:54:54 -0700980
981 af_ip4 = VppEnum.vl_api_address_family_t.ADDRESS_IP4
982 pt_ip = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_IP_PROTO
983 proto_ospf = VppEnum.vl_api_ip_proto_t.IP_API_PROTO_OSPF
984
985 #
986 # configure a punt socket to capture OSPF packets
987 #
988 punt_ospf = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200989 "type": pt_ip,
990 "punt": {"ip_proto": {"af": af_ip4, "protocol": proto_ospf}},
Neale Rannsb538dd82019-05-21 06:54:54 -0700991 }
992
993 #
994 # create packet streams and configure a punt sockets
995 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200996 pkt = (
997 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
998 / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
999 / OSPF_Hdr()
1000 / OSPFv3_Hello()
1001 )
Neale Rannsb538dd82019-05-21 06:54:54 -07001002 pkts = pkt * 7
1003
Ole Troan9cd8f332019-10-18 15:57:56 +02001004 sock = self.socket_client_create("%s/socket_1" % self.tempdir)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001005 self.vapi.punt_socket_register(punt_ospf, "%s/socket_1" % self.tempdir)
Neale Rannsb538dd82019-05-21 06:54:54 -07001006
1007 #
1008 # send packets for each SPI we expect to be punted
1009 #
1010 self.send_and_assert_no_replies(self.pg0, pkts)
1011
1012 #
1013 # verify the punted packets arrived on the associated socket
1014 #
1015 rx = sock.close()
1016 self.verify_ospf_pkts(rx, len(pkts))
1017 self.vapi.punt_socket_deregister(punt_ospf)
1018
1019
Andrew Yourtchenkofeb77422023-03-17 01:47:58 +00001020class TestDot1QPuntSocket(TestPuntSocket):
1021 """Punt Socket for 802.1Q (dot1q)"""
1022
1023 def setUp(self):
1024 super(TestDot1QPuntSocket, self).setUp()
1025
1026 for i in self.pg_interfaces:
1027 i.admin_up()
1028 i.config_ip4()
1029 i.resolve_arp()
1030
1031 def tearDown(self):
1032 super(TestDot1QPuntSocket, self).tearDown()
1033 for i in self.pg_interfaces:
1034 i.unconfig_ip4()
1035 i.admin_down()
1036
1037 def test_dot1q_header_punt(self):
1038 """Punt socket traffic with Dot1q header"""
1039
1040 port = self.ports[0]
1041 pt_l4 = VppEnum.vl_api_punt_type_t.PUNT_API_TYPE_L4
1042 punt_l4 = set_port(mk_vpp_cfg4(), port)
1043
1044 # VLAN ID
1045 vlan_id = 100
1046
1047 # Create a subinterface with the VLAN ID
1048 subif = VppDot1QSubint(self, self.pg0, vlan_id)
1049 subif.admin_up()
1050 subif.config_ip4()
1051
1052 # Configure an IP address on the subinterface
1053 subif_ip4 = subif.local_ip4
1054
1055 p = (
1056 Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
1057 / Dot1Q(vlan=vlan_id)
1058 / IP(src=self.pg0.remote_ip4, dst=subif_ip4)
1059 / UDP(sport=9876, dport=port)
1060 / Raw(b"\xa5" * 100)
1061 )
1062
1063 pkts = p * self.nr_packets
1064
1065 # Expect ICMP - port unreachable for all packets
1066 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
1067
1068 for p in rx:
1069 self.assertEqual(int(p[IP].proto), 1) # ICMP
1070 self.assertEqual(int(p[ICMP].code), 3) # unreachable
1071
1072 # Configure a punt socket
1073 self.socket_client_create("%s/socket_%d" % (self.tempdir, port))
1074 self.vapi.punt_socket_register(punt_l4, "%s/socket_%d" % (self.tempdir, port))
1075 punts = self.vapi.punt_socket_dump(type=pt_l4)
1076 self.assertEqual(len(punts), 1)
1077
1078 # Expect punt socket and no packets on pg0
1079 self.send_and_assert_no_replies(self.pg0, pkts)
1080 rx = self.socket_client_close()
1081 self.logger.info("RXPKT")
1082 self.logger.info(rx)
1083 self.verify_udp_pkts(rx, len(pkts), port)
1084 for pkt in rx:
1085 self.assertEqual(pkt[Ether].src, self.pg0.remote_mac)
1086 self.assertEqual(pkt[Ether].dst, self.pg0.local_mac)
1087 self.assertEqual(pkt[Dot1Q].vlan, 100)
1088
1089 # Remove punt socket. Expect ICMP - port unreachable for all packets
1090 self.vapi.punt_socket_deregister(punt_l4)
1091 punts = self.vapi.punt_socket_dump(type=pt_l4)
1092 self.assertEqual(len(punts), 0)
1093
1094 rx = self.send_and_expect_some(self.pg0, pkts, self.pg0)
1095 for p in rx:
1096 self.assertEqual(int(p[IP].proto), 1) # ICMP
1097 self.assertEqual(int(p[ICMP].code), 3) # unreachable
1098
1099
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001100@tag_fixme_vpp_workers
Neale Ranns76b56492018-09-28 15:16:14 +00001101class TestPunt(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001102 """Exception Punt Test Case"""
Neale Ranns76b56492018-09-28 15:16:14 +00001103
1104 @classmethod
1105 def setUpClass(cls):
1106 super(TestPunt, cls).setUpClass()
1107
1108 @classmethod
1109 def tearDownClass(cls):
1110 super(TestPunt, cls).tearDownClass()
1111
1112 def setUp(self):
1113 super(TestPunt, self).setUp()
1114
1115 self.create_pg_interfaces(range(4))
1116
1117 for i in self.pg_interfaces:
1118 i.admin_up()
1119 i.config_ip4()
1120 i.resolve_arp()
1121 i.config_ip6()
1122 i.resolve_ndp()
1123
1124 def tearDown(self):
1125 for i in self.pg_interfaces:
1126 i.unconfig_ip4()
1127 i.unconfig_ip6()
Neale Ranns76b56492018-09-28 15:16:14 +00001128 i.admin_down()
1129 super(TestPunt, self).tearDown()
1130
1131 def test_punt(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001132 """Exception Path testing"""
Neale Ranns76b56492018-09-28 15:16:14 +00001133
1134 #
Neale Ranns719beb72019-07-10 07:10:25 +00001135 # dump the punt registered reasons
1136 # search for a few we know should be there
1137 #
1138 rs = self.vapi.punt_reason_dump()
1139
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001140 reasons = [
1141 "ipsec6-no-such-tunnel",
1142 "ipsec4-no-such-tunnel",
1143 "ipsec4-spi-o-udp-0",
1144 ]
Neale Ranns719beb72019-07-10 07:10:25 +00001145
1146 for reason in reasons:
1147 found = False
1148 for r in rs:
1149 if r.reason.name == reason:
1150 found = True
1151 break
1152 self.assertTrue(found)
1153
1154 #
Neale Ranns76b56492018-09-28 15:16:14 +00001155 # Using the test CLI we will hook in a exception path to
1156 # send ACL deny packets out of pg0 and pg1.
1157 # the ACL is src,dst = 1.1.1.1,1.1.1.2
1158 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001159 ip_1_1_1_2 = VppIpRoute(
1160 self,
1161 "1.1.1.2",
1162 32,
1163 [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)],
1164 )
Neale Ranns76b56492018-09-28 15:16:14 +00001165 ip_1_1_1_2.add_vpp_config()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001166 ip_1_2 = VppIpRoute(
1167 self,
1168 "1::2",
1169 128,
1170 [
1171 VppRoutePath(
1172 self.pg3.remote_ip6,
1173 self.pg3.sw_if_index,
1174 proto=DpoProto.DPO_PROTO_IP6,
1175 )
1176 ],
1177 )
Neale Ranns76b56492018-09-28 15:16:14 +00001178 ip_1_2.add_vpp_config()
1179
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001180 p4 = (
1181 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
1182 / IP(src="1.1.1.1", dst="1.1.1.2")
1183 / UDP(sport=1234, dport=1234)
1184 / Raw(b"\xa5" * 100)
1185 )
1186 p6 = (
1187 Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
1188 / IPv6(src="1::1", dst="1::2")
1189 / UDP(sport=1234, dport=1234)
1190 / Raw(b"\xa5" * 100)
1191 )
1192 self.send_and_expect(self.pg2, p4 * 1, self.pg3)
1193 self.send_and_expect(self.pg2, p6 * 1, self.pg3)
Neale Ranns76b56492018-09-28 15:16:14 +00001194
1195 #
1196 # apply the punting features
1197 #
1198 self.vapi.cli("test punt pg2")
1199
1200 #
Neale Ranns719beb72019-07-10 07:10:25 +00001201 # dump the punt reasons to learn the IDs assigned
1202 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001203 rs = self.vapi.punt_reason_dump(reason={"name": "reason-v4"})
Neale Ranns719beb72019-07-10 07:10:25 +00001204 r4 = rs[0].reason.id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001205 rs = self.vapi.punt_reason_dump(reason={"name": "reason-v6"})
Neale Ranns719beb72019-07-10 07:10:25 +00001206 r6 = rs[0].reason.id
1207
1208 #
Neale Ranns76b56492018-09-28 15:16:14 +00001209 # pkts now dropped
1210 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001211 self.send_and_assert_no_replies(self.pg2, p4 * NUM_PKTS)
1212 self.send_and_assert_no_replies(self.pg2, p6 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001213
1214 #
1215 # Check state:
1216 # 1 - node error counters
1217 # 2 - per-reason counters
1218 # 2, 3 are the index of the assigned punt reason
1219 #
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001220 stats = self.statistics.get_err_counter("/err/punt-dispatch/No registrations")
1221 self.assertEqual(stats, 2 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001222
1223 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001224 self.assertEqual(stats[0][r4]["packets"], NUM_PKTS)
1225 self.assertEqual(stats[0][r6]["packets"], NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001226
1227 #
1228 # use the test CLI to test a client that punts exception
1229 # packets out of pg0
1230 #
1231 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip4)
1232 self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip6)
1233
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001234 rx4s = self.send_and_expect(self.pg2, p4 * NUM_PKTS, self.pg0)
1235 rx6s = self.send_and_expect(self.pg2, p6 * NUM_PKTS, self.pg0)
Neale Ranns76b56492018-09-28 15:16:14 +00001236
1237 #
1238 # check the packets come out IP unmodified but destined to pg0 host
1239 #
1240 for rx in rx4s:
1241 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1242 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1243 self.assertEqual(p4[IP].dst, rx[IP].dst)
1244 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
1245 for rx in rx6s:
1246 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1247 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1248 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1249 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
1250
1251 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001252 self.assertEqual(stats[0][r4]["packets"], 2 * NUM_PKTS)
1253 self.assertEqual(stats[0][r6]["packets"], 2 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001254
1255 #
1256 # add another registration for the same reason to send packets
1257 # out of pg1
1258 #
1259 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip4)
1260 self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip6)
1261
1262 self.vapi.cli("clear trace")
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001263 self.pg2.add_stream(p4 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001264 self.pg_enable_capture(self.pg_interfaces)
1265 self.pg_start()
1266
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001267 rxd = self.pg0.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001268 for rx in rxd:
1269 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1270 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1271 self.assertEqual(p4[IP].dst, rx[IP].dst)
1272 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001273 rxd = self.pg1.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001274 for rx in rxd:
1275 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
1276 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
1277 self.assertEqual(p4[IP].dst, rx[IP].dst)
1278 self.assertEqual(p4[IP].ttl, rx[IP].ttl)
1279
1280 self.vapi.cli("clear trace")
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001281 self.pg2.add_stream(p6 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001282 self.pg_enable_capture(self.pg_interfaces)
1283 self.pg_start()
1284
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001285 rxd = self.pg0.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001286 for rx in rxd:
1287 self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
1288 self.assertEqual(rx[Ether].src, self.pg0.local_mac)
1289 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1290 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
Paul Vinciguerra4271c972019-05-14 13:25:49 -04001291 rxd = self.pg1.get_capture(NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001292 for rx in rxd:
1293 self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
1294 self.assertEqual(rx[Ether].src, self.pg1.local_mac)
1295 self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
1296 self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
1297
1298 stats = self.statistics.get_counter("/net/punt")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001299 self.assertEqual(stats[0][r4]["packets"], 3 * NUM_PKTS)
1300 self.assertEqual(stats[0][r6]["packets"], 3 * NUM_PKTS)
Neale Ranns76b56492018-09-28 15:16:14 +00001301
1302 self.logger.info(self.vapi.cli("show vlib graph punt-dispatch"))
1303 self.logger.info(self.vapi.cli("show punt client"))
1304 self.logger.info(self.vapi.cli("show punt reason"))
1305 self.logger.info(self.vapi.cli("show punt stats"))
1306 self.logger.info(self.vapi.cli("show punt db"))
1307
Neale Ranns76b56492018-09-28 15:16:14 +00001308
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001309if __name__ == "__main__":
Pavel Kotuceke88865d2018-11-28 07:42:11 +01001310 unittest.main(testRunner=VppTestRunner)