blob: 73df30d77f29ccb428fb1533220db25c12f82554 [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Jan Gelety057bb8c2016-12-20 17:32:45 +01002"""IP6 VRF Multi-instance Test Case HLD:
3
4**NOTES:**
5 - higher number of pg-ip6 interfaces causes problems => only 15 pg-ip6 \
Dave Wallaced1706812021-08-12 18:36:02 -04006 interfaces in 5 VRFs are tested
Jan Gelety057bb8c2016-12-20 17:32:45 +01007 - jumbo packets in configuration with 15 pg-ip6 interfaces leads to \
Dave Wallaced1706812021-08-12 18:36:02 -04008 problems too
Jan Gelety057bb8c2016-12-20 17:32:45 +01009
10**config 1**
11 - add 15 pg-ip6 interfaces
12 - configure 5 hosts per pg-ip6 interface
13 - configure 4 VRFs
14 - add 3 pg-ip6 interfaces per VRF
15
16**test 1**
17 - send IP6 packets between all pg-ip6 interfaces in all VRF groups
18
19**verify 1**
Neale Ranns097fa662018-05-01 05:17:55 -070020 - check VRF data by parsing output of ip_route_dump API command
Dave Wallaced1706812021-08-12 18:36:02 -040021 - all packets received correctly in case of pg-ip6 interfaces in the
22 same VRF
Jan Gelety057bb8c2016-12-20 17:32:45 +010023 - no packet received in case of pg-ip6 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020024 - no packet received in case of pg-ip6 interfaces in different VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +010025
26**config 2**
Jan Geletyb5b2ef52017-02-23 15:01:29 +010027 - reset 2 VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +010028
29**test 2**
30 - send IP6 packets between all pg-ip6 interfaces in all VRF groups
31
32**verify 2**
Neale Ranns097fa662018-05-01 05:17:55 -070033 - check VRF data by parsing output of ip_route_dump API command
Dave Wallaced1706812021-08-12 18:36:02 -040034 - all packets received correctly in case of pg-ip6 interfaces in the
35 same VRF
Jan Gelety057bb8c2016-12-20 17:32:45 +010036 - no packet received in case of pg-ip6 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020037 - no packet received in case of pg-ip6 interfaces in different VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +010038
39**config 3**
Jan Geletyb5b2ef52017-02-23 15:01:29 +010040 - add 1 of reset VRFs and 1 new VRF
Jan Gelety057bb8c2016-12-20 17:32:45 +010041
42**test 3**
43 - send IP6 packets between all pg-ip6 interfaces in all VRF groups
44
45**verify 3**
Neale Ranns097fa662018-05-01 05:17:55 -070046 - check VRF data by parsing output of ip_route_dump API command
Dave Wallaced1706812021-08-12 18:36:02 -040047 - all packets received correctly in case of pg-ip6 interfaces in the
48 same VRF
Jan Gelety057bb8c2016-12-20 17:32:45 +010049 - no packet received in case of pg-ip6 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020050 - no packet received in case of pg-ip6 interfaces in different VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +010051
52**config 4**
Jan Geletyb5b2ef52017-02-23 15:01:29 +010053 - reset all VRFs (i.e. no VRF except VRF=0 created)
Jan Gelety057bb8c2016-12-20 17:32:45 +010054
55**test 4**
56 - send IP6 packets between all pg-ip6 interfaces in all VRF groups
57
58**verify 4**
Neale Ranns097fa662018-05-01 05:17:55 -070059 - check VRF data by parsing output of ip_route_dump API command
Dave Wallaced1706812021-08-12 18:36:02 -040060 - all packets received correctly in case of pg-ip6 interfaces in the
61 same VRF
Jan Gelety057bb8c2016-12-20 17:32:45 +010062 - no packet received in case of pg-ip6 interfaces not in VRF
Jan Geletyd16ba622018-06-21 16:57:47 +020063 - no packet received in case of pg-ip6 interfaces in different VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +010064"""
65
66import unittest
67import random
Jan Geletyb5b2ef52017-02-23 15:01:29 +010068import socket
Jan Gelety057bb8c2016-12-20 17:32:45 +010069
70from scapy.packet import Raw
71from scapy.layers.l2 import Ether
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020072from scapy.layers.inet6 import (
73 UDP,
74 IPv6,
75 ICMPv6ND_NS,
76 ICMPv6ND_RA,
77 RouterAlert,
78 IPv6ExtHdrHopByHop,
79)
Jan Geletyb5b2ef52017-02-23 15:01:29 +010080from scapy.utils6 import in6_ismaddr, in6_isllsnmaddr, in6_getAddrType
81from scapy.pton_ntop import inet_ntop
Jan Gelety057bb8c2016-12-20 17:32:45 +010082
83from framework import VppTestCase, VppTestRunner
84from util import ppp
Jan Gelety95c87b52017-02-27 10:46:14 +010085from vrf import VRFState
Jan Geletyb5b2ef52017-02-23 15:01:29 +010086
87
88def is_ipv6_misc_ext(p):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020089 """Is packet one of uninteresting IPv6 broadcasts (extended to filter out
90 ICMPv6 Neighbor Discovery - Neighbor Advertisement packets too)?"""
Jan Geletyb5b2ef52017-02-23 15:01:29 +010091 if p.haslayer(ICMPv6ND_RA):
92 if in6_ismaddr(p[IPv6].dst):
93 return True
94 if p.haslayer(ICMPv6ND_NS):
95 if in6_isllsnmaddr(p[IPv6].dst):
96 return True
97 if p.haslayer(IPv6ExtHdrHopByHop):
98 for o in p[IPv6ExtHdrHopByHop].options:
99 if isinstance(o, RouterAlert):
100 return True
101 return False
102
Jan Gelety057bb8c2016-12-20 17:32:45 +0100103
104class TestIP6VrfMultiInst(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200105 """IP6 VRF Multi-instance Test Case"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100106
107 @classmethod
108 def setUpClass(cls):
109 """
110 Perform standard class setup (defined by class method setUpClass in
111 class VppTestCase) before running the test case, set test case related
112 variables and configure VPP.
113 """
114 super(TestIP6VrfMultiInst, cls).setUpClass()
115
116 # Test variables
117 cls.hosts_per_pg = 5
118 cls.nr_of_vrfs = 5
119 cls.pg_ifs_per_vrf = 3
120
121 try:
122 # Create pg interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200123 cls.create_pg_interfaces(range(cls.nr_of_vrfs * cls.pg_ifs_per_vrf))
Jan Gelety057bb8c2016-12-20 17:32:45 +0100124
125 # Packet flows mapping pg0 -> pg1, pg2 etc.
126 cls.flows = dict()
127 for i in range(len(cls.pg_interfaces)):
Ole Troan19757332019-10-18 14:54:30 +0200128 multiplicand = i // cls.pg_ifs_per_vrf
Jan Gelety057bb8c2016-12-20 17:32:45 +0100129 pg_list = [
130 cls.pg_interfaces[multiplicand * cls.pg_ifs_per_vrf + j]
131 for j in range(cls.pg_ifs_per_vrf)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200132 if (multiplicand * cls.pg_ifs_per_vrf + j) != i
133 ]
Jan Gelety057bb8c2016-12-20 17:32:45 +0100134 cls.flows[cls.pg_interfaces[i]] = pg_list
135
136 # Packet sizes - jumbo packet (9018 bytes) skipped
137 cls.pg_if_packet_sizes = [64, 512, 1518]
138
139 # Set up all interfaces
140 for pg_if in cls.pg_interfaces:
141 pg_if.admin_up()
142 pg_if.generate_remote_hosts(cls.hosts_per_pg)
143
144 # Create list of VRFs
145 cls.vrf_list = list()
146
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100147 # Create list of reset VRFs
148 cls.vrf_reset_list = list()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100149
150 # Create list of pg_interfaces in VRFs
151 cls.pg_in_vrf = list()
152
Jan Geletyd16ba622018-06-21 16:57:47 +0200153 # Create list of pg_interfaces not in VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +0100154 cls.pg_not_in_vrf = [pg_if for pg_if in cls.pg_interfaces]
155
156 # Create mapping of pg_interfaces to VRF IDs
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200157 cls.pg_if_sets = dict()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100158 for i in range(cls.nr_of_vrfs):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200159 set_id = i + 1
Jan Gelety057bb8c2016-12-20 17:32:45 +0100160 pg_list = [
161 cls.pg_interfaces[i * cls.pg_ifs_per_vrf + j]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200162 for j in range(cls.pg_ifs_per_vrf)
163 ]
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200164 cls.pg_if_sets[set_id] = pg_list
Jan Gelety057bb8c2016-12-20 17:32:45 +0100165
166 except Exception:
167 super(TestIP6VrfMultiInst, cls).tearDownClass()
168 raise
169
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700170 @classmethod
171 def tearDownClass(cls):
172 super(TestIP6VrfMultiInst, cls).tearDownClass()
173
Jan Gelety057bb8c2016-12-20 17:32:45 +0100174 def setUp(self):
175 """
176 Clear trace and packet infos before running each test.
177 """
178 super(TestIP6VrfMultiInst, self).setUp()
179 self.reset_packet_infos()
180
181 def tearDown(self):
182 """
183 Show various debug prints after each test.
184 """
185 super(TestIP6VrfMultiInst, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700186
187 def show_commands_at_teardown(self):
188 self.logger.info(self.vapi.ppcli("show ip6 fib"))
189 self.logger.info(self.vapi.ppcli("show ip6 neighbors"))
Jan Gelety057bb8c2016-12-20 17:32:45 +0100190
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200191 def _assign_interfaces(self, vrf_id, if_set_id):
192 for i in range(self.pg_ifs_per_vrf):
193 pg_if = self.pg_if_sets[if_set_id][i]
194 pg_if.set_table_ip6(vrf_id)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200195 self.logger.info(
196 "pg-interface %s added to IPv6 VRF ID %d" % (pg_if.name, vrf_id)
197 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200198 if pg_if not in self.pg_in_vrf:
199 self.pg_in_vrf.append(pg_if)
200 if pg_if in self.pg_not_in_vrf:
201 self.pg_not_in_vrf.remove(pg_if)
202 pg_if.config_ip6()
203 pg_if.disable_ipv6_ra()
204 pg_if.configure_ipv6_neighbors()
205
Jan Gelety057bb8c2016-12-20 17:32:45 +0100206 def create_vrf_and_assign_interfaces(self, count, start=1):
207 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200208 Create required number of FIB tables / VRFs, put 3 pg-ip6 interfaces
Jan Gelety057bb8c2016-12-20 17:32:45 +0100209 to every FIB table / VRF.
210
211 :param int count: Number of FIB tables / VRFs to be created.
212 :param int start: Starting number of the FIB table / VRF ID. \
213 (Default value = 1)
214 """
215 for i in range(count):
216 vrf_id = i + start
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200217 self.vapi.ip_table_add_del(
218 is_add=1, table={"table_id": vrf_id, "is_ip6": 1}
219 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100220 self.logger.info("IPv6 VRF ID %d created" % vrf_id)
221 if vrf_id not in self.vrf_list:
222 self.vrf_list.append(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100223 if vrf_id in self.vrf_reset_list:
224 self.vrf_reset_list.remove(vrf_id)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200225 self._assign_interfaces(vrf_id, vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100226 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
227 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
228
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200229 def create_vrf_by_id_and_assign_interfaces(self, set_id, vrf_id=0xFFFFFFFF):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200230 """
231 Create a FIB table / VRF by vrf_id, put 3 pg-ip6 interfaces
232 to FIB table / VRF.
233
234 :param int vrf_id: Required table ID / VRF ID. \
235 (Default value = 0xffffffff, ID will be selected automatically)
236 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200237 ret = self.vapi.ip_table_allocate(table={"table_id": vrf_id, "is_ip6": 1})
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200238 vrf_id = ret.table.table_id
239 self.logger.info("IPv6 VRF ID %d created" % vrf_id)
240 if vrf_id not in self.vrf_list:
241 self.vrf_list.append(vrf_id)
242 if vrf_id in self.vrf_reset_list:
243 self.vrf_reset_list.remove(vrf_id)
244 self._assign_interfaces(vrf_id, set_id)
245 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
246 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
247
248 return vrf_id
249
250 def reset_vrf_and_remove_from_vrf_list(self, vrf_id, if_set_id=None):
Jan Gelety057bb8c2016-12-20 17:32:45 +0100251 """
Jan Gelety95c87b52017-02-27 10:46:14 +0100252 Reset required FIB table / VRF and remove it from VRF list.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100253
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100254 :param int vrf_id: The FIB table / VRF ID to be reset.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100255 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200256 if if_set_id is None:
257 if_set_id = vrf_id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200258 self.vapi.ip_table_flush(table={"table_id": vrf_id, "is_ip6": 1})
Jan Gelety057bb8c2016-12-20 17:32:45 +0100259 if vrf_id in self.vrf_list:
260 self.vrf_list.remove(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100261 if vrf_id not in self.vrf_reset_list:
262 self.vrf_reset_list.append(vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100263 for j in range(self.pg_ifs_per_vrf):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200264 pg_if = self.pg_if_sets[if_set_id][j]
Neale Ranns4008ac92017-02-13 23:20:04 -0800265 pg_if.unconfig_ip6()
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200266 pg_if.set_table_ip6(0)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100267 if pg_if in self.pg_in_vrf:
268 self.pg_in_vrf.remove(pg_if)
269 if pg_if not in self.pg_not_in_vrf:
270 self.pg_not_in_vrf.append(pg_if)
Jan Gelety95c87b52017-02-27 10:46:14 +0100271 self.logger.info("IPv6 VRF ID %d reset finished" % vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100272 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
273 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200274
275 def delete_vrf(self, vrf_id):
276 if vrf_id in self.vrf_list:
277 self.vrf_list.remove(vrf_id)
278 if vrf_id in self.vrf_reset_list:
279 self.vrf_reset_list.remove(vrf_id)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200280 self.vapi.ip_table_add_del(is_add=0, table={"table_id": vrf_id, "is_ip6": 1})
Jan Gelety057bb8c2016-12-20 17:32:45 +0100281
282 def create_stream(self, src_if, packet_sizes):
283 """
284 Create input packet stream for defined interface using hosts list.
285
286 :param object src_if: Interface to create packet stream for.
287 :param list packet_sizes: List of required packet sizes.
288 :return: Stream of packets.
289 """
290 pkts = []
291 src_hosts = src_if.remote_hosts
292 for dst_if in self.flows[src_if]:
293 for dst_host in dst_if.remote_hosts:
294 src_host = random.choice(src_hosts)
295 pkt_info = self.create_packet_info(src_if, dst_if)
296 payload = self.info_to_payload(pkt_info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200297 p = (
298 Ether(dst=src_if.local_mac, src=src_host.mac)
299 / IPv6(src=src_host.ip6, dst=dst_host.ip6)
300 / UDP(sport=1234, dport=1234)
301 / Raw(payload)
302 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100303 pkt_info.data = p.copy()
304 size = random.choice(packet_sizes)
305 self.extend_packet(p, size)
306 pkts.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200307 self.logger.debug(
308 "Input stream created for port %s. Length: %u pkt(s)"
309 % (src_if.name, len(pkts))
310 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100311 return pkts
312
Jan Geletyd16ba622018-06-21 16:57:47 +0200313 def create_stream_crosswise_vrf(self, src_if, vrf_id, packet_sizes):
314 """
315 Create input packet stream for negative test for leaking across
316 different VRFs for defined interface using hosts list.
317
318 :param object src_if: Interface to create packet stream for.
319 :param int vrf_id: The FIB table / VRF ID where src_if is assigned.
320 :param list packet_sizes: List of required packet sizes.
321 :return: Stream of packets.
322 """
323 pkts = []
324 src_hosts = src_if.remote_hosts
325 vrf_lst = list(self.vrf_list)
326 vrf_lst.remove(vrf_id)
327 for vrf in vrf_lst:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200328 for dst_if in self.pg_if_sets[vrf]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200329 for dst_host in dst_if.remote_hosts:
330 src_host = random.choice(src_hosts)
331 pkt_info = self.create_packet_info(src_if, dst_if)
332 payload = self.info_to_payload(pkt_info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200333 p = (
334 Ether(dst=src_if.local_mac, src=src_host.mac)
335 / IPv6(src=src_host.ip6, dst=dst_host.ip6)
336 / UDP(sport=1234, dport=1234)
337 / Raw(payload)
338 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200339 pkt_info.data = p.copy()
340 size = random.choice(packet_sizes)
341 self.extend_packet(p, size)
342 pkts.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200343 self.logger.debug(
344 "Input stream created for port %s. Length: %u pkt(s)"
345 % (src_if.name, len(pkts))
346 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200347 return pkts
348
Jan Gelety057bb8c2016-12-20 17:32:45 +0100349 def verify_capture(self, pg_if, capture):
350 """
351 Verify captured input packet stream for defined interface.
352
353 :param object pg_if: Interface to verify captured packet stream for.
354 :param list capture: Captured packet stream.
355 """
356 last_info = dict()
357 for i in self.pg_interfaces:
358 last_info[i.sw_if_index] = None
359 dst_sw_if_index = pg_if.sw_if_index
360 for packet in capture:
361 try:
362 ip = packet[IPv6]
363 udp = packet[UDP]
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800364 payload_info = self.payload_to_info(packet[Raw])
Jan Gelety057bb8c2016-12-20 17:32:45 +0100365 packet_index = payload_info.index
366 self.assertEqual(payload_info.dst, dst_sw_if_index)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200367 self.logger.debug(
368 "Got packet on port %s: src=%u (id=%u)"
369 % (pg_if.name, payload_info.src, packet_index)
370 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100371 next_info = self.get_next_packet_info_for_interface2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200372 payload_info.src, dst_sw_if_index, last_info[payload_info.src]
373 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100374 last_info[payload_info.src] = next_info
375 self.assertIsNotNone(next_info)
376 self.assertEqual(packet_index, next_info.index)
377 saved_packet = next_info.data
378 # Check standard fields
379 self.assertEqual(ip.src, saved_packet[IPv6].src)
380 self.assertEqual(ip.dst, saved_packet[IPv6].dst)
381 self.assertEqual(udp.sport, saved_packet[UDP].sport)
382 self.assertEqual(udp.dport, saved_packet[UDP].dport)
383 except:
384 self.logger.error(ppp("Unexpected or invalid packet:", packet))
385 raise
386 for i in self.pg_interfaces:
387 remaining_packet = self.get_next_packet_info_for_interface2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200388 i, dst_sw_if_index, last_info[i.sw_if_index]
389 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100390 self.assertIsNone(
391 remaining_packet,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200392 "Port %u: Packet expected from source %u didn't arrive"
393 % (dst_sw_if_index, i.sw_if_index),
394 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100395
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200396 def verify_vrf(self, vrf_id, if_set_id=None):
Jan Gelety057bb8c2016-12-20 17:32:45 +0100397 """
398 Check if the FIB table / VRF ID is configured.
399
400 :param int vrf_id: The FIB table / VRF ID to be verified.
401 :return: 1 if the FIB table / VRF ID is configured, otherwise return 0.
402 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200403 if if_set_id is None:
404 if_set_id = vrf_id
Neale Ranns097fa662018-05-01 05:17:55 -0700405 ip6_fib_dump = self.vapi.ip_route_dump(vrf_id, True)
406 vrf_exist = len(ip6_fib_dump)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100407 vrf_count = 0
408 for ip6_fib_details in ip6_fib_dump:
Neale Ranns097fa662018-05-01 05:17:55 -0700409 addr = ip6_fib_details.route.prefix.network_address
410 found = False
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200411 for pg_if in self.pg_if_sets[if_set_id]:
Neale Ranns097fa662018-05-01 05:17:55 -0700412 if found:
413 break
414 for host in pg_if.remote_hosts:
415 if str(addr) == host.ip6:
416 vrf_count += 1
417 found = True
Jan Gelety95c87b52017-02-27 10:46:14 +0100418 break
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100419 if not vrf_exist and vrf_count == 0:
Jan Gelety057bb8c2016-12-20 17:32:45 +0100420 self.logger.info("IPv6 VRF ID %d is not configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100421 return VRFState.not_configured
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100422 elif vrf_exist and vrf_count == 0:
423 self.logger.info("IPv6 VRF ID %d has been reset" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100424 return VRFState.reset
Jan Gelety057bb8c2016-12-20 17:32:45 +0100425 else:
426 self.logger.info("IPv6 VRF ID %d is configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100427 return VRFState.configured
Jan Gelety057bb8c2016-12-20 17:32:45 +0100428
429 def run_verify_test(self):
430 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200431 Create packet streams for all configured pg interfaces, send all \
Jan Gelety057bb8c2016-12-20 17:32:45 +0100432 prepared packet streams and verify that:
Jan Geletyd16ba622018-06-21 16:57:47 +0200433 - all packets received correctly on all pg-ip6 interfaces assigned
434 to VRFs
435 - no packet received on all pg-ip6 interfaces not assigned to VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +0100436
Jan Geletyd16ba622018-06-21 16:57:47 +0200437 :raise RuntimeError: If no packet captured on pg-ip6 interface assigned
438 to VRF or if any packet is captured on pg-ip6 interface not
439 assigned to VRF.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100440 """
441 # Test
442 # Create incoming packet streams for packet-generator interfaces
443 for pg_if in self.pg_interfaces:
444 pkts = self.create_stream(pg_if, self.pg_if_packet_sizes)
445 pg_if.add_stream(pkts)
446
447 # Enable packet capture and start packet sending
448 self.pg_enable_capture(self.pg_interfaces)
449 self.pg_start()
450
451 # Verify
452 # Verify outgoing packet streams per packet-generator interface
453 for pg_if in self.pg_interfaces:
454 if pg_if in self.pg_in_vrf:
455 capture = pg_if.get_capture(remark="interface is in VRF")
456 self.verify_capture(pg_if, capture)
457 elif pg_if in self.pg_not_in_vrf:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200458 pg_if.assert_nothing_captured(
459 remark="interface is not in VRF", filter_out_fn=is_ipv6_misc_ext
460 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100461 self.logger.debug("No capture for interface %s" % pg_if.name)
462 else:
463 raise Exception("Unknown interface: %s" % pg_if.name)
464
Jan Geletyd16ba622018-06-21 16:57:47 +0200465 def run_crosswise_vrf_test(self):
466 """
467 Create packet streams for every pg-ip6 interface in VRF towards all
Dave Wallaced1706812021-08-12 18:36:02 -0400468 pg-ip6 interfaces in other VRFs, send all prepared packet streams and
Jan Geletyd16ba622018-06-21 16:57:47 +0200469 verify that:
Dave Wallaced1706812021-08-12 18:36:02 -0400470
471 - no packet received on all configured pg-ip6 interfaces
Jan Geletyd16ba622018-06-21 16:57:47 +0200472
473 :raise RuntimeError: If any packet is captured on any pg-ip6 interface.
474 """
475 # Test
476 # Create incoming packet streams for packet-generator interfaces
477 for vrf_id in self.vrf_list:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200478 for pg_if in self.pg_if_sets[vrf_id]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200479 pkts = self.create_stream_crosswise_vrf(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200480 pg_if, vrf_id, self.pg_if_packet_sizes
481 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200482 pg_if.add_stream(pkts)
483
484 # Enable packet capture and start packet sending
485 self.pg_enable_capture(self.pg_interfaces)
486 self.pg_start()
487
488 # Verify
489 # Verify outgoing packet streams per packet-generator interface
490 for pg_if in self.pg_interfaces:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200491 pg_if.assert_nothing_captured(
492 remark="interface is in other VRF", filter_out_fn=is_ipv6_misc_ext
493 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200494 self.logger.debug("No capture for interface %s" % pg_if.name)
495
Jan Gelety057bb8c2016-12-20 17:32:45 +0100496 def test_ip6_vrf_01(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200497 """IP6 VRF Multi-instance test 1 - create 4 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100498 # Config 1
499 # Create 4 VRFs
500 self.create_vrf_and_assign_interfaces(4)
501
502 # Verify 1
503 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200504 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100505
506 # Test 1
507 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200508 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100509
Jan Gelety057bb8c2016-12-20 17:32:45 +0100510 def test_ip6_vrf_02(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200511 """IP6 VRF Multi-instance test 2 - reset 2 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100512 # Config 2
513 # Delete 2 VRFs
Jan Gelety95c87b52017-02-27 10:46:14 +0100514 self.reset_vrf_and_remove_from_vrf_list(1)
515 self.reset_vrf_and_remove_from_vrf_list(2)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100516
517 # Verify 2
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100518 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200519 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100520 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200521 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100522
523 # Test 2
524 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200525 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100526
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100527 # Reset routes learned from ICMPv6 Neighbor Discovery
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200528 # for vrf_id in self.vrf_reset_list:
529 # self.reset_vrf_and_remove_from_vrf_list(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100530
Jan Gelety057bb8c2016-12-20 17:32:45 +0100531 def test_ip6_vrf_03(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200532 """IP6 VRF Multi-instance 3 - add 2 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100533 # Config 3
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100534 # Add 1 of reset VRFs and 1 new VRF
535 self.create_vrf_and_assign_interfaces(1)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100536 self.create_vrf_and_assign_interfaces(1, start=5)
537
538 # Verify 3
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100539 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200540 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100541 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200542 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100543
544 # Test 3
545 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200546 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100547
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100548 # Reset routes learned from ICMPv6 Neighbor Discovery
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200549 # for vrf_id in self.vrf_reset_list:
550 # self.reset_vrf_and_remove_from_vrf_list(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100551
Jan Gelety057bb8c2016-12-20 17:32:45 +0100552 def test_ip6_vrf_04(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200553 """IP6 VRF Multi-instance test 4 - reset 4 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100554 # Config 4
Jan Gelety95c87b52017-02-27 10:46:14 +0100555 # Reset all VRFs (i.e. no VRF except VRF=0 configured)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100556 for i in range(len(self.vrf_list)):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200557 # This call removes the first item of vrf_list as a side effect
Jan Gelety95c87b52017-02-27 10:46:14 +0100558 self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
Jan Gelety057bb8c2016-12-20 17:32:45 +0100559
560 # Verify 4
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100561 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200562 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jan Gelety95c87b52017-02-27 10:46:14 +0100563 vrf_list_length = len(self.vrf_list)
564 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200565 vrf_list_length,
566 0,
567 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
568 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100569
570 # Test 4
571 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200572 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100573
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200574 def test_ip6_vrf_05(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200575 """IP6 VRF Multi-instance test 5 - auto allocate vrf id"""
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200576 # Config 5
577 # Create several VRFs
578 # Set vrf_id manually first
579 self.create_vrf_by_id_and_assign_interfaces(1, 10)
580 # Set vrf_id automatically a few times
581 auto_vrf_id = [
582 self.create_vrf_by_id_and_assign_interfaces(i) for i in range(2, 5)
583 ]
584
585 # Verify 5
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200586 self.assert_equal(self.verify_vrf(10, 1), VRFState.configured, VRFState)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200587 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200588 self.assert_equal(
589 self.verify_vrf(vrf, i + 2), VRFState.configured, VRFState
590 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200591
592 # Test 5
593 self.run_verify_test()
594
595 # Config 5.1
596 # Reset VRFs
597 self.reset_vrf_and_remove_from_vrf_list(10, 1)
598 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200599 self.reset_vrf_and_remove_from_vrf_list(vrf, i + 2)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200600
601 # Verify 5.1
602 self.assert_equal(self.verify_vrf(10, 1), VRFState.reset, VRFState)
603 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200604 self.assert_equal(self.verify_vrf(vrf, i + 2), VRFState.reset, VRFState)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200605
606 vrf_list_length = len(self.vrf_list)
607 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200608 vrf_list_length,
609 0,
610 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
611 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200612
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200613 # Cleanup our extra created VRFs
614 for vrf in auto_vrf_id:
615 self.delete_vrf(vrf)
616 self.delete_vrf(5)
617 self.delete_vrf(10)
618
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200619 def test_ip6_vrf_06(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200620 """IP6 VRF Multi-instance test 6 - recreate 4 VRFs"""
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200621 # Reconfigure all the VRFs
622 self.create_vrf_and_assign_interfaces(4)
623 # Verify
624 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200625 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200626 # Test
627 self.run_verify_test()
628 self.run_crosswise_vrf_test()
629 # Cleanup
630 for i in range(len(self.vrf_list)):
631 self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
632 # Verify
633 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200634 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200635 vrf_list_length = len(self.vrf_list)
636 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200637 vrf_list_length,
638 0,
639 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
640 )
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200641 # Test
642 self.run_verify_test()
643 self.run_crosswise_vrf_test()
644
Jan Gelety057bb8c2016-12-20 17:32:45 +0100645
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200646if __name__ == "__main__":
Jan Gelety057bb8c2016-12-20 17:32:45 +0100647 unittest.main(testRunner=VppTestRunner)