blob: 48c04f70e96c7fcd4a5d477848c989e3990b9908 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Jane546d3b2016-12-08 13:10:03 +01002"""IP4 VRF Multi-instance Test Case HLD:
3
4**NOTES:**
5 - higher number of pg-ip4 interfaces causes problems => only 15 pg-ip4 \
Dave Wallaced1706812021-08-12 18:36:02 -04006 interfaces in 5 VRFs are tested
Jane546d3b2016-12-08 13:10:03 +01007 - jumbo packets in configuration with 15 pg-ip4 interfaces leads to \
Dave Wallaced1706812021-08-12 18:36:02 -04008 problems too
Jane546d3b2016-12-08 13:10:03 +01009
10**config 1**
11 - add 15 pg-ip4 interfaces
12 - configure 5 hosts per pg-ip4 interface
13 - configure 4 VRFs
14 - add 3 pg-ip4 interfaces per VRF
15
16**test 1**
17 - send IP4 packets between all pg-ip4 interfaces in all VRF groups
18
19**verify 1**
20 - check VRF data by parsing output of ip_fib_dump API command
Dave Wallaced1706812021-08-12 18:36:02 -040021 - all packets received correctly in case of pg-ip4 interfaces in the
22 same VRF
Jane546d3b2016-12-08 13:10:03 +010023 - no packet received in case of pg-ip4 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020024 - no packet received in case of pg-ip4 interfaces in different VRFs
Jane546d3b2016-12-08 13:10:03 +010025
26**config 2**
Jan Gelety95c87b52017-02-27 10:46:14 +010027 - reset 2 VRFs
Jane546d3b2016-12-08 13:10:03 +010028
29**test 2**
30 - send IP4 packets between all pg-ip4 interfaces in all VRF groups
31
32**verify 2**
Dave Wallaced1706812021-08-12 18:36:02 -040033 - all packets received correctly in case of pg-ip4 interfaces in the
34 same VRF
Jane546d3b2016-12-08 13:10:03 +010035 - no packet received in case of pg-ip4 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020036 - no packet received in case of pg-ip4 interfaces in different VRFs
Jane546d3b2016-12-08 13:10:03 +010037
38**config 3**
Jan Gelety95c87b52017-02-27 10:46:14 +010039 - add 1 of reset VRFs and 1 new VRF
Jane546d3b2016-12-08 13:10:03 +010040
41**test 3**
42 - send IP4 packets between all pg-ip4 interfaces in all VRF groups
43
44**verify 3**
45 - check VRF data by parsing output of ip_fib_dump API command
Dave Wallaced1706812021-08-12 18:36:02 -040046 - all packets received correctly in case of pg-ip4 interfaces in the
47 same VRF
Jane546d3b2016-12-08 13:10:03 +010048 - no packet received in case of pg-ip4 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020049 - no packet received in case of pg-ip4 interfaces in different VRFs
Jane546d3b2016-12-08 13:10:03 +010050
51**config 4**
Jan Gelety95c87b52017-02-27 10:46:14 +010052 - reset all created VRFs
Jane546d3b2016-12-08 13:10:03 +010053
54**test 4**
55 - send IP4 packets between all pg-ip4 interfaces in all VRF groups
56
57**verify 4**
58 - check VRF data by parsing output of ip_fib_dump API command
Dave Wallaced1706812021-08-12 18:36:02 -040059 - all packets received correctly in case of pg-ip4 interfaces in the
60 same VRF
Jane546d3b2016-12-08 13:10:03 +010061 - no packet received in case of pg-ip4 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020062 - no packet received in case of pg-ip4 interfaces in different VRFs
Jane546d3b2016-12-08 13:10:03 +010063"""
64
65import unittest
66import random
Jan Gelety95c87b52017-02-27 10:46:14 +010067import socket
Jane546d3b2016-12-08 13:10:03 +010068
Paul Vinciguerraa7427ec2019-03-10 10:04:23 -070069import scapy.compat
Jane546d3b2016-12-08 13:10:03 +010070from scapy.packet import Raw
snaramre5d4b8912019-12-13 23:39:35 +000071from scapy.layers.l2 import Ether, ARP
72from scapy.layers.inet import IP, UDP
Jane546d3b2016-12-08 13:10:03 +010073
74from framework import VppTestCase, VppTestRunner
75from util import ppp
Jan Gelety95c87b52017-02-27 10:46:14 +010076from vrf import VRFState
Jane546d3b2016-12-08 13:10:03 +010077
78
79def is_ipv4_misc(p):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020080 """Is packet one of uninteresting IPv4 broadcasts?"""
Jane546d3b2016-12-08 13:10:03 +010081 if p.haslayer(ARP):
82 return True
83 return False
84
85
86class TestIp4VrfMultiInst(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087 """IP4 VRF Multi-instance Test Case"""
Jane546d3b2016-12-08 13:10:03 +010088
89 @classmethod
90 def setUpClass(cls):
91 """
92 Perform standard class setup (defined by class method setUpClass in
93 class VppTestCase) before running the test case, set test case related
94 variables and configure VPP.
95 """
96 super(TestIp4VrfMultiInst, cls).setUpClass()
97
98 # Test variables
99 cls.hosts_per_pg = 5
100 cls.nr_of_vrfs = 5
101 cls.pg_ifs_per_vrf = 3
102
103 try:
104 # Create pg interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200105 cls.create_pg_interfaces(range(cls.nr_of_vrfs * cls.pg_ifs_per_vrf))
Jane546d3b2016-12-08 13:10:03 +0100106
107 # Packet flows mapping pg0 -> pg1, pg2 etc.
108 cls.flows = dict()
109 for i in range(len(cls.pg_interfaces)):
Ole Troan19757332019-10-18 14:54:30 +0200110 multiplicand = i // cls.pg_ifs_per_vrf
Jane546d3b2016-12-08 13:10:03 +0100111 pg_list = [
112 cls.pg_interfaces[multiplicand * cls.pg_ifs_per_vrf + j]
113 for j in range(cls.pg_ifs_per_vrf)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200114 if (multiplicand * cls.pg_ifs_per_vrf + j) != i
115 ]
Jane546d3b2016-12-08 13:10:03 +0100116 cls.flows[cls.pg_interfaces[i]] = pg_list
117
118 # Packet sizes - jumbo packet (9018 bytes) skipped
119 cls.pg_if_packet_sizes = [64, 512, 1518]
120
121 # Set up all interfaces
122 for pg_if in cls.pg_interfaces:
123 pg_if.admin_up()
124 pg_if.generate_remote_hosts(cls.hosts_per_pg)
125
126 # Create list of VRFs
127 cls.vrf_list = list()
128
Jan Gelety95c87b52017-02-27 10:46:14 +0100129 # Create list of reset VRFs
130 cls.vrf_reset_list = list()
Jane546d3b2016-12-08 13:10:03 +0100131
132 # Create list of pg_interfaces in VRFs
133 cls.pg_in_vrf = list()
134
Jan Geletyd16ba622018-06-21 16:57:47 +0200135 # Create list of pg_interfaces not in VRFs
Jane546d3b2016-12-08 13:10:03 +0100136 cls.pg_not_in_vrf = [pg_if for pg_if in cls.pg_interfaces]
137
138 # Create mapping of pg_interfaces to VRF IDs
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200139 cls.pg_if_sets = dict()
Jane546d3b2016-12-08 13:10:03 +0100140 for i in range(cls.nr_of_vrfs):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200141 set_id = i + 1
Jane546d3b2016-12-08 13:10:03 +0100142 pg_list = [
143 cls.pg_interfaces[i * cls.pg_ifs_per_vrf + j]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200144 for j in range(cls.pg_ifs_per_vrf)
145 ]
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200146 cls.pg_if_sets[set_id] = pg_list
Jane546d3b2016-12-08 13:10:03 +0100147
148 except Exception:
149 super(TestIp4VrfMultiInst, cls).tearDownClass()
150 raise
151
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700152 @classmethod
153 def tearDownClass(cls):
154 super(TestIp4VrfMultiInst, cls).tearDownClass()
155
Jane546d3b2016-12-08 13:10:03 +0100156 def setUp(self):
Jan Gelety3900fe52017-01-26 15:46:19 +0100157 """
Jane546d3b2016-12-08 13:10:03 +0100158 Clear trace and packet infos before running each test.
159 """
160 super(TestIp4VrfMultiInst, self).setUp()
161 self.reset_packet_infos()
162
163 def tearDown(self):
164 """
165 Show various debug prints after each test.
166 """
167 super(TestIp4VrfMultiInst, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700168
169 def show_commands_at_teardown(self):
170 self.logger.info(self.vapi.ppcli("show ip fib"))
Neale Rannscbe25aa2019-09-30 10:53:31 +0000171 self.logger.info(self.vapi.ppcli("show ip4 neighbors"))
Jane546d3b2016-12-08 13:10:03 +0100172
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200173 def _assign_interfaces(self, vrf_id, if_set_id):
174 for i in range(self.pg_ifs_per_vrf):
175 pg_if = self.pg_if_sets[if_set_id][i]
176 pg_if.set_table_ip4(vrf_id)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200177 self.logger.info(
178 "pg-interface %s added to IPv4 VRF ID %d" % (pg_if.name, vrf_id)
179 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200180 if pg_if not in self.pg_in_vrf:
181 self.pg_in_vrf.append(pg_if)
182 if pg_if in self.pg_not_in_vrf:
183 self.pg_not_in_vrf.remove(pg_if)
184 pg_if.config_ip4()
185 pg_if.configure_ipv4_neighbors()
186
Jane546d3b2016-12-08 13:10:03 +0100187 def create_vrf_and_assign_interfaces(self, count, start=1):
Jan Gelety3900fe52017-01-26 15:46:19 +0100188 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200189 Create required number of FIB tables / VRFs, put 3 pg-ip4 interfaces
Jane546d3b2016-12-08 13:10:03 +0100190 to every FIB table / VRF.
191
192 :param int count: Number of FIB tables / VRFs to be created.
193 :param int start: Starting number of the FIB table / VRF ID. \
194 (Default value = 1)
195 """
196
197 for i in range(count):
198 vrf_id = i + start
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200199 self.vapi.ip_table_add_del(is_add=1, table={"table_id": vrf_id})
Jane546d3b2016-12-08 13:10:03 +0100200 self.logger.info("IPv4 VRF ID %d created" % vrf_id)
201 if vrf_id not in self.vrf_list:
202 self.vrf_list.append(vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100203 if vrf_id in self.vrf_reset_list:
204 self.vrf_reset_list.remove(vrf_id)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200205 self._assign_interfaces(vrf_id, vrf_id)
Jane546d3b2016-12-08 13:10:03 +0100206 self.logger.debug(self.vapi.ppcli("show ip fib"))
Neale Rannscbe25aa2019-09-30 10:53:31 +0000207 self.logger.debug(self.vapi.ppcli("show ip4 neighbors"))
Jane546d3b2016-12-08 13:10:03 +0100208
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200209 def create_vrf_by_id_and_assign_interfaces(self, set_id, vrf_id=0xFFFFFFFF):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200210 """
211 Create a FIB table / VRF by vrf_id, put 3 pg-ip4 interfaces
212 to FIB table / VRF.
213
214 :param int vrf_id: Required table ID / VRF ID. \
215 (Default value = 0xffffffff, ID will be selected automatically)
216 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200217 ret = self.vapi.ip_table_allocate(table={"table_id": vrf_id})
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200218 vrf_id = ret.table.table_id
219 self.logger.info("IPv4 VRF ID %d created" % vrf_id)
220 if vrf_id not in self.vrf_list:
221 self.vrf_list.append(vrf_id)
222 if vrf_id in self.vrf_reset_list:
223 self.vrf_reset_list.remove(vrf_id)
224 self._assign_interfaces(vrf_id, set_id)
225 self.logger.debug(self.vapi.ppcli("show ip fib"))
226 self.logger.debug(self.vapi.ppcli("show ip4 neighbors"))
227
228 return vrf_id
229
230 def reset_vrf_and_remove_from_vrf_list(self, vrf_id, if_set_id=None):
Jan Gelety3900fe52017-01-26 15:46:19 +0100231 """
Jan Gelety95c87b52017-02-27 10:46:14 +0100232 Reset required FIB table / VRF and remove it from VRF list.
Jane546d3b2016-12-08 13:10:03 +0100233
Jan Gelety95c87b52017-02-27 10:46:14 +0100234 :param int vrf_id: The FIB table / VRF ID to be reset.
Jane546d3b2016-12-08 13:10:03 +0100235 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200236 if if_set_id is None:
237 if_set_id = vrf_id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200238 self.vapi.ip_table_flush(table={"table_id": vrf_id})
Jane546d3b2016-12-08 13:10:03 +0100239 if vrf_id in self.vrf_list:
240 self.vrf_list.remove(vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100241 if vrf_id not in self.vrf_reset_list:
242 self.vrf_reset_list.append(vrf_id)
Jane546d3b2016-12-08 13:10:03 +0100243 for j in range(self.pg_ifs_per_vrf):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200244 pg_if = self.pg_if_sets[if_set_id][j]
Neale Ranns4008ac92017-02-13 23:20:04 -0800245 pg_if.unconfig_ip4()
Jane546d3b2016-12-08 13:10:03 +0100246 if pg_if in self.pg_in_vrf:
247 self.pg_in_vrf.remove(pg_if)
248 if pg_if not in self.pg_not_in_vrf:
249 self.pg_not_in_vrf.append(pg_if)
Jan Gelety95c87b52017-02-27 10:46:14 +0100250 self.logger.info("IPv4 VRF ID %d reset finished" % vrf_id)
Jane546d3b2016-12-08 13:10:03 +0100251 self.logger.debug(self.vapi.ppcli("show ip fib"))
Neale Rannscbe25aa2019-09-30 10:53:31 +0000252 self.logger.debug(self.vapi.ppcli("show ip neighbors"))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200253 self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id})
Jane546d3b2016-12-08 13:10:03 +0100254
255 def create_stream(self, src_if, packet_sizes):
256 """
257 Create input packet stream for defined interface using hosts list.
258
259 :param object src_if: Interface to create packet stream for.
260 :param list packet_sizes: List of required packet sizes.
261 :return: Stream of packets.
262 """
263 pkts = []
264 src_hosts = src_if.remote_hosts
265 for dst_if in self.flows[src_if]:
266 for dst_host in dst_if.remote_hosts:
267 src_host = random.choice(src_hosts)
268 pkt_info = self.create_packet_info(src_if, dst_if)
269 payload = self.info_to_payload(pkt_info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200270 p = (
271 Ether(dst=src_if.local_mac, src=src_host.mac)
272 / IP(src=src_host.ip4, dst=dst_host.ip4)
273 / UDP(sport=1234, dport=1234)
274 / Raw(payload)
275 )
Jane546d3b2016-12-08 13:10:03 +0100276 pkt_info.data = p.copy()
277 size = random.choice(packet_sizes)
278 self.extend_packet(p, size)
279 pkts.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200280 self.logger.debug(
281 "Input stream created for port %s. Length: %u pkt(s)"
282 % (src_if.name, len(pkts))
283 )
Jane546d3b2016-12-08 13:10:03 +0100284 return pkts
285
Jan Geletyd16ba622018-06-21 16:57:47 +0200286 def create_stream_crosswise_vrf(self, src_if, vrf_id, packet_sizes):
287 """
288 Create input packet stream for negative test for leaking across
289 different VRFs for defined interface using hosts list.
290
291 :param object src_if: Interface to create packet stream for.
292 :param int vrf_id: The FIB table / VRF ID where src_if is assigned.
293 :param list packet_sizes: List of required packet sizes.
294 :return: Stream of packets.
295 """
296 pkts = []
297 src_hosts = src_if.remote_hosts
298 vrf_lst = list(self.vrf_list)
299 vrf_lst.remove(vrf_id)
300 for vrf in vrf_lst:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200301 for dst_if in self.pg_if_sets[vrf]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200302 for dst_host in dst_if.remote_hosts:
303 src_host = random.choice(src_hosts)
304 pkt_info = self.create_packet_info(src_if, dst_if)
305 payload = self.info_to_payload(pkt_info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200306 p = (
307 Ether(dst=src_if.local_mac, src=src_host.mac)
308 / IP(src=src_host.ip4, dst=dst_host.ip4)
309 / UDP(sport=1234, dport=1234)
310 / Raw(payload)
311 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200312 pkt_info.data = p.copy()
313 size = random.choice(packet_sizes)
314 self.extend_packet(p, size)
315 pkts.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200316 self.logger.debug(
317 "Input stream created for port %s. Length: %u pkt(s)"
318 % (src_if.name, len(pkts))
319 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200320 return pkts
321
Jane546d3b2016-12-08 13:10:03 +0100322 def verify_capture(self, pg_if, capture):
323 """
324 Verify captured input packet stream for defined interface.
325
326 :param object pg_if: Interface to verify captured packet stream for.
327 :param list capture: Captured packet stream.
328 """
329 last_info = dict()
330 for i in self.pg_interfaces:
331 last_info[i.sw_if_index] = None
332 dst_sw_if_index = pg_if.sw_if_index
333 for packet in capture:
334 try:
335 ip = packet[IP]
336 udp = packet[UDP]
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800337 payload_info = self.payload_to_info(packet[Raw])
Jane546d3b2016-12-08 13:10:03 +0100338 packet_index = payload_info.index
339 self.assertEqual(payload_info.dst, dst_sw_if_index)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200340 self.logger.debug(
341 "Got packet on port %s: src=%u (id=%u)"
342 % (pg_if.name, payload_info.src, packet_index)
343 )
Jane546d3b2016-12-08 13:10:03 +0100344 next_info = self.get_next_packet_info_for_interface2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200345 payload_info.src, dst_sw_if_index, last_info[payload_info.src]
346 )
Jane546d3b2016-12-08 13:10:03 +0100347 last_info[payload_info.src] = next_info
348 self.assertIsNotNone(next_info)
349 self.assertEqual(packet_index, next_info.index)
350 saved_packet = next_info.data
351 # Check standard fields
352 self.assertEqual(ip.src, saved_packet[IP].src)
353 self.assertEqual(ip.dst, saved_packet[IP].dst)
354 self.assertEqual(udp.sport, saved_packet[UDP].sport)
355 self.assertEqual(udp.dport, saved_packet[UDP].dport)
356 except:
357 self.logger.error(ppp("Unexpected or invalid packet:", packet))
358 raise
359 for i in self.pg_interfaces:
360 remaining_packet = self.get_next_packet_info_for_interface2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200361 i, dst_sw_if_index, last_info[i.sw_if_index]
362 )
Jane546d3b2016-12-08 13:10:03 +0100363 self.assertIsNone(
364 remaining_packet,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200365 "Port %u: Packet expected from source %u didn't arrive"
366 % (dst_sw_if_index, i.sw_if_index),
367 )
Jane546d3b2016-12-08 13:10:03 +0100368
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200369 def verify_vrf(self, vrf_id, if_set_id=None):
Jane546d3b2016-12-08 13:10:03 +0100370 """
371 Check if the FIB table / VRF ID is configured.
372
373 :param int vrf_id: The FIB table / VRF ID to be verified.
374 :return: 1 if the FIB table / VRF ID is configured, otherwise return 0.
375 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200376 if if_set_id is None:
377 if_set_id = vrf_id
Neale Ranns097fa662018-05-01 05:17:55 -0700378 ip_fib_dump = self.vapi.ip_route_dump(vrf_id)
379 vrf_exist = len(ip_fib_dump)
Jane546d3b2016-12-08 13:10:03 +0100380 vrf_count = 0
381 for ip_fib_details in ip_fib_dump:
Neale Ranns097fa662018-05-01 05:17:55 -0700382 addr = ip_fib_details.route.prefix.network_address
383 found = False
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200384 for pg_if in self.pg_if_sets[if_set_id]:
Neale Ranns097fa662018-05-01 05:17:55 -0700385 if found:
386 break
387 for host in pg_if.remote_hosts:
388 if str(addr) == host.ip4:
389 vrf_count += 1
390 found = True
Jan Gelety95c87b52017-02-27 10:46:14 +0100391 break
Jan Gelety95c87b52017-02-27 10:46:14 +0100392 if not vrf_exist and vrf_count == 0:
Jane546d3b2016-12-08 13:10:03 +0100393 self.logger.info("IPv4 VRF ID %d is not configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100394 return VRFState.not_configured
395 elif vrf_exist and vrf_count == 0:
396 self.logger.info("IPv4 VRF ID %d has been reset" % vrf_id)
397 return VRFState.reset
Jane546d3b2016-12-08 13:10:03 +0100398 else:
399 self.logger.info("IPv4 VRF ID %d is configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100400 return VRFState.configured
Jane546d3b2016-12-08 13:10:03 +0100401
402 def run_verify_test(self):
403 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200404 Create packet streams for all configured pg interfaces, send all \
Jane546d3b2016-12-08 13:10:03 +0100405 prepared packet streams and verify that:
Jan Geletyd16ba622018-06-21 16:57:47 +0200406 - all packets received correctly on all pg-ip4 interfaces assigned
407 to VRFs
408 - no packet received on all pg-ip4 interfaces not assigned to VRFs
Jane546d3b2016-12-08 13:10:03 +0100409
Jan Geletyd16ba622018-06-21 16:57:47 +0200410 :raise RuntimeError: If no packet captured on pg-ip4 interface assigned
411 to VRF or if any packet is captured on pg-ip4 interface not
412 assigned to VRF.
Jane546d3b2016-12-08 13:10:03 +0100413 """
414 # Test
415 # Create incoming packet streams for packet-generator interfaces
416 for pg_if in self.pg_interfaces:
417 pkts = self.create_stream(pg_if, self.pg_if_packet_sizes)
418 pg_if.add_stream(pkts)
419
420 # Enable packet capture and start packet sending
421 self.pg_enable_capture(self.pg_interfaces)
422 self.pg_start()
423
424 # Verify
425 # Verify outgoing packet streams per packet-generator interface
426 for pg_if in self.pg_interfaces:
427 if pg_if in self.pg_in_vrf:
428 capture = pg_if.get_capture(remark="interface is in VRF")
429 self.verify_capture(pg_if, capture)
430 elif pg_if in self.pg_not_in_vrf:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200431 pg_if.assert_nothing_captured(
432 remark="interface is not in VRF", filter_out_fn=is_ipv4_misc
433 )
Jane546d3b2016-12-08 13:10:03 +0100434 self.logger.debug("No capture for interface %s" % pg_if.name)
435 else:
436 raise Exception("Unknown interface: %s" % pg_if.name)
437
Jan Geletyd16ba622018-06-21 16:57:47 +0200438 def run_crosswise_vrf_test(self):
439 """
440 Create packet streams for every pg-ip4 interface in VRF towards all
Dave Wallaced1706812021-08-12 18:36:02 -0400441 pg-ip4 interfaces in other VRFs, send all prepared packet streams and
Jan Geletyd16ba622018-06-21 16:57:47 +0200442 verify that:
Dave Wallaced1706812021-08-12 18:36:02 -0400443
444 - no packet received on all configured pg-ip4 interfaces
Jan Geletyd16ba622018-06-21 16:57:47 +0200445
446 :raise RuntimeError: If any packet is captured on any pg-ip4 interface.
447 """
448 # Test
449 # Create incoming packet streams for packet-generator interfaces
450 for vrf_id in self.vrf_list:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200451 for pg_if in self.pg_if_sets[vrf_id]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200452 pkts = self.create_stream_crosswise_vrf(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200453 pg_if, vrf_id, self.pg_if_packet_sizes
454 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200455 pg_if.add_stream(pkts)
456
457 # Enable packet capture and start packet sending
458 self.pg_enable_capture(self.pg_interfaces)
459 self.pg_start()
460
461 # Verify
462 # Verify outgoing packet streams per packet-generator interface
463 for pg_if in self.pg_interfaces:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200464 pg_if.assert_nothing_captured(
465 remark="interface is in other VRF", filter_out_fn=is_ipv4_misc
466 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200467 self.logger.debug("No capture for interface %s" % pg_if.name)
468
Jane546d3b2016-12-08 13:10:03 +0100469 def test_ip4_vrf_01(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200470 """IP4 VRF Multi-instance test 1 - create 4 VRFs"""
Jane546d3b2016-12-08 13:10:03 +0100471 # Config 1
472 # Create 4 VRFs
473 self.create_vrf_and_assign_interfaces(4)
474
475 # Verify 1
476 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200477 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jane546d3b2016-12-08 13:10:03 +0100478
479 # Test 1
480 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200481 self.run_crosswise_vrf_test()
Jane546d3b2016-12-08 13:10:03 +0100482
483 def test_ip4_vrf_02(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200484 """IP4 VRF Multi-instance test 2 - reset 2 VRFs"""
Jane546d3b2016-12-08 13:10:03 +0100485 # Config 2
Jan Gelety95c87b52017-02-27 10:46:14 +0100486 # Reset 2 VRFs
487 self.reset_vrf_and_remove_from_vrf_list(1)
488 self.reset_vrf_and_remove_from_vrf_list(2)
Jane546d3b2016-12-08 13:10:03 +0100489
490 # Verify 2
Jan Gelety95c87b52017-02-27 10:46:14 +0100491 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200492 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jane546d3b2016-12-08 13:10:03 +0100493 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200494 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jane546d3b2016-12-08 13:10:03 +0100495
496 # Test 2
497 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200498 self.run_crosswise_vrf_test()
Jane546d3b2016-12-08 13:10:03 +0100499
500 def test_ip4_vrf_03(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200501 """IP4 VRF Multi-instance 3 - add 2 VRFs"""
Jane546d3b2016-12-08 13:10:03 +0100502 # Config 3
Jan Gelety95c87b52017-02-27 10:46:14 +0100503 # Add 1 of reset VRFs and 1 new VRF
Jane546d3b2016-12-08 13:10:03 +0100504 self.create_vrf_and_assign_interfaces(1)
505 self.create_vrf_and_assign_interfaces(1, start=5)
506
507 # Verify 3
Jan Gelety95c87b52017-02-27 10:46:14 +0100508 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200509 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jane546d3b2016-12-08 13:10:03 +0100510 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200511 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jane546d3b2016-12-08 13:10:03 +0100512
513 # Test 3
514 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200515 self.run_crosswise_vrf_test()
Jane546d3b2016-12-08 13:10:03 +0100516
517 def test_ip4_vrf_04(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200518 """IP4 VRF Multi-instance test 4 - reset 4 VRFs"""
Jane546d3b2016-12-08 13:10:03 +0100519 # Config 4
Jan Gelety95c87b52017-02-27 10:46:14 +0100520 # Reset all VRFs (i.e. no VRF except VRF=0 configured)
Jane546d3b2016-12-08 13:10:03 +0100521 for i in range(len(self.vrf_list)):
Jan Gelety95c87b52017-02-27 10:46:14 +0100522 self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
Jane546d3b2016-12-08 13:10:03 +0100523
524 # Verify 4
Jan Gelety95c87b52017-02-27 10:46:14 +0100525 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200526 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jan Gelety95c87b52017-02-27 10:46:14 +0100527 vrf_list_length = len(self.vrf_list)
528 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200529 vrf_list_length,
530 0,
531 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
532 )
Jane546d3b2016-12-08 13:10:03 +0100533
534 # Test 4
535 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200536 self.run_crosswise_vrf_test()
Jane546d3b2016-12-08 13:10:03 +0100537
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200538 def test_ip4_vrf_05(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200539 """IP4 VRF Multi-instance test 5 - id allocation"""
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200540 # Config 5
541 # Create several VRFs
542 # Set vrf_id manually first
543 self.create_vrf_by_id_and_assign_interfaces(1, 1)
544 # Set vrf_id automatically a few times
545 auto_vrf_id = [
546 self.create_vrf_by_id_and_assign_interfaces(i) for i in range(2, 5)
547 ]
548
549 # Verify 5
550 self.assert_equal(self.verify_vrf(1, 1), VRFState.configured, VRFState)
551 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200552 self.assert_equal(
553 self.verify_vrf(vrf, i + 2), VRFState.configured, VRFState
554 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200555
556 # Test 5
557 self.run_verify_test()
558
559 # Config 5.1
560 # Reset VRFs
561 self.reset_vrf_and_remove_from_vrf_list(1)
562 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200563 self.reset_vrf_and_remove_from_vrf_list(vrf, i + 2)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200564
565 # Verify 5.1
566 self.assert_equal(self.verify_vrf(1, 1), VRFState.reset, VRFState)
567 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200568 self.assert_equal(self.verify_vrf(vrf, i + 2), VRFState.reset, VRFState)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200569
570 vrf_list_length = len(self.vrf_list)
571 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200572 vrf_list_length,
573 0,
574 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
575 )
Jane546d3b2016-12-08 13:10:03 +0100576
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200577
578if __name__ == "__main__":
Jane546d3b2016-12-08 13:10:03 +0100579 unittest.main(testRunner=VppTestRunner)