blob: 74dc923365c45d361ad5a960ff634bf67a39e185 [file] [log] [blame]
Pavel Kotuceke88865d2018-11-28 07:42:11 +01001#!/usr/bin/env python
2import 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
Pavel Kotucek9edb83a2018-12-11 16:57:25 +01008from struct import unpack, unpack_from
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -08009
10try:
11 import unittest2 as unittest
12except ImportError:
13 import unittest
14
Pavel Kotuceke88865d2018-11-28 07:42:11 +010015from util import ppp, ppc
16from re import compile
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070017import scapy.compat
Pavel Kotuceke88865d2018-11-28 07:42:11 +010018from scapy.packet import Raw
19from scapy.layers.l2 import Ether
20from scapy.layers.inet import IP, UDP, ICMP
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -080021import scapy.layers.inet6 as inet6
Pavel Kotuceke88865d2018-11-28 07:42:11 +010022from scapy.layers.inet6 import IPv6, ICMPv6DestUnreach
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -080023import six
Pavel Kotuceke88865d2018-11-28 07:42:11 +010024from framework import VppTestCase, VppTestRunner
25
26
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010027# Format MAC Address
28def get_mac_addr(bytes_addr):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070029 return ':'.join('%02x' % scapy.compat.orb(b) for b in bytes_addr)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010030
31
32# Format IP Address
33def ipv4(bytes_addr):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070034 return '.'.join('%d' % scapy.compat.orb(b) for b in bytes_addr)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +010035
36
37# Unpack Ethernet Frame
38def ethernet_frame(data):
39 dest_mac, src_mac, proto = struct.unpack('! 6s 6s H', data[:14])
40 return dest_mac, src_mac, socket.htons(proto), data[14:]
41
42
43# Unpack IPv4 Packets
44def ipv4_packet(data):
45 proto, src, target = struct.unpack('! 8x 1x B 2x 4s 4s', data[:20])
46 return proto, src, target, data[20:]
47
48
49# Unpack IPv6 Packets
50def ipv6_packet(data):
51 nh, src, target = struct.unpack('! 6x B 1x 16s 16s', data[:40])
52 return nh, src, target, data[40:]
53
54
55# Unpacks any UDP Packet
56def udp_seg(data):
57 src_port, dest_port, size = struct.unpack('! H H 2x H', data[:8])
58 return src_port, dest_port, size, data[8:]
59
60
61# Unpacks any TCP Packet
62def tcp_seg(data):
63 src_port, dest_port, seq, flag = struct.unpack('! H H L 4x H', data[:14])
64 return src_port, dest_port, seq, data[((flag >> 12) * 4):]
65
66
67def receivePackets(sock, counters):
68 # Wait for some packets on socket
69 while True:
70 data = sock.recv(65536)
71
72 # punt socket metadata
73 # packet_desc = data[0:8]
74
75 # Ethernet
76 _, _, eth_proto, data = ethernet_frame(data[8:])
77 # Ipv4
78 if eth_proto == 8:
79 proto, _, _, data = ipv4_packet(data)
80 # TCP
81 if proto == 6:
82 _, dst_port, _, data = udp_seg(data)
83 # UDP
84 elif proto == 17:
85 _, dst_port, _, data = udp_seg(data)
86 counters[dst_port] = 0
87 # Ipv6
88 elif eth_proto == 0xdd86:
89 nh, _, _, data = ipv6_packet(data)
90 # TCP
91 if nh == 6:
92 _, dst_port, _, data = udp_seg(data)
93 # UDP
94 elif nh == 17:
95 _, dst_port, _, data = udp_seg(data)
96 counters[dst_port] = 0
97
98
99class serverSocketThread(threading.Thread):
100 """ Socket server thread"""
101
102 def __init__(self, threadID, sockName, counters):
103 threading.Thread.__init__(self)
104 self.threadID = threadID
105 self.sockName = sockName
106 self.sock = None
107 self.counters = counters
108
109 def run(self):
110 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
111 try:
112 os.unlink(self.sockName)
113 except:
114 pass
115 self.sock.bind(self.sockName)
116
117 receivePackets(self.sock, self.counters)
118
119
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100120class TestPuntSocket(VppTestCase):
121 """ Punt Socket """
122
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100123 ports = [1111, 2222, 3333, 4444]
124 sock_servers = list()
125 portsCheck = dict()
126 nr_packets = 256
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100127
128 @classmethod
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800129 def setUpClass(cls):
130 super(TestPuntSocket, cls).setUpClass()
131
132 @classmethod
133 def tearDownClass(cls):
134 super(TestPuntSocket, cls).tearDownClass()
135
136 @classmethod
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100137 def setUpConstants(cls):
Ole Troana45dc072018-12-21 16:04:22 +0100138 cls.extra_vpp_punt_config = [
139 "punt", "{", "socket", cls.tempdir+"/socket_punt", "}"]
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100140 super(TestPuntSocket, cls).setUpConstants()
141
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100142 def setUp(self):
143 super(TestPuntSocket, self).setUp()
144 random.seed()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100145
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100146 self.create_pg_interfaces(range(2))
147 for i in self.pg_interfaces:
148 i.admin_up()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100149
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100150 def tearDown(self):
151 del self.sock_servers[:]
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800152 super(TestPuntSocket, self).tearDown()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100153
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100154 def socket_client_create(self, sock_name, id=None):
155 thread = serverSocketThread(id, sock_name, self.portsCheck)
156 self.sock_servers.append(thread)
157 thread.start()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100158
159 def socket_client_close(self):
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100160 for thread in self.sock_servers:
161 thread.sock.close()
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100162
163
164class TestIP4PuntSocket(TestPuntSocket):
165 """ Punt Socket for IPv4 """
166
Paul Vinciguerra8d991d92019-01-25 14:05:48 -0800167 @classmethod
168 def setUpClass(cls):
169 super(TestIP4PuntSocket, cls).setUpClass()
170
171 @classmethod
172 def tearDownClass(cls):
173 super(TestIP4PuntSocket, cls).tearDownClass()
174
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100175 def setUp(self):
176 super(TestIP4PuntSocket, self).setUp()
177
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100178 for i in self.pg_interfaces:
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100179 i.config_ip4()
180 i.resolve_arp()
181
182 def tearDown(self):
183 super(TestIP4PuntSocket, self).tearDown()
184 for i in self.pg_interfaces:
185 i.unconfig_ip4()
186 i.admin_down()
187
188 def test_punt_socket_dump(self):
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100189 """ Punt socket registration/deregistration"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100190
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100191 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100192 self.assertEqual(len(punts), 0)
193
194 #
195 # configure a punt socket
196 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800197 self.vapi.punt_socket_register(1111, b"%s/socket_punt_1111" %
198 six.ensure_binary(self.tempdir))
199 self.vapi.punt_socket_register(2222, b"%s/socket_punt_2222" %
200 six.ensure_binary(self.tempdir))
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100201 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100202 self.assertEqual(len(punts), 2)
203 self.assertEqual(punts[0].punt.l4_port, 1111)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100204 self.assertEqual(punts[1].punt.l4_port, 2222)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100205
206 #
207 # deregister a punt socket
208 #
209 self.vapi.punt_socket_deregister(1111)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100210 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100211 self.assertEqual(len(punts), 1)
212
213 #
214 # configure a punt socket again
215 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800216 self.vapi.punt_socket_register(1111, b"%s/socket_punt_1111" %
217 six.ensure_binary(self.tempdir))
218 self.vapi.punt_socket_register(3333, b"%s/socket_punt_3333" %
219 six.ensure_binary(self.tempdir))
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100220 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100221 self.assertEqual(len(punts), 3)
222
223 #
224 # deregister all punt socket
225 #
226 self.vapi.punt_socket_deregister(1111)
227 self.vapi.punt_socket_deregister(2222)
228 self.vapi.punt_socket_deregister(3333)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100229 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100230 self.assertEqual(len(punts), 0)
231
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100232 def test_punt_socket_traffic_single_port_single_socket(self):
233 """ Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100234
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100235 port = self.ports[0]
236
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100237 p = (Ether(src=self.pg0.remote_mac,
238 dst=self.pg0.local_mac) /
239 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100240 UDP(sport=9876, dport=port) /
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100241 Raw('\xa5' * 100))
242
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100243 pkts = p * self.nr_packets
244 self.portsCheck[port] = self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100245
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100246 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100247 self.assertEqual(len(punts), 0)
248
249 #
250 # expect ICMP - port unreachable for all packets
251 #
252 self.vapi.cli("clear trace")
253 self.pg0.add_stream(pkts)
254 self.pg_enable_capture(self.pg_interfaces)
255 self.pg_start()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100256 # FIXME - when punt socket deregister is implemented
257 # rx = self.pg0.get_capture(self.nr_packets)
258 # for p in rx:
259 # self.assertEqual(int(p[IP].proto), 1) # ICMP
260 # self.assertEqual(int(p[ICMP].code), 3) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100261
262 #
263 # configure a punt socket
264 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800265 self.socket_client_create(b"%s/socket_%d" % (
266 six.ensure_binary(self.tempdir), port))
267 self.vapi.punt_socket_register(port, b"%s/socket_%d" % (
268 six.ensure_binary(self.tempdir), port))
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100269 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100270 self.assertEqual(len(punts), 1)
271
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100272 self.logger.debug("Sending %s packets to port %d",
273 str(self.portsCheck[port]), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100274 #
275 # expect punt socket and no packets on pg0
276 #
277 self.vapi.cli("clear errors")
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100278 self.vapi.cli("clear trace")
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100279 self.pg0.add_stream(pkts)
280 self.pg_enable_capture(self.pg_interfaces)
281 self.pg_start()
282 self.pg0.get_capture(0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100283 self.logger.info(self.vapi.cli("show trace"))
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100284 self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100285 self.assertEqual(self.portsCheck[port], 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100286
287 #
288 # remove punt socket. expect ICMP - port unreachable for all packets
289 #
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100290 self.vapi.punt_socket_deregister(port)
291 punts = self.vapi.punt_socket_dump(is_ip6=0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100292 self.assertEqual(len(punts), 0)
293 self.pg0.add_stream(pkts)
294 self.pg_enable_capture(self.pg_interfaces)
295 self.pg_start()
296 # FIXME - when punt socket deregister is implemented
297 # self.pg0.get_capture(nr_packets)
298
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100299 def test_punt_socket_traffic_multi_port_multi_sockets(self):
300 """ Punt socket traffic multi ports and multi sockets"""
301
302 for p in self.ports:
303 self.portsCheck[p] = 0
304
305 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700306 # create stream with random packets count per given ports
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100307 #
308 pkts = list()
309 for _ in range(0, self.nr_packets):
310 # choose port from port list
311 p = random.choice(self.ports)
312 pkts.append((
313 Ether(src=self.pg0.remote_mac,
314 dst=self.pg0.local_mac) /
315 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
316 UDP(sport=9876, dport=p) /
317 Raw('\xa5' * 100)))
318 self.portsCheck[p] += 1
319 #
320 # no punt socket
321 #
322 punts = self.vapi.punt_socket_dump(is_ip6=0)
323 self.assertEqual(len(punts), 0)
324
325 #
326 # configure a punt socket
327 #
328 for p in self.ports:
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800329 self.socket_client_create(b"%s/socket_%d" % (
330 six.ensure_binary(self.tempdir), p))
331 self.vapi.punt_socket_register(p, b"%s/socket_%d" % (
332 six.ensure_binary(self.tempdir), p))
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100333 punts = self.vapi.punt_socket_dump(is_ip6=0)
334 self.assertEqual(len(punts), len(self.ports))
335
336 for p in self.ports:
337 self.logger.debug("Sending %s packets to port %d",
338 str(self.portsCheck[p]), p)
339
340 #
341 # expect punt socket and no packets on pg0
342 #
343 self.vapi.cli("clear errors")
344 self.vapi.cli("clear trace")
345 self.pg0.add_stream(pkts)
346 self.pg_enable_capture(self.pg_interfaces)
347 self.pg_start()
348 self.pg0.get_capture(0)
349 self.logger.info(self.vapi.cli("show trace"))
350 self.socket_client_close()
351
352 for p in self.ports:
353 self.assertEqual(self.portsCheck[p], 0)
354 self.vapi.punt_socket_deregister(p)
355 punts = self.vapi.punt_socket_dump(is_ip6=0)
356 self.assertEqual(len(punts), 0)
357
358 def test_punt_socket_traffic_multi_ports_single_socket(self):
359 """ Punt socket traffic multi ports and single socket"""
360
361 for p in self.ports:
362 self.portsCheck[p] = 0
363
364 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700365 # create stream with random packets count per given ports
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100366 #
367 pkts = list()
368 for _ in range(0, self.nr_packets):
369 # choose port from port list
370 p = random.choice(self.ports)
371 pkts.append((
372 Ether(src=self.pg0.remote_mac,
373 dst=self.pg0.local_mac) /
374 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
375 UDP(sport=9876, dport=p) /
376 Raw('\xa5' * 100)))
377 self.portsCheck[p] += 1
378
379 #
380 # no punt socket
381 #
382 punts = self.vapi.punt_socket_dump(is_ip6=0)
383 self.assertEqual(len(punts), 0)
384
385 # configure a punt socket
386 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800387 self.socket_client_create(b"%s/socket_multi" %
388 six.ensure_binary(self.tempdir))
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100389 for p in self.ports:
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800390 self.vapi.punt_socket_register(p,
391 b"%s/socket_multi" %
392 six.ensure_binary(self.tempdir))
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100393 punts = self.vapi.punt_socket_dump(is_ip6=0)
394 self.assertEqual(len(punts), len(self.ports))
395
396 for p in self.ports:
397 self.logger.debug("Sending %s packets to port %d",
398 str(self.portsCheck[p]), p)
399 #
400 # expect punt socket and no packets on pg0
401 #
402 self.vapi.cli("clear errors")
403 self.vapi.cli("clear trace")
404 self.pg0.add_stream(pkts)
405 self.pg_enable_capture(self.pg_interfaces)
406 self.pg_start()
407 self.pg0.get_capture(0)
408 self.logger.info(self.vapi.cli("show trace"))
409 self.socket_client_close()
410
411 for p in self.ports:
412 self.assertEqual(self.portsCheck[p], 0)
413 self.vapi.punt_socket_deregister(p)
414 punts = self.vapi.punt_socket_dump(is_ip6=0)
415 self.assertEqual(len(punts), 0)
416
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100417
418class TestIP6PuntSocket(TestPuntSocket):
419 """ Punt Socket for IPv6"""
420
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):
443 """ Punt socket registration """
444
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100445 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100446 self.assertEqual(len(punts), 0)
447
448 #
449 # configure a punt socket
450 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800451 self.vapi.punt_socket_register(1111, b"%s/socket_1111" %
452 six.ensure_binary(self.tempdir),
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100453 is_ip4=0)
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800454 self.vapi.punt_socket_register(2222, b"%s/socket_2222" %
455 six.ensure_binary(self.tempdir),
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100456 is_ip4=0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100457 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100458 self.assertEqual(len(punts), 2)
459 self.assertEqual(punts[0].punt.l4_port, 1111)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100460 self.assertEqual(punts[1].punt.l4_port, 2222)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100461
462 #
463 # deregister a punt socket
464 #
465 self.vapi.punt_socket_deregister(1111, is_ip4=0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100466 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100467 self.assertEqual(len(punts), 1)
468
469 #
470 # configure a punt socket again
471 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800472 self.vapi.punt_socket_register(1111, b"%s/socket_1111" %
473 six.ensure_binary(self.tempdir),
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100474 is_ip4=0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100475 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100476 self.assertEqual(len(punts), 2)
477
478 #
479 # deregister all punt socket
480 #
481 self.vapi.punt_socket_deregister(1111, is_ip4=0)
482 self.vapi.punt_socket_deregister(2222, is_ip4=0)
483 self.vapi.punt_socket_deregister(3333, is_ip4=0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100484 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100485 self.assertEqual(len(punts), 0)
486
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100487 def test_punt_socket_traffic_single_port_single_socket(self):
488 """ Punt socket traffic single port single socket"""
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100489
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100490 port = self.ports[0]
491
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100492 p = (Ether(src=self.pg0.remote_mac,
493 dst=self.pg0.local_mac) /
494 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100495 inet6.UDP(sport=9876, dport=port) /
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100496 Raw('\xa5' * 100))
497
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100498 pkts = p * self.nr_packets
499 self.portsCheck[port] = self.nr_packets
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100500
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100501 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100502 self.assertEqual(len(punts), 0)
503
504 #
505 # expect ICMPv6 - destination unreachable for all packets
506 #
507 self.vapi.cli("clear trace")
508 self.pg0.add_stream(pkts)
509 self.pg_enable_capture(self.pg_interfaces)
510 self.pg_start()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100511 # FIXME - when punt socket deregister is implemented
512 # rx = self.pg0.get_capture(self.nr_packets)
513 # for p in rx:
514 # self.assertEqual(int(p[IPv6].nh), 58) # ICMPv6
515 # self.assertEqual(int(p[ICMPv6DestUnreach].code),4) # unreachable
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100516
517 #
518 # configure a punt socket
519 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800520 self.socket_client_create(b"%s/socket_%d" % (
521 six.ensure_binary(self.tempdir), port))
522 self.vapi.punt_socket_register(port, b"%s/socket_%d" % (
523 six.ensure_binary(self.tempdir), port), is_ip4=0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100524 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100525 self.assertEqual(len(punts), 1)
526
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100527 self.logger.debug("Sending %s packets to port %d",
528 str(self.portsCheck[port]), port)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100529 #
530 # expect punt socket and no packets on pg0
531 #
532 self.vapi.cli("clear errors")
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100533 self.vapi.cli("clear trace")
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100534 self.pg0.add_stream(pkts)
535 self.pg_enable_capture(self.pg_interfaces)
536 self.pg_start()
537 self.pg0.get_capture(0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100538 self.logger.info(self.vapi.cli("show trace"))
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100539 self.socket_client_close()
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100540 self.assertEqual(self.portsCheck[port], 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100541
542 #
543 # remove punt socket. expect ICMP - dest. unreachable for all packets
544 #
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100545 self.vapi.punt_socket_deregister(port, is_ip4=0)
546 punts = self.vapi.punt_socket_dump(is_ip6=1)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100547 self.assertEqual(len(punts), 0)
548 self.pg0.add_stream(pkts)
549 self.pg_enable_capture(self.pg_interfaces)
550 self.pg_start()
551 # FIXME - when punt socket deregister is implemented
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100552 # self.pg0.get_capture(nr_packets)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100553
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100554 def test_punt_socket_traffic_multi_port_multi_sockets(self):
555 """ Punt socket traffic multi ports and multi sockets"""
556
557 for p in self.ports:
558 self.portsCheck[p] = 0
559
560 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700561 # create stream with random packets count per given ports
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100562 #
563 pkts = list()
564 for _ in range(0, self.nr_packets):
565 # choose port from port list
566 p = random.choice(self.ports)
567 pkts.append((
568 Ether(src=self.pg0.remote_mac,
569 dst=self.pg0.local_mac) /
570 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
571 inet6.UDP(sport=9876, dport=p) /
572 Raw('\xa5' * 100)))
573 self.portsCheck[p] += 1
574 #
575 # no punt socket
576 #
577 punts = self.vapi.punt_socket_dump(is_ip6=1)
578 self.assertEqual(len(punts), 0)
579
580 #
581 # configure a punt socket
582 #
583 for p in self.ports:
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800584 self.socket_client_create(b"%s/socket_%d" % (
585 six.ensure_binary(self.tempdir), p))
586 self.vapi.punt_socket_register(p, b"%s/socket_%d" % (
587 six.ensure_binary(self.tempdir), p), is_ip4=0)
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100588 punts = self.vapi.punt_socket_dump(is_ip6=1)
589 self.assertEqual(len(punts), len(self.ports))
590
591 for p in self.ports:
592 self.logger.debug("Sending %s packets to port %d",
593 str(self.portsCheck[p]), p)
594
595 #
596 # expect punt socket and no packets on pg0
597 #
598 self.vapi.cli("clear errors")
599 self.vapi.cli("clear trace")
600 self.pg0.add_stream(pkts)
601 self.pg_enable_capture(self.pg_interfaces)
602 self.pg_start()
603 self.pg0.get_capture(0)
604 self.logger.info(self.vapi.cli("show trace"))
605 self.socket_client_close()
606
607 for p in self.ports:
608 self.assertEqual(self.portsCheck[p], 0)
609 self.vapi.punt_socket_deregister(p, is_ip4=0)
610 punts = self.vapi.punt_socket_dump(is_ip6=1)
611 self.assertEqual(len(punts), 0)
612
613 def test_punt_socket_traffic_multi_ports_single_socket(self):
614 """ Punt socket traffic multi ports and single socket"""
615
616 for p in self.ports:
617 self.portsCheck[p] = 0
618
619 #
Paul Vinciguerra8feeaff2019-03-27 11:25:48 -0700620 # create stream with random packets count per given ports
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100621 #
622 pkts = list()
623 for _ in range(0, self.nr_packets):
624 # choose port from port list
625 p = random.choice(self.ports)
626 pkts.append((
627 Ether(src=self.pg0.remote_mac,
628 dst=self.pg0.local_mac) /
629 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
630 inet6.UDP(sport=9876, dport=p) /
631 Raw('\xa5' * 100)))
632 self.portsCheck[p] += 1
633
634 #
635 # no punt socket
636 #
637 punts = self.vapi.punt_socket_dump(is_ip6=1)
638 self.assertEqual(len(punts), 0)
639
640 #
641 # configure a punt socket
642 #
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800643 self.socket_client_create(b"%s/socket_multi" %
644 six.ensure_binary(self.tempdir))
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100645 for p in self.ports:
Paul Vinciguerra22ab6f72019-03-07 17:55:33 -0800646 self.vapi.punt_socket_register(p,
647 b"%s/socket_multi" %
648 six.ensure_binary(self.tempdir),
Pavel Kotucek9edb83a2018-12-11 16:57:25 +0100649 is_ip4=0)
650 punts = self.vapi.punt_socket_dump(is_ip6=1)
651 self.assertEqual(len(punts), len(self.ports))
652
653 for p in self.ports:
654 self.logger.debug("Send %s packets to port %d",
655 str(self.portsCheck[p]), p)
656 #
657 # expect punt socket and no packets on pg0
658 #
659 self.vapi.cli("clear errors")
660 self.vapi.cli("clear trace")
661 self.pg0.add_stream(pkts)
662 self.pg_enable_capture(self.pg_interfaces)
663 self.pg_start()
664 self.pg0.get_capture(0)
665 self.logger.info(self.vapi.cli("show trace"))
666 self.socket_client_close()
667
668 for p in self.ports:
669 self.assertEqual(self.portsCheck[p], 0)
670 self.vapi.punt_socket_deregister(p, is_ip4=0)
671 punts = self.vapi.punt_socket_dump(is_ip6=1)
672 self.assertEqual(len(punts), 0)
Pavel Kotuceke88865d2018-11-28 07:42:11 +0100673
674if __name__ == '__main__':
675 unittest.main(testRunner=VppTestRunner)