blob: 26519b129cf3d0267db3df261b4b81a205542035 [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
68
69from scapy.packet import Raw
70from scapy.layers.l2 import Ether
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020071from scapy.layers.inet6 import (
72 UDP,
73 IPv6,
74 ICMPv6ND_NS,
75 ICMPv6ND_RA,
76 RouterAlert,
77 IPv6ExtHdrHopByHop,
78)
Dave Wallace8800f732023-08-31 00:47:44 -040079from scapy.utils6 import in6_ismaddr, in6_isllsnmaddr
Jan Gelety057bb8c2016-12-20 17:32:45 +010080
Dave Wallace8800f732023-08-31 00:47:44 -040081from framework import VppTestCase
82from asfframework import VppTestRunner
Jan Gelety057bb8c2016-12-20 17:32:45 +010083from util import ppp
Jan Gelety95c87b52017-02-27 10:46:14 +010084from vrf import VRFState
Jan Geletyb5b2ef52017-02-23 15:01:29 +010085
86
87def is_ipv6_misc_ext(p):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020088 """Is packet one of uninteresting IPv6 broadcasts (extended to filter out
89 ICMPv6 Neighbor Discovery - Neighbor Advertisement packets too)?"""
Jan Geletyb5b2ef52017-02-23 15:01:29 +010090 if p.haslayer(ICMPv6ND_RA):
91 if in6_ismaddr(p[IPv6].dst):
92 return True
93 if p.haslayer(ICMPv6ND_NS):
94 if in6_isllsnmaddr(p[IPv6].dst):
95 return True
96 if p.haslayer(IPv6ExtHdrHopByHop):
97 for o in p[IPv6ExtHdrHopByHop].options:
98 if isinstance(o, RouterAlert):
99 return True
100 return False
101
Jan Gelety057bb8c2016-12-20 17:32:45 +0100102
103class TestIP6VrfMultiInst(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200104 """IP6 VRF Multi-instance Test Case"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100105
106 @classmethod
107 def setUpClass(cls):
108 """
109 Perform standard class setup (defined by class method setUpClass in
110 class VppTestCase) before running the test case, set test case related
111 variables and configure VPP.
112 """
113 super(TestIP6VrfMultiInst, cls).setUpClass()
114
115 # Test variables
116 cls.hosts_per_pg = 5
117 cls.nr_of_vrfs = 5
118 cls.pg_ifs_per_vrf = 3
119
120 try:
121 # Create pg interfaces
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200122 cls.create_pg_interfaces(range(cls.nr_of_vrfs * cls.pg_ifs_per_vrf))
Jan Gelety057bb8c2016-12-20 17:32:45 +0100123
124 # Packet flows mapping pg0 -> pg1, pg2 etc.
125 cls.flows = dict()
126 for i in range(len(cls.pg_interfaces)):
Ole Troan19757332019-10-18 14:54:30 +0200127 multiplicand = i // cls.pg_ifs_per_vrf
Jan Gelety057bb8c2016-12-20 17:32:45 +0100128 pg_list = [
129 cls.pg_interfaces[multiplicand * cls.pg_ifs_per_vrf + j]
130 for j in range(cls.pg_ifs_per_vrf)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200131 if (multiplicand * cls.pg_ifs_per_vrf + j) != i
132 ]
Jan Gelety057bb8c2016-12-20 17:32:45 +0100133 cls.flows[cls.pg_interfaces[i]] = pg_list
134
135 # Packet sizes - jumbo packet (9018 bytes) skipped
136 cls.pg_if_packet_sizes = [64, 512, 1518]
137
138 # Set up all interfaces
139 for pg_if in cls.pg_interfaces:
140 pg_if.admin_up()
141 pg_if.generate_remote_hosts(cls.hosts_per_pg)
142
143 # Create list of VRFs
144 cls.vrf_list = list()
145
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100146 # Create list of reset VRFs
147 cls.vrf_reset_list = list()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100148
149 # Create list of pg_interfaces in VRFs
150 cls.pg_in_vrf = list()
151
Jan Geletyd16ba622018-06-21 16:57:47 +0200152 # Create list of pg_interfaces not in VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +0100153 cls.pg_not_in_vrf = [pg_if for pg_if in cls.pg_interfaces]
154
155 # Create mapping of pg_interfaces to VRF IDs
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200156 cls.pg_if_sets = dict()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100157 for i in range(cls.nr_of_vrfs):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200158 set_id = i + 1
Jan Gelety057bb8c2016-12-20 17:32:45 +0100159 pg_list = [
160 cls.pg_interfaces[i * cls.pg_ifs_per_vrf + j]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200161 for j in range(cls.pg_ifs_per_vrf)
162 ]
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200163 cls.pg_if_sets[set_id] = pg_list
Jan Gelety057bb8c2016-12-20 17:32:45 +0100164
165 except Exception:
166 super(TestIP6VrfMultiInst, cls).tearDownClass()
167 raise
168
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700169 @classmethod
170 def tearDownClass(cls):
171 super(TestIP6VrfMultiInst, cls).tearDownClass()
172
Jan Gelety057bb8c2016-12-20 17:32:45 +0100173 def setUp(self):
174 """
175 Clear trace and packet infos before running each test.
176 """
177 super(TestIP6VrfMultiInst, self).setUp()
178 self.reset_packet_infos()
179
180 def tearDown(self):
181 """
182 Show various debug prints after each test.
183 """
184 super(TestIP6VrfMultiInst, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700185
186 def show_commands_at_teardown(self):
187 self.logger.info(self.vapi.ppcli("show ip6 fib"))
188 self.logger.info(self.vapi.ppcli("show ip6 neighbors"))
Jan Gelety057bb8c2016-12-20 17:32:45 +0100189
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200190 def _assign_interfaces(self, vrf_id, if_set_id):
191 for i in range(self.pg_ifs_per_vrf):
192 pg_if = self.pg_if_sets[if_set_id][i]
193 pg_if.set_table_ip6(vrf_id)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200194 self.logger.info(
195 "pg-interface %s added to IPv6 VRF ID %d" % (pg_if.name, vrf_id)
196 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200197 if pg_if not in self.pg_in_vrf:
198 self.pg_in_vrf.append(pg_if)
199 if pg_if in self.pg_not_in_vrf:
200 self.pg_not_in_vrf.remove(pg_if)
201 pg_if.config_ip6()
202 pg_if.disable_ipv6_ra()
203 pg_if.configure_ipv6_neighbors()
204
Jan Gelety057bb8c2016-12-20 17:32:45 +0100205 def create_vrf_and_assign_interfaces(self, count, start=1):
206 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200207 Create required number of FIB tables / VRFs, put 3 pg-ip6 interfaces
Jan Gelety057bb8c2016-12-20 17:32:45 +0100208 to every FIB table / VRF.
209
210 :param int count: Number of FIB tables / VRFs to be created.
211 :param int start: Starting number of the FIB table / VRF ID. \
212 (Default value = 1)
213 """
214 for i in range(count):
215 vrf_id = i + start
Benoît Ganneff570d32024-04-16 09:36:05 +0200216 self.vapi.ip_table_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200217 is_add=1, table={"table_id": vrf_id, "is_ip6": 1}
218 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100219 self.logger.info("IPv6 VRF ID %d created" % vrf_id)
220 if vrf_id not in self.vrf_list:
221 self.vrf_list.append(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100222 if vrf_id in self.vrf_reset_list:
223 self.vrf_reset_list.remove(vrf_id)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200224 self._assign_interfaces(vrf_id, vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100225 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
226 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
227
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200228 def create_vrf_by_id_and_assign_interfaces(self, set_id, vrf_id=0xFFFFFFFF):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200229 """
230 Create a FIB table / VRF by vrf_id, put 3 pg-ip6 interfaces
231 to FIB table / VRF.
232
233 :param int vrf_id: Required table ID / VRF ID. \
234 (Default value = 0xffffffff, ID will be selected automatically)
235 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200236 ret = self.vapi.ip_table_allocate(table={"table_id": vrf_id, "is_ip6": 1})
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200237 vrf_id = ret.table.table_id
238 self.logger.info("IPv6 VRF ID %d created" % vrf_id)
239 if vrf_id not in self.vrf_list:
240 self.vrf_list.append(vrf_id)
241 if vrf_id in self.vrf_reset_list:
242 self.vrf_reset_list.remove(vrf_id)
243 self._assign_interfaces(vrf_id, set_id)
244 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
245 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
246
247 return vrf_id
248
249 def reset_vrf_and_remove_from_vrf_list(self, vrf_id, if_set_id=None):
Jan Gelety057bb8c2016-12-20 17:32:45 +0100250 """
Jan Gelety95c87b52017-02-27 10:46:14 +0100251 Reset required FIB table / VRF and remove it from VRF list.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100252
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100253 :param int vrf_id: The FIB table / VRF ID to be reset.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100254 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200255 if if_set_id is None:
256 if_set_id = vrf_id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200257 self.vapi.ip_table_flush(table={"table_id": vrf_id, "is_ip6": 1})
Jan Gelety057bb8c2016-12-20 17:32:45 +0100258 if vrf_id in self.vrf_list:
259 self.vrf_list.remove(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100260 if vrf_id not in self.vrf_reset_list:
261 self.vrf_reset_list.append(vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100262 for j in range(self.pg_ifs_per_vrf):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200263 pg_if = self.pg_if_sets[if_set_id][j]
Neale Ranns4008ac92017-02-13 23:20:04 -0800264 pg_if.unconfig_ip6()
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200265 pg_if.set_table_ip6(0)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100266 if pg_if in self.pg_in_vrf:
267 self.pg_in_vrf.remove(pg_if)
268 if pg_if not in self.pg_not_in_vrf:
269 self.pg_not_in_vrf.append(pg_if)
Jan Gelety95c87b52017-02-27 10:46:14 +0100270 self.logger.info("IPv6 VRF ID %d reset finished" % vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100271 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
272 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200273
274 def delete_vrf(self, vrf_id):
275 if vrf_id in self.vrf_list:
276 self.vrf_list.remove(vrf_id)
277 if vrf_id in self.vrf_reset_list:
278 self.vrf_reset_list.remove(vrf_id)
Benoît Ganneff570d32024-04-16 09:36:05 +0200279 self.vapi.ip_table_add_del_v2(is_add=0, table={"table_id": vrf_id, "is_ip6": 1})
Jan Gelety057bb8c2016-12-20 17:32:45 +0100280
281 def create_stream(self, src_if, packet_sizes):
282 """
283 Create input packet stream for defined interface using hosts list.
284
285 :param object src_if: Interface to create packet stream for.
286 :param list packet_sizes: List of required packet sizes.
287 :return: Stream of packets.
288 """
289 pkts = []
290 src_hosts = src_if.remote_hosts
291 for dst_if in self.flows[src_if]:
292 for dst_host in dst_if.remote_hosts:
293 src_host = random.choice(src_hosts)
294 pkt_info = self.create_packet_info(src_if, dst_if)
295 payload = self.info_to_payload(pkt_info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200296 p = (
297 Ether(dst=src_if.local_mac, src=src_host.mac)
298 / IPv6(src=src_host.ip6, dst=dst_host.ip6)
299 / UDP(sport=1234, dport=1234)
300 / Raw(payload)
301 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100302 pkt_info.data = p.copy()
303 size = random.choice(packet_sizes)
304 self.extend_packet(p, size)
305 pkts.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200306 self.logger.debug(
307 "Input stream created for port %s. Length: %u pkt(s)"
308 % (src_if.name, len(pkts))
309 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100310 return pkts
311
Jan Geletyd16ba622018-06-21 16:57:47 +0200312 def create_stream_crosswise_vrf(self, src_if, vrf_id, packet_sizes):
313 """
314 Create input packet stream for negative test for leaking across
315 different VRFs for defined interface using hosts list.
316
317 :param object src_if: Interface to create packet stream for.
318 :param int vrf_id: The FIB table / VRF ID where src_if is assigned.
319 :param list packet_sizes: List of required packet sizes.
320 :return: Stream of packets.
321 """
322 pkts = []
323 src_hosts = src_if.remote_hosts
324 vrf_lst = list(self.vrf_list)
325 vrf_lst.remove(vrf_id)
326 for vrf in vrf_lst:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200327 for dst_if in self.pg_if_sets[vrf]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200328 for dst_host in dst_if.remote_hosts:
329 src_host = random.choice(src_hosts)
330 pkt_info = self.create_packet_info(src_if, dst_if)
331 payload = self.info_to_payload(pkt_info)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200332 p = (
333 Ether(dst=src_if.local_mac, src=src_host.mac)
334 / IPv6(src=src_host.ip6, dst=dst_host.ip6)
335 / UDP(sport=1234, dport=1234)
336 / Raw(payload)
337 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200338 pkt_info.data = p.copy()
339 size = random.choice(packet_sizes)
340 self.extend_packet(p, size)
341 pkts.append(p)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200342 self.logger.debug(
343 "Input stream created for port %s. Length: %u pkt(s)"
344 % (src_if.name, len(pkts))
345 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200346 return pkts
347
Jan Gelety057bb8c2016-12-20 17:32:45 +0100348 def verify_capture(self, pg_if, capture):
349 """
350 Verify captured input packet stream for defined interface.
351
352 :param object pg_if: Interface to verify captured packet stream for.
353 :param list capture: Captured packet stream.
354 """
355 last_info = dict()
356 for i in self.pg_interfaces:
357 last_info[i.sw_if_index] = None
358 dst_sw_if_index = pg_if.sw_if_index
359 for packet in capture:
360 try:
361 ip = packet[IPv6]
362 udp = packet[UDP]
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800363 payload_info = self.payload_to_info(packet[Raw])
Jan Gelety057bb8c2016-12-20 17:32:45 +0100364 packet_index = payload_info.index
365 self.assertEqual(payload_info.dst, dst_sw_if_index)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200366 self.logger.debug(
367 "Got packet on port %s: src=%u (id=%u)"
368 % (pg_if.name, payload_info.src, packet_index)
369 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100370 next_info = self.get_next_packet_info_for_interface2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200371 payload_info.src, dst_sw_if_index, last_info[payload_info.src]
372 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100373 last_info[payload_info.src] = next_info
374 self.assertIsNotNone(next_info)
375 self.assertEqual(packet_index, next_info.index)
376 saved_packet = next_info.data
377 # Check standard fields
378 self.assertEqual(ip.src, saved_packet[IPv6].src)
379 self.assertEqual(ip.dst, saved_packet[IPv6].dst)
380 self.assertEqual(udp.sport, saved_packet[UDP].sport)
381 self.assertEqual(udp.dport, saved_packet[UDP].dport)
382 except:
383 self.logger.error(ppp("Unexpected or invalid packet:", packet))
384 raise
385 for i in self.pg_interfaces:
386 remaining_packet = self.get_next_packet_info_for_interface2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200387 i, dst_sw_if_index, last_info[i.sw_if_index]
388 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100389 self.assertIsNone(
390 remaining_packet,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200391 "Port %u: Packet expected from source %u didn't arrive"
392 % (dst_sw_if_index, i.sw_if_index),
393 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100394
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200395 def verify_vrf(self, vrf_id, if_set_id=None):
Jan Gelety057bb8c2016-12-20 17:32:45 +0100396 """
397 Check if the FIB table / VRF ID is configured.
398
399 :param int vrf_id: The FIB table / VRF ID to be verified.
400 :return: 1 if the FIB table / VRF ID is configured, otherwise return 0.
401 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200402 if if_set_id is None:
403 if_set_id = vrf_id
Neale Ranns097fa662018-05-01 05:17:55 -0700404 ip6_fib_dump = self.vapi.ip_route_dump(vrf_id, True)
405 vrf_exist = len(ip6_fib_dump)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100406 vrf_count = 0
407 for ip6_fib_details in ip6_fib_dump:
Neale Ranns097fa662018-05-01 05:17:55 -0700408 addr = ip6_fib_details.route.prefix.network_address
409 found = False
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200410 for pg_if in self.pg_if_sets[if_set_id]:
Neale Ranns097fa662018-05-01 05:17:55 -0700411 if found:
412 break
413 for host in pg_if.remote_hosts:
414 if str(addr) == host.ip6:
415 vrf_count += 1
416 found = True
Jan Gelety95c87b52017-02-27 10:46:14 +0100417 break
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100418 if not vrf_exist and vrf_count == 0:
Jan Gelety057bb8c2016-12-20 17:32:45 +0100419 self.logger.info("IPv6 VRF ID %d is not configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100420 return VRFState.not_configured
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100421 elif vrf_exist and vrf_count == 0:
422 self.logger.info("IPv6 VRF ID %d has been reset" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100423 return VRFState.reset
Jan Gelety057bb8c2016-12-20 17:32:45 +0100424 else:
425 self.logger.info("IPv6 VRF ID %d is configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100426 return VRFState.configured
Jan Gelety057bb8c2016-12-20 17:32:45 +0100427
428 def run_verify_test(self):
429 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200430 Create packet streams for all configured pg interfaces, send all \
Jan Gelety057bb8c2016-12-20 17:32:45 +0100431 prepared packet streams and verify that:
Jan Geletyd16ba622018-06-21 16:57:47 +0200432 - all packets received correctly on all pg-ip6 interfaces assigned
433 to VRFs
434 - no packet received on all pg-ip6 interfaces not assigned to VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +0100435
Jan Geletyd16ba622018-06-21 16:57:47 +0200436 :raise RuntimeError: If no packet captured on pg-ip6 interface assigned
437 to VRF or if any packet is captured on pg-ip6 interface not
438 assigned to VRF.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100439 """
440 # Test
441 # Create incoming packet streams for packet-generator interfaces
442 for pg_if in self.pg_interfaces:
443 pkts = self.create_stream(pg_if, self.pg_if_packet_sizes)
444 pg_if.add_stream(pkts)
445
446 # Enable packet capture and start packet sending
447 self.pg_enable_capture(self.pg_interfaces)
448 self.pg_start()
449
450 # Verify
451 # Verify outgoing packet streams per packet-generator interface
452 for pg_if in self.pg_interfaces:
453 if pg_if in self.pg_in_vrf:
454 capture = pg_if.get_capture(remark="interface is in VRF")
455 self.verify_capture(pg_if, capture)
456 elif pg_if in self.pg_not_in_vrf:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200457 pg_if.assert_nothing_captured(
458 remark="interface is not in VRF", filter_out_fn=is_ipv6_misc_ext
459 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100460 self.logger.debug("No capture for interface %s" % pg_if.name)
461 else:
462 raise Exception("Unknown interface: %s" % pg_if.name)
463
Jan Geletyd16ba622018-06-21 16:57:47 +0200464 def run_crosswise_vrf_test(self):
465 """
466 Create packet streams for every pg-ip6 interface in VRF towards all
Dave Wallaced1706812021-08-12 18:36:02 -0400467 pg-ip6 interfaces in other VRFs, send all prepared packet streams and
Jan Geletyd16ba622018-06-21 16:57:47 +0200468 verify that:
Dave Wallaced1706812021-08-12 18:36:02 -0400469
470 - no packet received on all configured pg-ip6 interfaces
Jan Geletyd16ba622018-06-21 16:57:47 +0200471
472 :raise RuntimeError: If any packet is captured on any pg-ip6 interface.
473 """
474 # Test
475 # Create incoming packet streams for packet-generator interfaces
476 for vrf_id in self.vrf_list:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200477 for pg_if in self.pg_if_sets[vrf_id]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200478 pkts = self.create_stream_crosswise_vrf(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200479 pg_if, vrf_id, self.pg_if_packet_sizes
480 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200481 pg_if.add_stream(pkts)
482
483 # Enable packet capture and start packet sending
484 self.pg_enable_capture(self.pg_interfaces)
485 self.pg_start()
486
487 # Verify
488 # Verify outgoing packet streams per packet-generator interface
489 for pg_if in self.pg_interfaces:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200490 pg_if.assert_nothing_captured(
491 remark="interface is in other VRF", filter_out_fn=is_ipv6_misc_ext
492 )
Jan Geletyd16ba622018-06-21 16:57:47 +0200493 self.logger.debug("No capture for interface %s" % pg_if.name)
494
Jan Gelety057bb8c2016-12-20 17:32:45 +0100495 def test_ip6_vrf_01(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200496 """IP6 VRF Multi-instance test 1 - create 4 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100497 # Config 1
498 # Create 4 VRFs
499 self.create_vrf_and_assign_interfaces(4)
500
501 # Verify 1
502 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200503 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100504
505 # Test 1
506 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200507 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100508
Jan Gelety057bb8c2016-12-20 17:32:45 +0100509 def test_ip6_vrf_02(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200510 """IP6 VRF Multi-instance test 2 - reset 2 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100511 # Config 2
512 # Delete 2 VRFs
Jan Gelety95c87b52017-02-27 10:46:14 +0100513 self.reset_vrf_and_remove_from_vrf_list(1)
514 self.reset_vrf_and_remove_from_vrf_list(2)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100515
516 # Verify 2
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100517 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200518 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100519 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200520 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100521
522 # Test 2
523 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200524 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100525
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100526 # Reset routes learned from ICMPv6 Neighbor Discovery
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200527 # for vrf_id in self.vrf_reset_list:
528 # self.reset_vrf_and_remove_from_vrf_list(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100529
Jan Gelety057bb8c2016-12-20 17:32:45 +0100530 def test_ip6_vrf_03(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200531 """IP6 VRF Multi-instance 3 - add 2 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100532 # Config 3
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100533 # Add 1 of reset VRFs and 1 new VRF
534 self.create_vrf_and_assign_interfaces(1)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100535 self.create_vrf_and_assign_interfaces(1, start=5)
536
537 # Verify 3
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100538 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200539 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100540 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200541 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100542
543 # Test 3
544 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200545 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100546
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100547 # Reset routes learned from ICMPv6 Neighbor Discovery
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200548 # for vrf_id in self.vrf_reset_list:
549 # self.reset_vrf_and_remove_from_vrf_list(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100550
Jan Gelety057bb8c2016-12-20 17:32:45 +0100551 def test_ip6_vrf_04(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200552 """IP6 VRF Multi-instance test 4 - reset 4 VRFs"""
Jan Gelety057bb8c2016-12-20 17:32:45 +0100553 # Config 4
Jan Gelety95c87b52017-02-27 10:46:14 +0100554 # Reset all VRFs (i.e. no VRF except VRF=0 configured)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100555 for i in range(len(self.vrf_list)):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200556 # This call removes the first item of vrf_list as a side effect
Jan Gelety95c87b52017-02-27 10:46:14 +0100557 self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
Jan Gelety057bb8c2016-12-20 17:32:45 +0100558
559 # Verify 4
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100560 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200561 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Jan Gelety95c87b52017-02-27 10:46:14 +0100562 vrf_list_length = len(self.vrf_list)
563 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200564 vrf_list_length,
565 0,
566 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
567 )
Jan Gelety057bb8c2016-12-20 17:32:45 +0100568
569 # Test 4
570 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200571 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100572
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200573 def test_ip6_vrf_05(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200574 """IP6 VRF Multi-instance test 5 - auto allocate vrf id"""
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200575 # Config 5
576 # Create several VRFs
577 # Set vrf_id manually first
578 self.create_vrf_by_id_and_assign_interfaces(1, 10)
579 # Set vrf_id automatically a few times
580 auto_vrf_id = [
581 self.create_vrf_by_id_and_assign_interfaces(i) for i in range(2, 5)
582 ]
583
584 # Verify 5
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200585 self.assert_equal(self.verify_vrf(10, 1), VRFState.configured, VRFState)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200586 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200587 self.assert_equal(
588 self.verify_vrf(vrf, i + 2), VRFState.configured, VRFState
589 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200590
591 # Test 5
592 self.run_verify_test()
593
594 # Config 5.1
595 # Reset VRFs
596 self.reset_vrf_and_remove_from_vrf_list(10, 1)
597 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200598 self.reset_vrf_and_remove_from_vrf_list(vrf, i + 2)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200599
600 # Verify 5.1
601 self.assert_equal(self.verify_vrf(10, 1), VRFState.reset, VRFState)
602 for i, vrf in enumerate(auto_vrf_id):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200603 self.assert_equal(self.verify_vrf(vrf, i + 2), VRFState.reset, VRFState)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200604
605 vrf_list_length = len(self.vrf_list)
606 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200607 vrf_list_length,
608 0,
609 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
610 )
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200611
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200612 # Cleanup our extra created VRFs
613 for vrf in auto_vrf_id:
614 self.delete_vrf(vrf)
615 self.delete_vrf(5)
616 self.delete_vrf(10)
617
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200618 def test_ip6_vrf_06(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200619 """IP6 VRF Multi-instance test 6 - recreate 4 VRFs"""
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200620 # Reconfigure all the VRFs
621 self.create_vrf_and_assign_interfaces(4)
622 # Verify
623 for vrf_id in self.vrf_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200624 self.assert_equal(self.verify_vrf(vrf_id), VRFState.configured, VRFState)
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200625 # Test
626 self.run_verify_test()
627 self.run_crosswise_vrf_test()
628 # Cleanup
629 for i in range(len(self.vrf_list)):
630 self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
631 # Verify
632 for vrf_id in self.vrf_reset_list:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200633 self.assert_equal(self.verify_vrf(vrf_id), VRFState.reset, VRFState)
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200634 vrf_list_length = len(self.vrf_list)
635 self.assertEqual(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200636 vrf_list_length,
637 0,
638 "List of configured VRFs is not empty: %s != 0" % vrf_list_length,
639 )
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200640 # Test
641 self.run_verify_test()
642 self.run_crosswise_vrf_test()
643
Jan Gelety057bb8c2016-12-20 17:32:45 +0100644
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200645if __name__ == "__main__":
Jan Gelety057bb8c2016-12-20 17:32:45 +0100646 unittest.main(testRunner=VppTestRunner)