blob: 57005f793559ea93de5c77b975cc2adbd5571a1e [file] [log] [blame]
Damjan Marionf56b77a2016-10-03 19:44:57 +02001#!/usr/bin/env python
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -08002import binascii
Matej Klotton16a14cd2016-12-07 15:09:13 +01003import random
Klement Sekeraf62ae122016-10-11 11:47:09 +02004import socket
Matej Klotton16a14cd2016-12-07 15:09:13 +01005import unittest
Klement Sekeraf62ae122016-10-11 11:47:09 +02006
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -07007import scapy.compat
Paul Vinciguerraa6fe4632018-11-25 11:21:50 -08008from scapy.contrib.mpls import MPLS
9from scapy.layers.inet import IP, UDP, TCP, ICMP, icmptypes, icmpcodes
10from scapy.layers.l2 import Ether, Dot1Q, ARP
11from scapy.packet import Raw
12from six import moves
13
Damjan Marionf56b77a2016-10-03 19:44:57 +020014from framework import VppTestCase, VppTestRunner
Paul Vinciguerraa6fe4632018-11-25 11:21:50 -080015from util import ppp
Neale Ranns180279b2017-03-16 15:49:09 -040016from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpMRoute, \
Neale Ranns15002542017-09-10 04:39:11 -070017 VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \
Ole Troan0bcad322018-12-11 13:04:01 +010018 VppMplsTable, VppIpTable
Paul Vinciguerraa6fe4632018-11-25 11:21:50 -080019from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
Damjan Marionf56b77a2016-10-03 19:44:57 +020020
21
Klement Sekeraf62ae122016-10-11 11:47:09 +020022class TestIPv4(VppTestCase):
Damjan Marionf56b77a2016-10-03 19:44:57 +020023 """ IPv4 Test Case """
24
Klement Sekeraf62ae122016-10-11 11:47:09 +020025 def setUp(self):
Matej Klotton86d87c42016-11-11 11:38:55 +010026 """
27 Perform test setup before test case.
28
29 **Config:**
30 - create 3 pg interfaces
31 - untagged pg0 interface
32 - Dot1Q subinterface on pg1
33 - Dot1AD subinterface on pg2
34 - setup interfaces:
35 - put it into UP state
36 - set IPv4 addresses
37 - resolve neighbor address using ARP
38 - configure 200 fib entries
39
40 :ivar list interfaces: pg interfaces and subinterfaces.
41 :ivar dict flows: IPv4 packet flows in test.
Matej Klotton86d87c42016-11-11 11:38:55 +010042 """
Klement Sekeraf62ae122016-10-11 11:47:09 +020043 super(TestIPv4, self).setUp()
Damjan Marionf56b77a2016-10-03 19:44:57 +020044
Klement Sekeraf62ae122016-10-11 11:47:09 +020045 # create 3 pg interfaces
46 self.create_pg_interfaces(range(3))
Damjan Marionf56b77a2016-10-03 19:44:57 +020047
Klement Sekeraf62ae122016-10-11 11:47:09 +020048 # create 2 subinterfaces for pg1 and pg2
49 self.sub_interfaces = [
50 VppDot1QSubint(self, self.pg1, 100),
51 VppDot1ADSubint(self, self.pg2, 200, 300, 400)]
Damjan Marionf56b77a2016-10-03 19:44:57 +020052
Klement Sekeraf62ae122016-10-11 11:47:09 +020053 # packet flows mapping pg0 -> pg1.sub, pg2.sub, etc.
54 self.flows = dict()
55 self.flows[self.pg0] = [self.pg1.sub_if, self.pg2.sub_if]
56 self.flows[self.pg1.sub_if] = [self.pg0, self.pg2.sub_if]
57 self.flows[self.pg2.sub_if] = [self.pg0, self.pg1.sub_if]
Damjan Marionf56b77a2016-10-03 19:44:57 +020058
Klement Sekeraf62ae122016-10-11 11:47:09 +020059 # packet sizes
Jan Geletye6c78ee2018-06-26 12:24:03 +020060 self.pg_if_packet_sizes = [64, 1500, 9020]
Damjan Marionf56b77a2016-10-03 19:44:57 +020061
Klement Sekeraf62ae122016-10-11 11:47:09 +020062 self.interfaces = list(self.pg_interfaces)
63 self.interfaces.extend(self.sub_interfaces)
Damjan Marionf56b77a2016-10-03 19:44:57 +020064
Klement Sekeraf62ae122016-10-11 11:47:09 +020065 # setup all interfaces
66 for i in self.interfaces:
67 i.admin_up()
68 i.config_ip4()
69 i.resolve_arp()
70
Matej Klotton86d87c42016-11-11 11:38:55 +010071 # config 2M FIB entries
Klement Sekeraf62ae122016-10-11 11:47:09 +020072 self.config_fib_entries(200)
Damjan Marionf56b77a2016-10-03 19:44:57 +020073
74 def tearDown(self):
Matej Klotton86d87c42016-11-11 11:38:55 +010075 """Run standard test teardown and log ``show ip arp``."""
Klement Sekeraf62ae122016-10-11 11:47:09 +020076 super(TestIPv4, self).tearDown()
77 if not self.vpp_dead:
Matej Klotton86d87c42016-11-11 11:38:55 +010078 self.logger.info(self.vapi.cli("show ip arp"))
Klement Sekeraf62ae122016-10-11 11:47:09 +020079 # info(self.vapi.cli("show ip fib")) # many entries
Damjan Marionf56b77a2016-10-03 19:44:57 +020080
Klement Sekeraf62ae122016-10-11 11:47:09 +020081 def config_fib_entries(self, count):
Matej Klotton86d87c42016-11-11 11:38:55 +010082 """For each interface add to the FIB table *count* routes to
83 "10.0.0.1/32" destination with interface's local address as next-hop
84 address.
85
86 :param int count: Number of FIB entries.
87
88 - *TODO:* check if the next-hop address shouldn't be remote address
89 instead of local address.
90 """
Klement Sekeraf62ae122016-10-11 11:47:09 +020091 n_int = len(self.interfaces)
92 percent = 0
93 counter = 0.0
94 dest_addr = socket.inet_pton(socket.AF_INET, "10.0.0.1")
95 dest_addr_len = 32
96 for i in self.interfaces:
97 next_hop_address = i.local_ip4n
98 for j in range(count / n_int):
99 self.vapi.ip_add_del_route(
100 dest_addr, dest_addr_len, next_hop_address)
Matej Klotton86d87c42016-11-11 11:38:55 +0100101 counter += 1
Klement Sekeraf62ae122016-10-11 11:47:09 +0200102 if counter / count * 100 > percent:
Matej Klotton86d87c42016-11-11 11:38:55 +0100103 self.logger.info("Configure %d FIB entries .. %d%% done" %
104 (count, percent))
105 percent += 1
Damjan Marionf56b77a2016-10-03 19:44:57 +0200106
Jan Geletye6c78ee2018-06-26 12:24:03 +0200107 def modify_packet(self, src_if, packet_size, pkt):
108 """Add load, set destination IP and extend packet to required packet
109 size for defined interface.
110
111 :param VppInterface src_if: Interface to create packet for.
112 :param int packet_size: Required packet size.
113 :param Scapy pkt: Packet to be modified.
114 """
115 dst_if_idx = packet_size / 10 % 2
116 dst_if = self.flows[src_if][dst_if_idx]
117 info = self.create_packet_info(src_if, dst_if)
118 payload = self.info_to_payload(info)
119 p = pkt/Raw(payload)
120 p[IP].dst = dst_if.remote_ip4
121 info.data = p.copy()
122 if isinstance(src_if, VppSubInterface):
123 p = src_if.add_dot1_layer(p)
124 self.extend_packet(p, packet_size)
125
126 return p
127
128 def create_stream(self, src_if):
Matej Klotton86d87c42016-11-11 11:38:55 +0100129 """Create input packet stream for defined interface.
130
131 :param VppInterface src_if: Interface to create packet stream for.
Matej Klotton86d87c42016-11-11 11:38:55 +0100132 """
Jan Geletye6c78ee2018-06-26 12:24:03 +0200133 hdr_ext = 4 if isinstance(src_if, VppSubInterface) else 0
134 pkt_tmpl = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
135 IP(src=src_if.remote_ip4) /
136 UDP(sport=1234, dport=1234))
137
138 pkts = [self.modify_packet(src_if, i, pkt_tmpl)
Paul Vinciguerraa6fe4632018-11-25 11:21:50 -0800139 for i in moves.range(self.pg_if_packet_sizes[0],
140 self.pg_if_packet_sizes[1], 10)]
Jan Geletye6c78ee2018-06-26 12:24:03 +0200141 pkts_b = [self.modify_packet(src_if, i, pkt_tmpl)
Paul Vinciguerraa6fe4632018-11-25 11:21:50 -0800142 for i in moves.range(self.pg_if_packet_sizes[1] + hdr_ext,
143 self.pg_if_packet_sizes[2] + hdr_ext,
144 50)]
Jan Geletye6c78ee2018-06-26 12:24:03 +0200145 pkts.extend(pkts_b)
146
Damjan Marionf56b77a2016-10-03 19:44:57 +0200147 return pkts
148
Klement Sekeraf62ae122016-10-11 11:47:09 +0200149 def verify_capture(self, dst_if, capture):
Matej Klotton86d87c42016-11-11 11:38:55 +0100150 """Verify captured input packet stream for defined interface.
151
152 :param VppInterface dst_if: Interface to verify captured packet stream
Jan Geletye6c78ee2018-06-26 12:24:03 +0200153 for.
Matej Klotton86d87c42016-11-11 11:38:55 +0100154 :param list capture: Captured packet stream.
155 """
156 self.logger.info("Verifying capture on interface %s" % dst_if.name)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200157 last_info = dict()
Damjan Marionf56b77a2016-10-03 19:44:57 +0200158 for i in self.interfaces:
Klement Sekeraf62ae122016-10-11 11:47:09 +0200159 last_info[i.sw_if_index] = None
160 is_sub_if = False
161 dst_sw_if_index = dst_if.sw_if_index
162 if hasattr(dst_if, 'parent'):
163 is_sub_if = True
Damjan Marionf56b77a2016-10-03 19:44:57 +0200164 for packet in capture:
Klement Sekeraf62ae122016-10-11 11:47:09 +0200165 if is_sub_if:
166 # Check VLAN tags and Ethernet header
167 packet = dst_if.remove_dot1_layer(packet)
Damjan Marionf56b77a2016-10-03 19:44:57 +0200168 self.assertTrue(Dot1Q not in packet)
169 try:
170 ip = packet[IP]
171 udp = packet[UDP]
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800172 payload_info = self.payload_to_info(packet[Raw])
Damjan Marionf56b77a2016-10-03 19:44:57 +0200173 packet_index = payload_info.index
Klement Sekeraf62ae122016-10-11 11:47:09 +0200174 self.assertEqual(payload_info.dst, dst_sw_if_index)
Klement Sekerada505f62017-01-04 12:58:53 +0100175 self.logger.debug(
176 "Got packet on port %s: src=%u (id=%u)" %
177 (dst_if.name, payload_info.src, packet_index))
Klement Sekeraf62ae122016-10-11 11:47:09 +0200178 next_info = self.get_next_packet_info_for_interface2(
179 payload_info.src, dst_sw_if_index,
180 last_info[payload_info.src])
181 last_info[payload_info.src] = next_info
Damjan Marionf56b77a2016-10-03 19:44:57 +0200182 self.assertTrue(next_info is not None)
183 self.assertEqual(packet_index, next_info.index)
184 saved_packet = next_info.data
185 # Check standard fields
186 self.assertEqual(ip.src, saved_packet[IP].src)
187 self.assertEqual(ip.dst, saved_packet[IP].dst)
188 self.assertEqual(udp.sport, saved_packet[UDP].sport)
189 self.assertEqual(udp.dport, saved_packet[UDP].dport)
190 except:
Klement Sekera7bb873a2016-11-18 07:38:42 +0100191 self.logger.error(ppp("Unexpected or invalid packet:", packet))
Damjan Marionf56b77a2016-10-03 19:44:57 +0200192 raise
193 for i in self.interfaces:
Klement Sekeraf62ae122016-10-11 11:47:09 +0200194 remaining_packet = self.get_next_packet_info_for_interface2(
195 i.sw_if_index, dst_sw_if_index, last_info[i.sw_if_index])
Klement Sekera7bb873a2016-11-18 07:38:42 +0100196 self.assertTrue(remaining_packet is None,
197 "Interface %s: Packet expected from interface %s "
198 "didn't arrive" % (dst_if.name, i.name))
Damjan Marionf56b77a2016-10-03 19:44:57 +0200199
200 def test_fib(self):
Matej Klotton86d87c42016-11-11 11:38:55 +0100201 """ IPv4 FIB test
202
203 Test scenario:
204
205 - Create IPv4 stream for pg0 interface
Jan Geletye6c78ee2018-06-26 12:24:03 +0200206 - Create IPv4 tagged streams for pg1's and pg2's sub-interface.
Matej Klotton86d87c42016-11-11 11:38:55 +0100207 - Send and verify received packets on each interface.
208 """
Damjan Marionf56b77a2016-10-03 19:44:57 +0200209
Jan Geletye6c78ee2018-06-26 12:24:03 +0200210 pkts = self.create_stream(self.pg0)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200211 self.pg0.add_stream(pkts)
Damjan Marionf56b77a2016-10-03 19:44:57 +0200212
Klement Sekeraf62ae122016-10-11 11:47:09 +0200213 for i in self.sub_interfaces:
Jan Geletye6c78ee2018-06-26 12:24:03 +0200214 pkts = self.create_stream(i)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200215 i.parent.add_stream(pkts)
216
217 self.pg_enable_capture(self.pg_interfaces)
Damjan Marionf56b77a2016-10-03 19:44:57 +0200218 self.pg_start()
219
Klement Sekeraf62ae122016-10-11 11:47:09 +0200220 pkts = self.pg0.get_capture()
221 self.verify_capture(self.pg0, pkts)
222
223 for i in self.sub_interfaces:
224 pkts = i.parent.get_capture()
225 self.verify_capture(i, pkts)
Damjan Marionf56b77a2016-10-03 19:44:57 +0200226
227
Jan Geletye6c78ee2018-06-26 12:24:03 +0200228class TestICMPEcho(VppTestCase):
229 """ ICMP Echo Test Case """
230
231 def setUp(self):
232 super(TestICMPEcho, self).setUp()
233
234 # create 1 pg interface
235 self.create_pg_interfaces(range(1))
236
237 for i in self.pg_interfaces:
238 i.admin_up()
239 i.config_ip4()
240 i.resolve_arp()
241
242 def tearDown(self):
243 super(TestICMPEcho, self).tearDown()
244 for i in self.pg_interfaces:
245 i.unconfig_ip4()
246 i.admin_down()
247
248 def test_icmp_echo(self):
249 """ VPP replies to ICMP Echo Request
250
251 Test scenario:
252
253 - Receive ICMP Echo Request message on pg0 interface.
254 - Check outgoing ICMP Echo Reply message on pg0 interface.
255 """
256
257 icmp_id = 0xb
258 icmp_seq = 5
259 icmp_load = '\x0a' * 18
260 p_echo_request = (Ether(src=self.pg0.remote_mac,
261 dst=self.pg0.local_mac) /
262 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
263 ICMP(id=icmp_id, seq=icmp_seq) /
264 Raw(load=icmp_load))
265
266 self.pg0.add_stream(p_echo_request)
267 self.pg_enable_capture(self.pg_interfaces)
268 self.pg_start()
269
270 rx = self.pg0.get_capture(1)
271 rx = rx[0]
272 ether = rx[Ether]
273 ipv4 = rx[IP]
274 icmp = rx[ICMP]
275
276 self.assertEqual(ether.src, self.pg0.local_mac)
277 self.assertEqual(ether.dst, self.pg0.remote_mac)
278
279 self.assertEqual(ipv4.src, self.pg0.local_ip4)
280 self.assertEqual(ipv4.dst, self.pg0.remote_ip4)
281
282 self.assertEqual(icmptypes[icmp.type], "echo-reply")
283 self.assertEqual(icmp.id, icmp_id)
284 self.assertEqual(icmp.seq, icmp_seq)
285 self.assertEqual(icmp[Raw].load, icmp_load)
286
287
Matej Klotton16a14cd2016-12-07 15:09:13 +0100288class TestIPv4FibCrud(VppTestCase):
289 """ FIB - add/update/delete - ip4 routes
290
291 Test scenario:
292 - add 1k,
293 - del 100,
294 - add new 1k,
295 - del 1.5k
296
Klement Sekerada505f62017-01-04 12:58:53 +0100297 ..note:: Python API is too slow to add many routes, needs replacement.
Matej Klotton16a14cd2016-12-07 15:09:13 +0100298 """
299
300 def config_fib_many_to_one(self, start_dest_addr, next_hop_addr, count):
301 """
302
303 :param start_dest_addr:
304 :param next_hop_addr:
305 :param count:
306 :return list: added ips with 32 prefix
307 """
308 added_ips = []
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800309 dest_addr = int(binascii.hexlify(socket.inet_pton(socket.AF_INET,
310 start_dest_addr)), 16)
Matej Klotton16a14cd2016-12-07 15:09:13 +0100311 dest_addr_len = 32
312 n_next_hop_addr = socket.inet_pton(socket.AF_INET, next_hop_addr)
313 for _ in range(count):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700314 n_dest_addr = binascii.unhexlify('{:08x}'.format(dest_addr))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100315 self.vapi.ip_add_del_route(n_dest_addr, dest_addr_len,
316 n_next_hop_addr)
317 added_ips.append(socket.inet_ntoa(n_dest_addr))
318 dest_addr += 1
319 return added_ips
320
321 def unconfig_fib_many_to_one(self, start_dest_addr, next_hop_addr, count):
322
323 removed_ips = []
Paul Vinciguerra6e4c6ad2018-11-25 10:35:29 -0800324 dest_addr = int(binascii.hexlify(socket.inet_pton(socket.AF_INET,
325 start_dest_addr)), 16)
Matej Klotton16a14cd2016-12-07 15:09:13 +0100326 dest_addr_len = 32
327 n_next_hop_addr = socket.inet_pton(socket.AF_INET, next_hop_addr)
328 for _ in range(count):
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -0700329 n_dest_addr = binascii.unhexlify('{:08x}'.format(dest_addr))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100330 self.vapi.ip_add_del_route(n_dest_addr, dest_addr_len,
331 n_next_hop_addr, is_add=0)
332 removed_ips.append(socket.inet_ntoa(n_dest_addr))
333 dest_addr += 1
334 return removed_ips
335
336 def create_stream(self, src_if, dst_if, dst_ips, count):
337 pkts = []
338
339 for _ in range(count):
340 dst_addr = random.choice(dst_ips)
Klement Sekeradab231a2016-12-21 08:50:14 +0100341 info = self.create_packet_info(src_if, dst_if)
Matej Klotton16a14cd2016-12-07 15:09:13 +0100342 payload = self.info_to_payload(info)
343 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
344 IP(src=src_if.remote_ip4, dst=dst_addr) /
345 UDP(sport=1234, dport=1234) /
346 Raw(payload))
347 info.data = p.copy()
Matej Klotton16a14cd2016-12-07 15:09:13 +0100348 self.extend_packet(p, random.choice(self.pg_if_packet_sizes))
349 pkts.append(p)
350
351 return pkts
352
353 def _find_ip_match(self, find_in, pkt):
354 for p in find_in:
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800355 if self.payload_to_info(p[Raw]) == \
356 self.payload_to_info(pkt[Raw]):
Matej Klotton16a14cd2016-12-07 15:09:13 +0100357 if p[IP].src != pkt[IP].src:
358 break
359 if p[IP].dst != pkt[IP].dst:
360 break
361 if p[UDP].sport != pkt[UDP].sport:
362 break
363 if p[UDP].dport != pkt[UDP].dport:
364 break
365 return p
366 return None
367
368 @staticmethod
369 def _match_route_detail(route_detail, ip, address_length=32, table_id=0):
370 if route_detail.address == socket.inet_pton(socket.AF_INET, ip):
371 if route_detail.table_id != table_id:
372 return False
373 elif route_detail.address_length != address_length:
374 return False
375 else:
376 return True
377 else:
378 return False
379
380 def verify_capture(self, dst_interface, received_pkts, expected_pkts):
381 self.assertEqual(len(received_pkts), len(expected_pkts))
382 to_verify = list(expected_pkts)
383 for p in received_pkts:
384 self.assertEqual(p.src, dst_interface.local_mac)
385 self.assertEqual(p.dst, dst_interface.remote_mac)
386 x = self._find_ip_match(to_verify, p)
387 to_verify.remove(x)
388 self.assertListEqual(to_verify, [])
389
390 def verify_route_dump(self, fib_dump, ips):
391
392 def _ip_in_route_dump(ip, fib_dump):
393 return next((route for route in fib_dump
394 if self._match_route_detail(route, ip)),
395 False)
396
397 for ip in ips:
398 self.assertTrue(_ip_in_route_dump(ip, fib_dump),
Paul Vinciguerraea2450f2019-03-06 08:23:58 -0800399 'IP {!s} is not in fib dump.'.format(ip))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100400
401 def verify_not_in_route_dump(self, fib_dump, ips):
402
403 def _ip_in_route_dump(ip, fib_dump):
404 return next((route for route in fib_dump
405 if self._match_route_detail(route, ip)),
406 False)
407
408 for ip in ips:
409 self.assertFalse(_ip_in_route_dump(ip, fib_dump),
Paul Vinciguerraea2450f2019-03-06 08:23:58 -0800410 'IP {!s} is in fib dump.'.format(ip))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100411
412 @classmethod
413 def setUpClass(cls):
414 """
415 #. Create and initialize 3 pg interfaces.
416 #. initialize class attributes configured_routes and deleted_routes
417 to store information between tests.
418 """
419 super(TestIPv4FibCrud, cls).setUpClass()
420
421 try:
422 # create 3 pg interfaces
423 cls.create_pg_interfaces(range(3))
424
425 cls.interfaces = list(cls.pg_interfaces)
426
427 # setup all interfaces
428 for i in cls.interfaces:
429 i.admin_up()
430 i.config_ip4()
431 i.resolve_arp()
432
433 cls.configured_routes = []
434 cls.deleted_routes = []
435 cls.pg_if_packet_sizes = [64, 512, 1518, 9018]
436
437 except Exception:
438 super(TestIPv4FibCrud, cls).tearDownClass()
439 raise
440
441 def setUp(self):
442 super(TestIPv4FibCrud, self).setUp()
Klement Sekeradab231a2016-12-21 08:50:14 +0100443 self.reset_packet_infos()
Matej Klotton16a14cd2016-12-07 15:09:13 +0100444
Paul Vinciguerra4eed7472018-12-16 14:52:36 -0800445 self.configured_routes = []
446 self.deleted_routes = []
447
Matej Klotton16a14cd2016-12-07 15:09:13 +0100448 def test_1_add_routes(self):
449 """ Add 1k routes
450
451 - add 100 routes check with traffic script.
452 """
453 # config 1M FIB entries
454 self.configured_routes.extend(self.config_fib_many_to_one(
455 "10.0.0.0", self.pg0.remote_ip4, 100))
456
457 fib_dump = self.vapi.ip_fib_dump()
458 self.verify_route_dump(fib_dump, self.configured_routes)
459
460 self.stream_1 = self.create_stream(
461 self.pg1, self.pg0, self.configured_routes, 100)
462 self.stream_2 = self.create_stream(
463 self.pg2, self.pg0, self.configured_routes, 100)
464 self.pg1.add_stream(self.stream_1)
465 self.pg2.add_stream(self.stream_2)
466
467 self.pg_enable_capture(self.pg_interfaces)
468 self.pg_start()
469
Klement Sekeradab231a2016-12-21 08:50:14 +0100470 pkts = self.pg0.get_capture(len(self.stream_1) + len(self.stream_2))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100471 self.verify_capture(self.pg0, pkts, self.stream_1 + self.stream_2)
472
Matej Klotton16a14cd2016-12-07 15:09:13 +0100473 def test_2_del_routes(self):
474 """ Delete 100 routes
475
476 - delete 10 routes check with traffic script.
477 """
Paul Vinciguerra4eed7472018-12-16 14:52:36 -0800478 # config 1M FIB entries
479 self.configured_routes.extend(self.config_fib_many_to_one(
480 "10.0.0.0", self.pg0.remote_ip4, 100))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100481 self.deleted_routes.extend(self.unconfig_fib_many_to_one(
482 "10.0.0.10", self.pg0.remote_ip4, 10))
483 for x in self.deleted_routes:
484 self.configured_routes.remove(x)
485
486 fib_dump = self.vapi.ip_fib_dump()
487 self.verify_route_dump(fib_dump, self.configured_routes)
488
489 self.stream_1 = self.create_stream(
490 self.pg1, self.pg0, self.configured_routes, 100)
491 self.stream_2 = self.create_stream(
492 self.pg2, self.pg0, self.configured_routes, 100)
493 self.stream_3 = self.create_stream(
494 self.pg1, self.pg0, self.deleted_routes, 100)
495 self.stream_4 = self.create_stream(
496 self.pg2, self.pg0, self.deleted_routes, 100)
497 self.pg1.add_stream(self.stream_1 + self.stream_3)
498 self.pg2.add_stream(self.stream_2 + self.stream_4)
499 self.pg_enable_capture(self.pg_interfaces)
500 self.pg_start()
501
Klement Sekeradab231a2016-12-21 08:50:14 +0100502 pkts = self.pg0.get_capture(len(self.stream_1) + len(self.stream_2))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100503 self.verify_capture(self.pg0, pkts, self.stream_1 + self.stream_2)
504
505 def test_3_add_new_routes(self):
506 """ Add 1k routes
507
508 - re-add 5 routes check with traffic script.
509 - add 100 routes check with traffic script.
510 """
Paul Vinciguerra4eed7472018-12-16 14:52:36 -0800511 # config 1M FIB entries
512 self.configured_routes.extend(self.config_fib_many_to_one(
513 "10.0.0.0", self.pg0.remote_ip4, 100))
514 self.deleted_routes.extend(self.unconfig_fib_many_to_one(
515 "10.0.0.10", self.pg0.remote_ip4, 10))
516 for x in self.deleted_routes:
517 self.configured_routes.remove(x)
518
Matej Klotton16a14cd2016-12-07 15:09:13 +0100519 tmp = self.config_fib_many_to_one(
520 "10.0.0.10", self.pg0.remote_ip4, 5)
521 self.configured_routes.extend(tmp)
522 for x in tmp:
523 self.deleted_routes.remove(x)
524
525 self.configured_routes.extend(self.config_fib_many_to_one(
526 "10.0.1.0", self.pg0.remote_ip4, 100))
527
528 fib_dump = self.vapi.ip_fib_dump()
529 self.verify_route_dump(fib_dump, self.configured_routes)
530
531 self.stream_1 = self.create_stream(
532 self.pg1, self.pg0, self.configured_routes, 300)
533 self.stream_2 = self.create_stream(
534 self.pg2, self.pg0, self.configured_routes, 300)
535 self.stream_3 = self.create_stream(
536 self.pg1, self.pg0, self.deleted_routes, 100)
537 self.stream_4 = self.create_stream(
538 self.pg2, self.pg0, self.deleted_routes, 100)
539
540 self.pg1.add_stream(self.stream_1 + self.stream_3)
541 self.pg2.add_stream(self.stream_2 + self.stream_4)
542 self.pg_enable_capture(self.pg_interfaces)
543 self.pg_start()
544
Klement Sekeradab231a2016-12-21 08:50:14 +0100545 pkts = self.pg0.get_capture(len(self.stream_1) + len(self.stream_2))
Matej Klotton16a14cd2016-12-07 15:09:13 +0100546 self.verify_capture(self.pg0, pkts, self.stream_1 + self.stream_2)
547
548 def test_4_del_routes(self):
549 """ Delete 1.5k routes
550
551 - delete 5 routes check with traffic script.
552 - add 100 routes check with traffic script.
553 """
554 self.deleted_routes.extend(self.unconfig_fib_many_to_one(
555 "10.0.0.0", self.pg0.remote_ip4, 15))
556 self.deleted_routes.extend(self.unconfig_fib_many_to_one(
557 "10.0.0.20", self.pg0.remote_ip4, 85))
558 self.deleted_routes.extend(self.unconfig_fib_many_to_one(
559 "10.0.1.0", self.pg0.remote_ip4, 100))
560 fib_dump = self.vapi.ip_fib_dump()
561 self.verify_not_in_route_dump(fib_dump, self.deleted_routes)
562
563
Neale Ranns37be7362017-02-21 17:30:26 -0800564class TestIPNull(VppTestCase):
565 """ IPv4 routes via NULL """
566
567 def setUp(self):
568 super(TestIPNull, self).setUp()
569
570 # create 2 pg interfaces
Neale Ranns3b93be52018-09-07 01:48:54 -0700571 self.create_pg_interfaces(range(2))
Neale Ranns37be7362017-02-21 17:30:26 -0800572
573 for i in self.pg_interfaces:
574 i.admin_up()
575 i.config_ip4()
576 i.resolve_arp()
577
578 def tearDown(self):
579 super(TestIPNull, self).tearDown()
580 for i in self.pg_interfaces:
581 i.unconfig_ip4()
582 i.admin_down()
583
584 def test_ip_null(self):
585 """ IP NULL route """
586
587 #
588 # A route via IP NULL that will reply with ICMP unreachables
589 #
590 ip_unreach = VppIpRoute(self, "10.0.0.1", 32, [], is_unreach=1)
591 ip_unreach.add_vpp_config()
592
593 p_unreach = (Ether(src=self.pg0.remote_mac,
594 dst=self.pg0.local_mac) /
595 IP(src=self.pg0.remote_ip4, dst="10.0.0.1") /
596 UDP(sport=1234, dport=1234) /
597 Raw('\xa5' * 100))
598
599 self.pg0.add_stream(p_unreach)
600 self.pg_enable_capture(self.pg_interfaces)
601 self.pg_start()
602
603 rx = self.pg0.get_capture(1)
604 rx = rx[0]
605 icmp = rx[ICMP]
606
607 self.assertEqual(icmptypes[icmp.type], "dest-unreach")
608 self.assertEqual(icmpcodes[icmp.type][icmp.code], "host-unreachable")
609 self.assertEqual(icmp.src, self.pg0.remote_ip4)
610 self.assertEqual(icmp.dst, "10.0.0.1")
611
612 #
613 # ICMP replies are rate limited. so sit and spin.
614 #
615 self.sleep(1)
616
617 #
618 # A route via IP NULL that will reply with ICMP prohibited
619 #
620 ip_prohibit = VppIpRoute(self, "10.0.0.2", 32, [], is_prohibit=1)
621 ip_prohibit.add_vpp_config()
622
623 p_prohibit = (Ether(src=self.pg0.remote_mac,
624 dst=self.pg0.local_mac) /
625 IP(src=self.pg0.remote_ip4, dst="10.0.0.2") /
626 UDP(sport=1234, dport=1234) /
627 Raw('\xa5' * 100))
628
629 self.pg0.add_stream(p_prohibit)
630 self.pg_enable_capture(self.pg_interfaces)
631 self.pg_start()
632
633 rx = self.pg0.get_capture(1)
634
635 rx = rx[0]
636 icmp = rx[ICMP]
637
638 self.assertEqual(icmptypes[icmp.type], "dest-unreach")
639 self.assertEqual(icmpcodes[icmp.type][icmp.code], "host-prohibited")
640 self.assertEqual(icmp.src, self.pg0.remote_ip4)
641 self.assertEqual(icmp.dst, "10.0.0.2")
642
Neale Ranns3b93be52018-09-07 01:48:54 -0700643 def test_ip_drop(self):
644 """ IP Drop Routes """
645
646 p = (Ether(src=self.pg0.remote_mac,
647 dst=self.pg0.local_mac) /
648 IP(src=self.pg0.remote_ip4, dst="1.1.1.1") /
649 UDP(sport=1234, dport=1234) /
650 Raw('\xa5' * 100))
651
652 r1 = VppIpRoute(self, "1.1.1.0", 24,
653 [VppRoutePath(self.pg1.remote_ip4,
654 self.pg1.sw_if_index)])
655 r1.add_vpp_config()
656
657 rx = self.send_and_expect(self.pg0, p * 65, self.pg1)
658
659 #
660 # insert a more specific as a drop
661 #
662 r2 = VppIpRoute(self, "1.1.1.1", 32, [], is_drop=1)
663 r2.add_vpp_config()
664
665 self.send_and_assert_no_replies(self.pg0, p * 65, "Drop Route")
666 r2.remove_vpp_config()
667 rx = self.send_and_expect(self.pg0, p * 65, self.pg1)
668
Neale Ranns37be7362017-02-21 17:30:26 -0800669
Neale Ranns180279b2017-03-16 15:49:09 -0400670class TestIPDisabled(VppTestCase):
671 """ IPv4 disabled """
672
673 def setUp(self):
674 super(TestIPDisabled, self).setUp()
675
676 # create 2 pg interfaces
677 self.create_pg_interfaces(range(2))
678
679 # PG0 is IP enalbed
680 self.pg0.admin_up()
681 self.pg0.config_ip4()
682 self.pg0.resolve_arp()
683
684 # PG 1 is not IP enabled
685 self.pg1.admin_up()
686
687 def tearDown(self):
688 super(TestIPDisabled, self).tearDown()
689 for i in self.pg_interfaces:
690 i.unconfig_ip4()
691 i.admin_down()
692
Neale Ranns180279b2017-03-16 15:49:09 -0400693 def test_ip_disabled(self):
694 """ IP Disabled """
695
696 #
697 # An (S,G).
698 # one accepting interface, pg0, 2 forwarding interfaces
699 #
700 route_232_1_1_1 = VppIpMRoute(
701 self,
702 "0.0.0.0",
703 "232.1.1.1", 32,
704 MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
705 [VppMRoutePath(self.pg1.sw_if_index,
706 MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
707 VppMRoutePath(self.pg0.sw_if_index,
708 MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
709 route_232_1_1_1.add_vpp_config()
710
711 pu = (Ether(src=self.pg1.remote_mac,
712 dst=self.pg1.local_mac) /
713 IP(src="10.10.10.10", dst=self.pg0.remote_ip4) /
714 UDP(sport=1234, dport=1234) /
715 Raw('\xa5' * 100))
716 pm = (Ether(src=self.pg1.remote_mac,
717 dst=self.pg1.local_mac) /
718 IP(src="10.10.10.10", dst="232.1.1.1") /
719 UDP(sport=1234, dport=1234) /
720 Raw('\xa5' * 100))
721
722 #
723 # PG1 does not forward IP traffic
724 #
725 self.send_and_assert_no_replies(self.pg1, pu, "IP disabled")
726 self.send_and_assert_no_replies(self.pg1, pm, "IP disabled")
727
728 #
729 # IP enable PG1
730 #
731 self.pg1.config_ip4()
732
733 #
734 # Now we get packets through
735 #
736 self.pg1.add_stream(pu)
737 self.pg_enable_capture(self.pg_interfaces)
738 self.pg_start()
739 rx = self.pg0.get_capture(1)
740
741 self.pg1.add_stream(pm)
742 self.pg_enable_capture(self.pg_interfaces)
743 self.pg_start()
744 rx = self.pg0.get_capture(1)
745
746 #
747 # Disable PG1
748 #
749 self.pg1.unconfig_ip4()
750
751 #
752 # PG1 does not forward IP traffic
753 #
754 self.send_and_assert_no_replies(self.pg1, pu, "IP disabled")
755 self.send_and_assert_no_replies(self.pg1, pm, "IP disabled")
756
757
Neale Ranns9a69a602017-03-26 10:56:33 -0700758class TestIPSubNets(VppTestCase):
759 """ IPv4 Subnets """
760
761 def setUp(self):
762 super(TestIPSubNets, self).setUp()
763
764 # create a 2 pg interfaces
765 self.create_pg_interfaces(range(2))
766
767 # pg0 we will use to experiemnt
768 self.pg0.admin_up()
769
770 # pg1 is setup normally
771 self.pg1.admin_up()
772 self.pg1.config_ip4()
773 self.pg1.resolve_arp()
774
775 def tearDown(self):
776 super(TestIPSubNets, self).tearDown()
777 for i in self.pg_interfaces:
778 i.admin_down()
779
Neale Ranns9a69a602017-03-26 10:56:33 -0700780 def test_ip_sub_nets(self):
781 """ IP Sub Nets """
782
783 #
784 # Configure a covering route to forward so we know
785 # when we are dropping
786 #
787 cover_route = VppIpRoute(self, "10.0.0.0", 8,
788 [VppRoutePath(self.pg1.remote_ip4,
789 self.pg1.sw_if_index)])
790 cover_route.add_vpp_config()
791
792 p = (Ether(src=self.pg1.remote_mac,
793 dst=self.pg1.local_mac) /
794 IP(dst="10.10.10.10", src=self.pg0.local_ip4) /
795 UDP(sport=1234, dport=1234) /
796 Raw('\xa5' * 100))
797
798 self.pg1.add_stream(p)
799 self.pg_enable_capture(self.pg_interfaces)
800 self.pg_start()
801 rx = self.pg1.get_capture(1)
802
803 #
804 # Configure some non-/24 subnets on an IP interface
805 #
806 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10")
807
Ole Troan9a475372019-03-05 16:58:24 +0100808 self.vapi.sw_interface_add_del_address(
809 sw_if_index=self.pg0.sw_if_index, address=ip_addr_n,
810 address_length=16)
Neale Ranns9a69a602017-03-26 10:56:33 -0700811
812 pn = (Ether(src=self.pg1.remote_mac,
813 dst=self.pg1.local_mac) /
814 IP(dst="10.10.0.0", src=self.pg0.local_ip4) /
815 UDP(sport=1234, dport=1234) /
816 Raw('\xa5' * 100))
817 pb = (Ether(src=self.pg1.remote_mac,
818 dst=self.pg1.local_mac) /
819 IP(dst="10.10.255.255", src=self.pg0.local_ip4) /
820 UDP(sport=1234, dport=1234) /
821 Raw('\xa5' * 100))
822
823 self.send_and_assert_no_replies(self.pg1, pn, "IP Network address")
824 self.send_and_assert_no_replies(self.pg1, pb, "IP Broadcast address")
825
826 # remove the sub-net and we are forwarding via the cover again
Ole Troan9a475372019-03-05 16:58:24 +0100827 self.vapi.sw_interface_add_del_address(
828 sw_if_index=self.pg0.sw_if_index, address=ip_addr_n,
829 address_length=16, is_add=0)
Neale Ranns9a69a602017-03-26 10:56:33 -0700830 self.pg1.add_stream(pn)
831 self.pg_enable_capture(self.pg_interfaces)
832 self.pg_start()
833 rx = self.pg1.get_capture(1)
834 self.pg1.add_stream(pb)
835 self.pg_enable_capture(self.pg_interfaces)
836 self.pg_start()
837 rx = self.pg1.get_capture(1)
838
839 #
840 # A /31 is a special case where the 'other-side' is an attached host
841 # packets to that peer generate ARP requests
842 #
843 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10")
844
Ole Troan9a475372019-03-05 16:58:24 +0100845 self.vapi.sw_interface_add_del_address(
846 sw_if_index=self.pg0.sw_if_index, address=ip_addr_n,
847 address_length=31)
Neale Ranns9a69a602017-03-26 10:56:33 -0700848
849 pn = (Ether(src=self.pg1.remote_mac,
850 dst=self.pg1.local_mac) /
851 IP(dst="10.10.10.11", src=self.pg0.local_ip4) /
852 UDP(sport=1234, dport=1234) /
853 Raw('\xa5' * 100))
854
855 self.pg1.add_stream(pn)
856 self.pg_enable_capture(self.pg_interfaces)
857 self.pg_start()
858 rx = self.pg0.get_capture(1)
859 rx[ARP]
860
861 # remove the sub-net and we are forwarding via the cover again
Ole Troan9a475372019-03-05 16:58:24 +0100862 self.vapi.sw_interface_add_del_address(
863 sw_if_index=self.pg0.sw_if_index, address=ip_addr_n,
864 address_length=31, is_add=0)
Neale Ranns9a69a602017-03-26 10:56:33 -0700865 self.pg1.add_stream(pn)
866 self.pg_enable_capture(self.pg_interfaces)
867 self.pg_start()
868 rx = self.pg1.get_capture(1)
869
870
Neale Ranns227038a2017-04-21 01:07:59 -0700871class TestIPLoadBalance(VppTestCase):
872 """ IPv4 Load-Balancing """
873
874 def setUp(self):
875 super(TestIPLoadBalance, self).setUp()
876
877 self.create_pg_interfaces(range(5))
Neale Ranns15002542017-09-10 04:39:11 -0700878 mpls_tbl = VppMplsTable(self, 0)
879 mpls_tbl.add_vpp_config()
Neale Ranns227038a2017-04-21 01:07:59 -0700880
881 for i in self.pg_interfaces:
882 i.admin_up()
883 i.config_ip4()
884 i.resolve_arp()
Neale Ranns71275e32017-05-25 12:38:58 -0700885 i.enable_mpls()
Neale Ranns227038a2017-04-21 01:07:59 -0700886
887 def tearDown(self):
Neale Ranns227038a2017-04-21 01:07:59 -0700888 for i in self.pg_interfaces:
Neale Ranns71275e32017-05-25 12:38:58 -0700889 i.disable_mpls()
Neale Ranns227038a2017-04-21 01:07:59 -0700890 i.unconfig_ip4()
891 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -0700892 super(TestIPLoadBalance, self).tearDown()
Neale Ranns227038a2017-04-21 01:07:59 -0700893
894 def send_and_expect_load_balancing(self, input, pkts, outputs):
895 input.add_stream(pkts)
896 self.pg_enable_capture(self.pg_interfaces)
897 self.pg_start()
898 for oo in outputs:
899 rx = oo._get_capture(1)
900 self.assertNotEqual(0, len(rx))
901
Neale Ranns42e6b092017-07-31 02:56:03 -0700902 def send_and_expect_one_itf(self, input, pkts, itf):
903 input.add_stream(pkts)
904 self.pg_enable_capture(self.pg_interfaces)
905 self.pg_start()
906 rx = itf.get_capture(len(pkts))
907
Neale Ranns227038a2017-04-21 01:07:59 -0700908 def test_ip_load_balance(self):
909 """ IP Load-Balancing """
910
911 #
912 # An array of packets that differ only in the destination port
913 #
Neale Ranns71275e32017-05-25 12:38:58 -0700914 port_ip_pkts = []
915 port_mpls_pkts = []
Neale Ranns227038a2017-04-21 01:07:59 -0700916
917 #
918 # An array of packets that differ only in the source address
919 #
Neale Ranns71275e32017-05-25 12:38:58 -0700920 src_ip_pkts = []
921 src_mpls_pkts = []
Neale Ranns227038a2017-04-21 01:07:59 -0700922
923 for ii in range(65):
Neale Ranns71275e32017-05-25 12:38:58 -0700924 port_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.1") /
925 UDP(sport=1234, dport=1234 + ii) /
926 Raw('\xa5' * 100))
927 port_ip_pkts.append((Ether(src=self.pg0.remote_mac,
928 dst=self.pg0.local_mac) /
929 port_ip_hdr))
930 port_mpls_pkts.append((Ether(src=self.pg0.remote_mac,
931 dst=self.pg0.local_mac) /
932 MPLS(label=66, ttl=2) /
933 port_ip_hdr))
934
935 src_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.%d" % ii) /
936 UDP(sport=1234, dport=1234) /
937 Raw('\xa5' * 100))
938 src_ip_pkts.append((Ether(src=self.pg0.remote_mac,
939 dst=self.pg0.local_mac) /
940 src_ip_hdr))
941 src_mpls_pkts.append((Ether(src=self.pg0.remote_mac,
942 dst=self.pg0.local_mac) /
943 MPLS(label=66, ttl=2) /
944 src_ip_hdr))
Neale Ranns227038a2017-04-21 01:07:59 -0700945
946 route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
947 [VppRoutePath(self.pg1.remote_ip4,
948 self.pg1.sw_if_index),
949 VppRoutePath(self.pg2.remote_ip4,
950 self.pg2.sw_if_index)])
951 route_10_0_0_1.add_vpp_config()
952
Neale Ranns71275e32017-05-25 12:38:58 -0700953 binding = VppMplsIpBind(self, 66, "10.0.0.1", 32)
954 binding.add_vpp_config()
955
Neale Ranns227038a2017-04-21 01:07:59 -0700956 #
957 # inject the packet on pg0 - expect load-balancing across the 2 paths
958 # - since the default hash config is to use IP src,dst and port
959 # src,dst
960 # We are not going to ensure equal amounts of packets across each link,
961 # since the hash algorithm is statistical and therefore this can never
962 # be guaranteed. But wuth 64 different packets we do expect some
963 # balancing. So instead just ensure there is traffic on each link.
964 #
Neale Ranns71275e32017-05-25 12:38:58 -0700965 self.send_and_expect_load_balancing(self.pg0, port_ip_pkts,
Neale Ranns227038a2017-04-21 01:07:59 -0700966 [self.pg1, self.pg2])
Neale Ranns71275e32017-05-25 12:38:58 -0700967 self.send_and_expect_load_balancing(self.pg0, src_ip_pkts,
968 [self.pg1, self.pg2])
969 self.send_and_expect_load_balancing(self.pg0, port_mpls_pkts,
970 [self.pg1, self.pg2])
971 self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts,
Neale Ranns227038a2017-04-21 01:07:59 -0700972 [self.pg1, self.pg2])
973
974 #
975 # change the flow hash config so it's only IP src,dst
976 # - now only the stream with differing source address will
977 # load-balance
978 #
979 self.vapi.set_ip_flow_hash(0, src=1, dst=1, sport=0, dport=0)
980
Neale Ranns71275e32017-05-25 12:38:58 -0700981 self.send_and_expect_load_balancing(self.pg0, src_ip_pkts,
982 [self.pg1, self.pg2])
983 self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts,
Neale Ranns227038a2017-04-21 01:07:59 -0700984 [self.pg1, self.pg2])
985
Neale Ranns42e6b092017-07-31 02:56:03 -0700986 self.send_and_expect_one_itf(self.pg0, port_ip_pkts, self.pg2)
Neale Ranns227038a2017-04-21 01:07:59 -0700987
988 #
989 # change the flow hash config back to defaults
990 #
991 self.vapi.set_ip_flow_hash(0, src=1, dst=1, sport=1, dport=1)
992
993 #
994 # Recursive prefixes
995 # - testing that 2 stages of load-balancing occurs and there is no
996 # polarisation (i.e. only 2 of 4 paths are used)
997 #
998 port_pkts = []
999 src_pkts = []
1000
1001 for ii in range(257):
1002 port_pkts.append((Ether(src=self.pg0.remote_mac,
1003 dst=self.pg0.local_mac) /
1004 IP(dst="1.1.1.1", src="20.0.0.1") /
1005 UDP(sport=1234, dport=1234 + ii) /
1006 Raw('\xa5' * 100)))
1007 src_pkts.append((Ether(src=self.pg0.remote_mac,
1008 dst=self.pg0.local_mac) /
1009 IP(dst="1.1.1.1", src="20.0.0.%d" % ii) /
1010 UDP(sport=1234, dport=1234) /
1011 Raw('\xa5' * 100)))
1012
1013 route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
1014 [VppRoutePath(self.pg3.remote_ip4,
1015 self.pg3.sw_if_index),
1016 VppRoutePath(self.pg4.remote_ip4,
1017 self.pg4.sw_if_index)])
1018 route_10_0_0_2.add_vpp_config()
1019
1020 route_1_1_1_1 = VppIpRoute(self, "1.1.1.1", 32,
1021 [VppRoutePath("10.0.0.2", 0xffffffff),
1022 VppRoutePath("10.0.0.1", 0xffffffff)])
1023 route_1_1_1_1.add_vpp_config()
1024
1025 #
1026 # inject the packet on pg0 - expect load-balancing across all 4 paths
1027 #
1028 self.vapi.cli("clear trace")
1029 self.send_and_expect_load_balancing(self.pg0, port_pkts,
1030 [self.pg1, self.pg2,
1031 self.pg3, self.pg4])
1032 self.send_and_expect_load_balancing(self.pg0, src_pkts,
1033 [self.pg1, self.pg2,
1034 self.pg3, self.pg4])
1035
Neale Ranns42e6b092017-07-31 02:56:03 -07001036 #
1037 # Recursive prefixes
1038 # - testing that 2 stages of load-balancing, no choices
1039 #
1040 port_pkts = []
1041
1042 for ii in range(257):
1043 port_pkts.append((Ether(src=self.pg0.remote_mac,
1044 dst=self.pg0.local_mac) /
1045 IP(dst="1.1.1.2", src="20.0.0.2") /
1046 UDP(sport=1234, dport=1234 + ii) /
1047 Raw('\xa5' * 100)))
1048
1049 route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
1050 [VppRoutePath(self.pg3.remote_ip4,
1051 self.pg3.sw_if_index)])
1052 route_10_0_0_3.add_vpp_config()
1053
1054 route_1_1_1_2 = VppIpRoute(self, "1.1.1.2", 32,
1055 [VppRoutePath("10.0.0.3", 0xffffffff)])
1056 route_1_1_1_2.add_vpp_config()
1057
1058 #
1059 # inject the packet on pg0 - expect load-balancing across all 4 paths
1060 #
1061 self.vapi.cli("clear trace")
1062 self.send_and_expect_one_itf(self.pg0, port_pkts, self.pg3)
1063
Neale Ranns30d0fd42017-05-30 07:30:04 -07001064
1065class TestIPVlan0(VppTestCase):
1066 """ IPv4 VLAN-0 """
1067
1068 def setUp(self):
1069 super(TestIPVlan0, self).setUp()
1070
1071 self.create_pg_interfaces(range(2))
Neale Ranns15002542017-09-10 04:39:11 -07001072 mpls_tbl = VppMplsTable(self, 0)
1073 mpls_tbl.add_vpp_config()
Neale Ranns30d0fd42017-05-30 07:30:04 -07001074
1075 for i in self.pg_interfaces:
1076 i.admin_up()
1077 i.config_ip4()
1078 i.resolve_arp()
1079 i.enable_mpls()
1080
1081 def tearDown(self):
Neale Ranns30d0fd42017-05-30 07:30:04 -07001082 for i in self.pg_interfaces:
1083 i.disable_mpls()
1084 i.unconfig_ip4()
1085 i.admin_down()
Neale Ranns15002542017-09-10 04:39:11 -07001086 super(TestIPVlan0, self).tearDown()
Neale Ranns30d0fd42017-05-30 07:30:04 -07001087
Neale Ranns30d0fd42017-05-30 07:30:04 -07001088 def test_ip_vlan_0(self):
1089 """ IP VLAN-0 """
1090
1091 pkts = (Ether(src=self.pg0.remote_mac,
1092 dst=self.pg0.local_mac) /
1093 Dot1Q(vlan=0) /
1094 IP(dst=self.pg1.remote_ip4,
1095 src=self.pg0.remote_ip4) /
1096 UDP(sport=1234, dport=1234) /
1097 Raw('\xa5' * 100)) * 65
1098
1099 #
1100 # Expect that packets sent on VLAN-0 are forwarded on the
1101 # main interface.
1102 #
1103 self.send_and_expect(self.pg0, pkts, self.pg1)
1104
1105
Neale Rannsd91c1db2017-07-31 02:30:50 -07001106class TestIPPunt(VppTestCase):
1107 """ IPv4 Punt Police/Redirect """
1108
1109 def setUp(self):
1110 super(TestIPPunt, self).setUp()
1111
Pavel Kotucek609e1212018-11-27 09:59:44 +01001112 self.create_pg_interfaces(range(4))
Neale Rannsd91c1db2017-07-31 02:30:50 -07001113
1114 for i in self.pg_interfaces:
1115 i.admin_up()
1116 i.config_ip4()
1117 i.resolve_arp()
1118
1119 def tearDown(self):
1120 super(TestIPPunt, self).tearDown()
1121 for i in self.pg_interfaces:
1122 i.unconfig_ip4()
1123 i.admin_down()
1124
Neale Rannsd91c1db2017-07-31 02:30:50 -07001125 def test_ip_punt(self):
1126 """ IP punt police and redirect """
1127
1128 p = (Ether(src=self.pg0.remote_mac,
1129 dst=self.pg0.local_mac) /
1130 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
1131 TCP(sport=1234, dport=1234) /
1132 Raw('\xa5' * 100))
1133
1134 pkts = p * 1025
1135
1136 #
1137 # Configure a punt redirect via pg1.
1138 #
Ole Troan0bcad322018-12-11 13:04:01 +01001139 nh_addr = self.pg1.remote_ip4
Neale Rannsd91c1db2017-07-31 02:30:50 -07001140 self.vapi.ip_punt_redirect(self.pg0.sw_if_index,
1141 self.pg1.sw_if_index,
1142 nh_addr)
1143
1144 self.send_and_expect(self.pg0, pkts, self.pg1)
1145
1146 #
1147 # add a policer
1148 #
1149 policer = self.vapi.policer_add_del("ip4-punt", 400, 0, 10, 0,
1150 rate_type=1)
1151 self.vapi.ip_punt_police(policer.policer_index)
1152
1153 self.vapi.cli("clear trace")
1154 self.pg0.add_stream(pkts)
1155 self.pg_enable_capture(self.pg_interfaces)
1156 self.pg_start()
1157
1158 #
1159 # the number of packet recieved should be greater than 0,
1160 # but not equal to the number sent, since some were policed
1161 #
1162 rx = self.pg1._get_capture(1)
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08001163 self.assertGreater(len(rx), 0)
1164 self.assertLess(len(rx), len(pkts))
Neale Rannsd91c1db2017-07-31 02:30:50 -07001165
1166 #
1167 # remove the poilcer. back to full rx
1168 #
1169 self.vapi.ip_punt_police(policer.policer_index, is_add=0)
1170 self.vapi.policer_add_del("ip4-punt", 400, 0, 10, 0,
1171 rate_type=1, is_add=0)
1172 self.send_and_expect(self.pg0, pkts, self.pg1)
1173
1174 #
1175 # remove the redirect. expect full drop.
1176 #
1177 self.vapi.ip_punt_redirect(self.pg0.sw_if_index,
1178 self.pg1.sw_if_index,
1179 nh_addr,
1180 is_add=0)
1181 self.send_and_assert_no_replies(self.pg0, pkts,
1182 "IP no punt config")
1183
1184 #
1185 # Add a redirect that is not input port selective
1186 #
1187 self.vapi.ip_punt_redirect(0xffffffff,
1188 self.pg1.sw_if_index,
1189 nh_addr)
1190 self.send_and_expect(self.pg0, pkts, self.pg1)
1191
1192 self.vapi.ip_punt_redirect(0xffffffff,
1193 self.pg1.sw_if_index,
1194 nh_addr,
1195 is_add=0)
1196
Pavel Kotucek609e1212018-11-27 09:59:44 +01001197 def test_ip_punt_dump(self):
1198 """ IP4 punt redirect dump"""
1199
1200 #
1201 # Configure a punt redirects
1202 #
Ole Troan0bcad322018-12-11 13:04:01 +01001203 nh_address = self.pg3.remote_ip4
Pavel Kotucek609e1212018-11-27 09:59:44 +01001204 self.vapi.ip_punt_redirect(self.pg0.sw_if_index,
1205 self.pg3.sw_if_index,
1206 nh_address)
1207 self.vapi.ip_punt_redirect(self.pg1.sw_if_index,
1208 self.pg3.sw_if_index,
1209 nh_address)
1210 self.vapi.ip_punt_redirect(self.pg2.sw_if_index,
1211 self.pg3.sw_if_index,
Ole Troan0bcad322018-12-11 13:04:01 +01001212 '0.0.0.0')
Pavel Kotucek609e1212018-11-27 09:59:44 +01001213
1214 #
1215 # Dump pg0 punt redirects
1216 #
1217 punts = self.vapi.ip_punt_redirect_dump(self.pg0.sw_if_index)
1218 for p in punts:
1219 self.assertEqual(p.punt.rx_sw_if_index, self.pg0.sw_if_index)
1220
1221 #
1222 # Dump punt redirects for all interfaces
1223 #
1224 punts = self.vapi.ip_punt_redirect_dump(0xffffffff)
1225 self.assertEqual(len(punts), 3)
1226 for p in punts:
1227 self.assertEqual(p.punt.tx_sw_if_index, self.pg3.sw_if_index)
Ole Troan0bcad322018-12-11 13:04:01 +01001228 self.assertNotEqual(punts[1].punt.nh, self.pg3.remote_ip4)
1229 self.assertEqual(str(punts[2].punt.nh), '0.0.0.0')
Pavel Kotucek609e1212018-11-27 09:59:44 +01001230
Neale Rannsd91c1db2017-07-31 02:30:50 -07001231
Neale Ranns054c03a2017-10-13 05:15:07 -07001232class TestIPDeag(VppTestCase):
1233 """ IPv4 Deaggregate Routes """
1234
1235 def setUp(self):
1236 super(TestIPDeag, self).setUp()
1237
1238 self.create_pg_interfaces(range(3))
1239
1240 for i in self.pg_interfaces:
1241 i.admin_up()
1242 i.config_ip4()
1243 i.resolve_arp()
1244
1245 def tearDown(self):
1246 super(TestIPDeag, self).tearDown()
1247 for i in self.pg_interfaces:
1248 i.unconfig_ip4()
1249 i.admin_down()
1250
Neale Ranns054c03a2017-10-13 05:15:07 -07001251 def test_ip_deag(self):
1252 """ IP Deag Routes """
1253
1254 #
1255 # Create a table to be used for:
1256 # 1 - another destination address lookup
1257 # 2 - a source address lookup
1258 #
1259 table_dst = VppIpTable(self, 1)
1260 table_src = VppIpTable(self, 2)
1261 table_dst.add_vpp_config()
1262 table_src.add_vpp_config()
1263
1264 #
1265 # Add a route in the default table to point to a deag/
1266 # second lookup in each of these tables
1267 #
1268 route_to_dst = VppIpRoute(self, "1.1.1.1", 32,
1269 [VppRoutePath("0.0.0.0",
1270 0xffffffff,
1271 nh_table_id=1)])
1272 route_to_src = VppIpRoute(self, "1.1.1.2", 32,
1273 [VppRoutePath("0.0.0.0",
1274 0xffffffff,
1275 nh_table_id=2,
1276 is_source_lookup=1)])
1277 route_to_dst.add_vpp_config()
1278 route_to_src.add_vpp_config()
1279
1280 #
1281 # packets to these destination are dropped, since they'll
1282 # hit the respective default routes in the second table
1283 #
1284 p_dst = (Ether(src=self.pg0.remote_mac,
1285 dst=self.pg0.local_mac) /
1286 IP(src="5.5.5.5", dst="1.1.1.1") /
1287 TCP(sport=1234, dport=1234) /
1288 Raw('\xa5' * 100))
1289 p_src = (Ether(src=self.pg0.remote_mac,
1290 dst=self.pg0.local_mac) /
1291 IP(src="2.2.2.2", dst="1.1.1.2") /
1292 TCP(sport=1234, dport=1234) /
1293 Raw('\xa5' * 100))
1294 pkts_dst = p_dst * 257
1295 pkts_src = p_src * 257
1296
1297 self.send_and_assert_no_replies(self.pg0, pkts_dst,
1298 "IP in dst table")
1299 self.send_and_assert_no_replies(self.pg0, pkts_src,
1300 "IP in src table")
1301
1302 #
1303 # add a route in the dst table to forward via pg1
1304 #
1305 route_in_dst = VppIpRoute(self, "1.1.1.1", 32,
1306 [VppRoutePath(self.pg1.remote_ip4,
1307 self.pg1.sw_if_index)],
1308 table_id=1)
1309 route_in_dst.add_vpp_config()
1310 self.send_and_expect(self.pg0, pkts_dst, self.pg1)
1311
1312 #
1313 # add a route in the src table to forward via pg2
1314 #
1315 route_in_src = VppIpRoute(self, "2.2.2.2", 32,
1316 [VppRoutePath(self.pg2.remote_ip4,
1317 self.pg2.sw_if_index)],
1318 table_id=2)
1319 route_in_src.add_vpp_config()
1320 self.send_and_expect(self.pg0, pkts_src, self.pg2)
1321
Neale Rannsce9e0b42018-08-01 12:53:17 -07001322 #
1323 # loop in the lookup DP
1324 #
1325 route_loop = VppIpRoute(self, "2.2.2.3", 32,
1326 [VppRoutePath("0.0.0.0",
1327 0xffffffff,
1328 nh_table_id=0)])
1329 route_loop.add_vpp_config()
1330
1331 p_l = (Ether(src=self.pg0.remote_mac,
1332 dst=self.pg0.local_mac) /
1333 IP(src="2.2.2.4", dst="2.2.2.3") /
1334 TCP(sport=1234, dport=1234) /
1335 Raw('\xa5' * 100))
1336
1337 self.send_and_assert_no_replies(self.pg0, p_l * 257,
1338 "IP lookup loop")
1339
Neale Ranns054c03a2017-10-13 05:15:07 -07001340
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001341class TestIPInput(VppTestCase):
1342 """ IPv4 Input Exceptions """
1343
1344 def setUp(self):
1345 super(TestIPInput, self).setUp()
1346
1347 self.create_pg_interfaces(range(2))
1348
1349 for i in self.pg_interfaces:
1350 i.admin_up()
1351 i.config_ip4()
1352 i.resolve_arp()
1353
1354 def tearDown(self):
1355 super(TestIPInput, self).tearDown()
1356 for i in self.pg_interfaces:
1357 i.unconfig_ip4()
1358 i.admin_down()
1359
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001360 def test_ip_input(self):
1361 """ IP Input Exceptions """
1362
1363 # i can't find a way in scapy to construct an IP packet
1364 # with a length less than the IP header length
1365
1366 #
1367 # Packet too short - this is forwarded
1368 #
1369 p_short = (Ether(src=self.pg0.remote_mac,
1370 dst=self.pg0.local_mac) /
1371 IP(src=self.pg0.remote_ip4,
1372 dst=self.pg1.remote_ip4,
1373 len=40) /
1374 UDP(sport=1234, dport=1234) /
1375 Raw('\xa5' * 100))
1376
1377 rx = self.send_and_expect(self.pg0, p_short * 65, self.pg1)
1378
1379 #
1380 # Packet too long - this is dropped
1381 #
1382 p_long = (Ether(src=self.pg0.remote_mac,
1383 dst=self.pg0.local_mac) /
1384 IP(src=self.pg0.remote_ip4,
1385 dst=self.pg1.remote_ip4,
1386 len=400) /
1387 UDP(sport=1234, dport=1234) /
1388 Raw('\xa5' * 100))
1389
1390 rx = self.send_and_assert_no_replies(self.pg0, p_long * 65,
1391 "too long")
1392
1393 #
1394 # bad chksum - this is dropped
1395 #
1396 p_chksum = (Ether(src=self.pg0.remote_mac,
1397 dst=self.pg0.local_mac) /
1398 IP(src=self.pg0.remote_ip4,
1399 dst=self.pg1.remote_ip4,
1400 chksum=400) /
1401 UDP(sport=1234, dport=1234) /
1402 Raw('\xa5' * 100))
1403
1404 rx = self.send_and_assert_no_replies(self.pg0, p_chksum * 65,
1405 "bad checksum")
1406
1407 #
1408 # bad version - this is dropped
1409 #
1410 p_ver = (Ether(src=self.pg0.remote_mac,
1411 dst=self.pg0.local_mac) /
1412 IP(src=self.pg0.remote_ip4,
1413 dst=self.pg1.remote_ip4,
1414 version=3) /
1415 UDP(sport=1234, dport=1234) /
1416 Raw('\xa5' * 100))
1417
1418 rx = self.send_and_assert_no_replies(self.pg0, p_ver * 65,
1419 "funky version")
1420
1421 #
1422 # fragment offset 1 - this is dropped
1423 #
1424 p_frag = (Ether(src=self.pg0.remote_mac,
1425 dst=self.pg0.local_mac) /
1426 IP(src=self.pg0.remote_ip4,
1427 dst=self.pg1.remote_ip4,
1428 frag=1) /
1429 UDP(sport=1234, dport=1234) /
1430 Raw('\xa5' * 100))
1431
1432 rx = self.send_and_assert_no_replies(self.pg0, p_frag * 65,
1433 "frag offset")
1434
1435 #
1436 # TTL expired packet
1437 #
1438 p_ttl = (Ether(src=self.pg0.remote_mac,
1439 dst=self.pg0.local_mac) /
1440 IP(src=self.pg0.remote_ip4,
1441 dst=self.pg1.remote_ip4,
1442 ttl=1) /
1443 UDP(sport=1234, dport=1234) /
1444 Raw('\xa5' * 100))
1445
1446 rx = self.send_and_expect(self.pg0, p_ttl * 65, self.pg0)
1447
1448 rx = rx[0]
1449 icmp = rx[ICMP]
1450
1451 self.assertEqual(icmptypes[icmp.type], "time-exceeded")
1452 self.assertEqual(icmpcodes[icmp.type][icmp.code],
1453 "ttl-zero-during-transit")
1454 self.assertEqual(icmp.src, self.pg0.remote_ip4)
1455 self.assertEqual(icmp.dst, self.pg1.remote_ip4)
1456
Neale Rannsffd78d12018-02-09 06:05:16 -08001457 #
1458 # MTU exceeded
1459 #
1460 p_mtu = (Ether(src=self.pg0.remote_mac,
1461 dst=self.pg0.local_mac) /
1462 IP(src=self.pg0.remote_ip4,
1463 dst=self.pg1.remote_ip4,
Ole Troan8a9c8f12018-05-18 11:01:31 +02001464 ttl=10, flags='DF') /
Neale Rannsffd78d12018-02-09 06:05:16 -08001465 UDP(sport=1234, dport=1234) /
1466 Raw('\xa5' * 2000))
1467
Ole Troand7231612018-06-07 10:17:57 +02001468 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1500, 0, 0, 0])
Neale Rannsffd78d12018-02-09 06:05:16 -08001469
1470 rx = self.send_and_expect(self.pg0, p_mtu * 65, self.pg0)
1471 rx = rx[0]
1472 icmp = rx[ICMP]
1473
1474 self.assertEqual(icmptypes[icmp.type], "dest-unreach")
1475 self.assertEqual(icmpcodes[icmp.type][icmp.code],
1476 "fragmentation-needed")
1477 self.assertEqual(icmp.src, self.pg0.remote_ip4)
1478 self.assertEqual(icmp.dst, self.pg1.remote_ip4)
1479
Ole Troand7231612018-06-07 10:17:57 +02001480 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [2500, 0, 0, 0])
Neale Rannsffd78d12018-02-09 06:05:16 -08001481 rx = self.send_and_expect(self.pg0, p_mtu * 65, self.pg1)
1482
Ole Troand7231612018-06-07 10:17:57 +02001483 # Reset MTU for subsequent tests
1484 self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0])
Neale Ranns4c7c8e52017-10-21 09:37:55 -07001485
Neale Rannsbe2286b2018-12-09 12:54:51 -08001486 #
1487 # source address 0.0.0.0 and 25.255.255.255 and for-us
1488 #
1489 p_s0 = (Ether(src=self.pg0.remote_mac,
1490 dst=self.pg0.local_mac) /
1491 IP(src="0.0.0.0",
1492 dst=self.pg0.local_ip4) /
1493 ICMP(id=4, seq=4) /
1494 Raw(load='\x0a' * 18))
1495 rx = self.send_and_assert_no_replies(self.pg0, p_s0 * 17)
1496
1497 p_s0 = (Ether(src=self.pg0.remote_mac,
1498 dst=self.pg0.local_mac) /
1499 IP(src="255.255.255.255",
1500 dst=self.pg0.local_ip4) /
1501 ICMP(id=4, seq=4) /
1502 Raw(load='\x0a' * 18))
1503 rx = self.send_and_assert_no_replies(self.pg0, p_s0 * 17)
1504
Neale Ranns1855b8e2018-07-11 10:31:26 -07001505
1506class TestIPDirectedBroadcast(VppTestCase):
1507 """ IPv4 Directed Broadcast """
1508
1509 def setUp(self):
1510 super(TestIPDirectedBroadcast, self).setUp()
1511
1512 self.create_pg_interfaces(range(2))
1513
1514 for i in self.pg_interfaces:
1515 i.admin_up()
1516
1517 def tearDown(self):
1518 super(TestIPDirectedBroadcast, self).tearDown()
1519 for i in self.pg_interfaces:
1520 i.admin_down()
1521
1522 def test_ip_input(self):
1523 """ IP Directed Broadcast """
1524
1525 #
1526 # set the directed broadcast on pg0 first, then config IP4 addresses
1527 # for pg1 directed broadcast is always disabled
1528 self.vapi.sw_interface_set_ip_directed_broadcast(
1529 self.pg0.sw_if_index, 1)
1530
1531 p0 = (Ether(src=self.pg1.remote_mac,
1532 dst=self.pg1.local_mac) /
1533 IP(src="1.1.1.1",
1534 dst=self.pg0._local_ip4_bcast) /
1535 UDP(sport=1234, dport=1234) /
1536 Raw('\xa5' * 2000))
1537 p1 = (Ether(src=self.pg0.remote_mac,
1538 dst=self.pg0.local_mac) /
1539 IP(src="1.1.1.1",
1540 dst=self.pg1._local_ip4_bcast) /
1541 UDP(sport=1234, dport=1234) /
1542 Raw('\xa5' * 2000))
1543
1544 self.pg0.config_ip4()
1545 self.pg0.resolve_arp()
1546 self.pg1.config_ip4()
1547 self.pg1.resolve_arp()
1548
1549 #
1550 # test packet is L2 broadcast
1551 #
1552 rx = self.send_and_expect(self.pg1, p0 * 65, self.pg0)
1553 self.assertTrue(rx[0][Ether].dst, "ff:ff:ff:ff:ff:ff")
1554
1555 self.send_and_assert_no_replies(self.pg0, p1 * 65,
1556 "directed broadcast disabled")
1557
1558 #
1559 # toggle directed broadcast on pg0
1560 #
1561 self.vapi.sw_interface_set_ip_directed_broadcast(
1562 self.pg0.sw_if_index, 0)
1563 self.send_and_assert_no_replies(self.pg1, p0 * 65,
1564 "directed broadcast disabled")
1565
1566 self.vapi.sw_interface_set_ip_directed_broadcast(
1567 self.pg0.sw_if_index, 1)
1568 rx = self.send_and_expect(self.pg1, p0 * 65, self.pg0)
1569
1570 self.pg0.unconfig_ip4()
1571 self.pg1.unconfig_ip4()
1572
1573
mu.duojiao59a82952018-10-11 14:27:30 +08001574class TestIPLPM(VppTestCase):
1575 """ IPv4 longest Prefix Match """
1576
1577 def setUp(self):
1578 super(TestIPLPM, self).setUp()
1579
1580 self.create_pg_interfaces(range(4))
1581
1582 for i in self.pg_interfaces:
1583 i.admin_up()
1584 i.config_ip4()
1585 i.resolve_arp()
1586
1587 def tearDown(self):
1588 super(TestIPLPM, self).tearDown()
1589 for i in self.pg_interfaces:
1590 i.admin_down()
1591 i.unconfig_ip4()
1592
1593 def test_ip_lpm(self):
1594 """ IP longest Prefix Match """
1595
1596 s_24 = VppIpRoute(self, "10.1.2.0", 24,
1597 [VppRoutePath(self.pg1.remote_ip4,
1598 self.pg1.sw_if_index)])
1599 s_24.add_vpp_config()
1600 s_8 = VppIpRoute(self, "10.0.0.0", 8,
1601 [VppRoutePath(self.pg2.remote_ip4,
1602 self.pg2.sw_if_index)])
1603 s_8.add_vpp_config()
1604
1605 p_8 = (Ether(src=self.pg0.remote_mac,
1606 dst=self.pg0.local_mac) /
1607 IP(src="1.1.1.1",
1608 dst="10.1.1.1") /
1609 UDP(sport=1234, dport=1234) /
1610 Raw('\xa5' * 2000))
1611 p_24 = (Ether(src=self.pg0.remote_mac,
1612 dst=self.pg0.local_mac) /
1613 IP(src="1.1.1.1",
1614 dst="10.1.2.1") /
1615 UDP(sport=1234, dport=1234) /
1616 Raw('\xa5' * 2000))
1617
1618 self.logger.info(self.vapi.cli("sh ip fib mtrie"))
1619 rx = self.send_and_expect(self.pg0, p_8 * 65, self.pg2)
1620 rx = self.send_and_expect(self.pg0, p_24 * 65, self.pg1)
1621
1622
Juraj Sloboda68b7cb82018-10-16 12:18:21 +02001623class TestIPv4Frag(VppTestCase):
1624 """ IPv4 fragmentation """
1625
1626 @classmethod
1627 def setUpClass(cls):
1628 super(TestIPv4Frag, cls).setUpClass()
1629
1630 cls.create_pg_interfaces([0, 1])
1631 cls.src_if = cls.pg0
1632 cls.dst_if = cls.pg1
1633
1634 # setup all interfaces
1635 for i in cls.pg_interfaces:
1636 i.admin_up()
1637 i.config_ip4()
1638 i.resolve_arp()
1639
1640 def test_frag_large_packets(self):
1641 """ Fragmentation of large packets """
1642
1643 p = (Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
1644 IP(src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4) /
1645 UDP(sport=1234, dport=5678) / Raw())
1646 self.extend_packet(p, 6000, "abcde")
1647 saved_payload = p[Raw].load
1648
1649 # Force fragmentation by setting MTU of output interface
1650 # lower than packet size
1651 self.vapi.sw_interface_set_mtu(self.dst_if.sw_if_index,
1652 [5000, 0, 0, 0])
1653
1654 self.pg_enable_capture()
1655 self.src_if.add_stream(p)
1656 self.pg_start()
1657
1658 # Expecting 3 fragments because size of created fragments currently
1659 # cannot be larger then VPP buffer size (which is 2048)
1660 packets = self.dst_if.get_capture(3)
1661
1662 # Assume VPP sends the fragments in order
1663 payload = ''
1664 for p in packets:
1665 payload_offset = p.frag * 8
1666 if payload_offset > 0:
1667 payload_offset -= 8 # UDP header is not in payload
1668 self.assert_equal(payload_offset, len(payload))
1669 payload += p[Raw].load
1670 self.assert_equal(payload, saved_payload, "payload")
1671
1672
Damjan Marionf56b77a2016-10-03 19:44:57 +02001673if __name__ == '__main__':
Klement Sekeraf62ae122016-10-11 11:47:09 +02001674 unittest.main(testRunner=VppTestRunner)