blob: d95e7927f98dd0c024de98d69ca651dde934c640 [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
Jan Geletyb5b2ef52017-02-23 15:01:29 +010072from scapy.layers.inet6 import UDP, IPv6, ICMPv6ND_NS, ICMPv6ND_RA, \
73 RouterAlert, IPv6ExtHdrHopByHop
74from scapy.utils6 import in6_ismaddr, in6_isllsnmaddr, in6_getAddrType
75from scapy.pton_ntop import inet_ntop
Jan Gelety057bb8c2016-12-20 17:32:45 +010076
77from framework import VppTestCase, VppTestRunner
78from util import ppp
Jan Gelety95c87b52017-02-27 10:46:14 +010079from vrf import VRFState
Jan Geletyb5b2ef52017-02-23 15:01:29 +010080
81
82def is_ipv6_misc_ext(p):
83 """ Is packet one of uninteresting IPv6 broadcasts (extended to filter out
84 ICMPv6 Neighbor Discovery - Neighbor Advertisement packets too)? """
85 if p.haslayer(ICMPv6ND_RA):
86 if in6_ismaddr(p[IPv6].dst):
87 return True
88 if p.haslayer(ICMPv6ND_NS):
89 if in6_isllsnmaddr(p[IPv6].dst):
90 return True
91 if p.haslayer(IPv6ExtHdrHopByHop):
92 for o in p[IPv6ExtHdrHopByHop].options:
93 if isinstance(o, RouterAlert):
94 return True
95 return False
96
Jan Gelety057bb8c2016-12-20 17:32:45 +010097
98class TestIP6VrfMultiInst(VppTestCase):
99 """ IP6 VRF Multi-instance Test Case """
100
101 @classmethod
102 def setUpClass(cls):
103 """
104 Perform standard class setup (defined by class method setUpClass in
105 class VppTestCase) before running the test case, set test case related
106 variables and configure VPP.
107 """
108 super(TestIP6VrfMultiInst, cls).setUpClass()
109
110 # Test variables
111 cls.hosts_per_pg = 5
112 cls.nr_of_vrfs = 5
113 cls.pg_ifs_per_vrf = 3
114
115 try:
116 # Create pg interfaces
117 cls.create_pg_interfaces(
118 range(cls.nr_of_vrfs * cls.pg_ifs_per_vrf))
119
120 # Packet flows mapping pg0 -> pg1, pg2 etc.
121 cls.flows = dict()
122 for i in range(len(cls.pg_interfaces)):
Ole Troan19757332019-10-18 14:54:30 +0200123 multiplicand = i // cls.pg_ifs_per_vrf
Jan Gelety057bb8c2016-12-20 17:32:45 +0100124 pg_list = [
125 cls.pg_interfaces[multiplicand * cls.pg_ifs_per_vrf + j]
126 for j in range(cls.pg_ifs_per_vrf)
127 if (multiplicand * cls.pg_ifs_per_vrf + j) != i]
128 cls.flows[cls.pg_interfaces[i]] = pg_list
129
130 # Packet sizes - jumbo packet (9018 bytes) skipped
131 cls.pg_if_packet_sizes = [64, 512, 1518]
132
133 # Set up all interfaces
134 for pg_if in cls.pg_interfaces:
135 pg_if.admin_up()
136 pg_if.generate_remote_hosts(cls.hosts_per_pg)
137
138 # Create list of VRFs
139 cls.vrf_list = list()
140
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100141 # Create list of reset VRFs
142 cls.vrf_reset_list = list()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100143
144 # Create list of pg_interfaces in VRFs
145 cls.pg_in_vrf = list()
146
Jan Geletyd16ba622018-06-21 16:57:47 +0200147 # Create list of pg_interfaces not in VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +0100148 cls.pg_not_in_vrf = [pg_if for pg_if in cls.pg_interfaces]
149
150 # Create mapping of pg_interfaces to VRF IDs
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200151 cls.pg_if_sets = dict()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100152 for i in range(cls.nr_of_vrfs):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200153 set_id = i + 1
Jan Gelety057bb8c2016-12-20 17:32:45 +0100154 pg_list = [
155 cls.pg_interfaces[i * cls.pg_ifs_per_vrf + j]
156 for j in range(cls.pg_ifs_per_vrf)]
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200157 cls.pg_if_sets[set_id] = pg_list
Jan Gelety057bb8c2016-12-20 17:32:45 +0100158
159 except Exception:
160 super(TestIP6VrfMultiInst, cls).tearDownClass()
161 raise
162
Paul Vinciguerra7f9b7f92019-03-12 19:23:27 -0700163 @classmethod
164 def tearDownClass(cls):
165 super(TestIP6VrfMultiInst, cls).tearDownClass()
166
Jan Gelety057bb8c2016-12-20 17:32:45 +0100167 def setUp(self):
168 """
169 Clear trace and packet infos before running each test.
170 """
171 super(TestIP6VrfMultiInst, self).setUp()
172 self.reset_packet_infos()
173
174 def tearDown(self):
175 """
176 Show various debug prints after each test.
177 """
178 super(TestIP6VrfMultiInst, self).tearDown()
Paul Vinciguerra90cf21b2019-03-13 09:23:05 -0700179
180 def show_commands_at_teardown(self):
181 self.logger.info(self.vapi.ppcli("show ip6 fib"))
182 self.logger.info(self.vapi.ppcli("show ip6 neighbors"))
Jan Gelety057bb8c2016-12-20 17:32:45 +0100183
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200184 def _assign_interfaces(self, vrf_id, if_set_id):
185 for i in range(self.pg_ifs_per_vrf):
186 pg_if = self.pg_if_sets[if_set_id][i]
187 pg_if.set_table_ip6(vrf_id)
188 self.logger.info("pg-interface %s added to IPv6 VRF ID %d"
189 % (pg_if.name, vrf_id))
190 if pg_if not in self.pg_in_vrf:
191 self.pg_in_vrf.append(pg_if)
192 if pg_if in self.pg_not_in_vrf:
193 self.pg_not_in_vrf.remove(pg_if)
194 pg_if.config_ip6()
195 pg_if.disable_ipv6_ra()
196 pg_if.configure_ipv6_neighbors()
197
Jan Gelety057bb8c2016-12-20 17:32:45 +0100198 def create_vrf_and_assign_interfaces(self, count, start=1):
199 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200200 Create required number of FIB tables / VRFs, put 3 pg-ip6 interfaces
Jan Gelety057bb8c2016-12-20 17:32:45 +0100201 to every FIB table / VRF.
202
203 :param int count: Number of FIB tables / VRFs to be created.
204 :param int start: Starting number of the FIB table / VRF ID. \
205 (Default value = 1)
206 """
207 for i in range(count):
208 vrf_id = i + start
Neale Ranns9db6ada2019-11-08 12:42:31 +0000209 self.vapi.ip_table_add_del(is_add=1,
210 table={'table_id': vrf_id, 'is_ip6': 1})
Jan Gelety057bb8c2016-12-20 17:32:45 +0100211 self.logger.info("IPv6 VRF ID %d created" % vrf_id)
212 if vrf_id not in self.vrf_list:
213 self.vrf_list.append(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100214 if vrf_id in self.vrf_reset_list:
215 self.vrf_reset_list.remove(vrf_id)
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200216 self._assign_interfaces(vrf_id, vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100217 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
218 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
219
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200220 def create_vrf_by_id_and_assign_interfaces(self, set_id,
221 vrf_id=0xffffffff):
222 """
223 Create a FIB table / VRF by vrf_id, put 3 pg-ip6 interfaces
224 to FIB table / VRF.
225
226 :param int vrf_id: Required table ID / VRF ID. \
227 (Default value = 0xffffffff, ID will be selected automatically)
228 """
229 ret = self.vapi.ip_table_allocate(table={'table_id': vrf_id,
230 'is_ip6': 1})
231 vrf_id = ret.table.table_id
232 self.logger.info("IPv6 VRF ID %d created" % vrf_id)
233 if vrf_id not in self.vrf_list:
234 self.vrf_list.append(vrf_id)
235 if vrf_id in self.vrf_reset_list:
236 self.vrf_reset_list.remove(vrf_id)
237 self._assign_interfaces(vrf_id, set_id)
238 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
239 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
240
241 return vrf_id
242
243 def reset_vrf_and_remove_from_vrf_list(self, vrf_id, if_set_id=None):
Jan Gelety057bb8c2016-12-20 17:32:45 +0100244 """
Jan Gelety95c87b52017-02-27 10:46:14 +0100245 Reset required FIB table / VRF and remove it from VRF list.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100246
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100247 :param int vrf_id: The FIB table / VRF ID to be reset.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100248 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200249 if if_set_id is None:
250 if_set_id = vrf_id
Neale Ranns9db6ada2019-11-08 12:42:31 +0000251 self.vapi.ip_table_flush(table={'table_id': vrf_id, 'is_ip6': 1})
Jan Gelety057bb8c2016-12-20 17:32:45 +0100252 if vrf_id in self.vrf_list:
253 self.vrf_list.remove(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100254 if vrf_id not in self.vrf_reset_list:
255 self.vrf_reset_list.append(vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100256 for j in range(self.pg_ifs_per_vrf):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200257 pg_if = self.pg_if_sets[if_set_id][j]
Neale Ranns4008ac92017-02-13 23:20:04 -0800258 pg_if.unconfig_ip6()
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200259 pg_if.set_table_ip6(0)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100260 if pg_if in self.pg_in_vrf:
261 self.pg_in_vrf.remove(pg_if)
262 if pg_if not in self.pg_not_in_vrf:
263 self.pg_not_in_vrf.append(pg_if)
Jan Gelety95c87b52017-02-27 10:46:14 +0100264 self.logger.info("IPv6 VRF ID %d reset finished" % vrf_id)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100265 self.logger.debug(self.vapi.ppcli("show ip6 fib"))
266 self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200267
268 def delete_vrf(self, vrf_id):
269 if vrf_id in self.vrf_list:
270 self.vrf_list.remove(vrf_id)
271 if vrf_id in self.vrf_reset_list:
272 self.vrf_reset_list.remove(vrf_id)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000273 self.vapi.ip_table_add_del(is_add=0,
274 table={'table_id': vrf_id, 'is_ip6': 1})
Jan Gelety057bb8c2016-12-20 17:32:45 +0100275
276 def create_stream(self, src_if, packet_sizes):
277 """
278 Create input packet stream for defined interface using hosts list.
279
280 :param object src_if: Interface to create packet stream for.
281 :param list packet_sizes: List of required packet sizes.
282 :return: Stream of packets.
283 """
284 pkts = []
285 src_hosts = src_if.remote_hosts
286 for dst_if in self.flows[src_if]:
287 for dst_host in dst_if.remote_hosts:
288 src_host = random.choice(src_hosts)
289 pkt_info = self.create_packet_info(src_if, dst_if)
290 payload = self.info_to_payload(pkt_info)
291 p = (Ether(dst=src_if.local_mac, src=src_host.mac) /
292 IPv6(src=src_host.ip6, dst=dst_host.ip6) /
293 UDP(sport=1234, dport=1234) /
294 Raw(payload))
295 pkt_info.data = p.copy()
296 size = random.choice(packet_sizes)
297 self.extend_packet(p, size)
298 pkts.append(p)
299 self.logger.debug("Input stream created for port %s. Length: %u pkt(s)"
300 % (src_if.name, len(pkts)))
301 return pkts
302
Jan Geletyd16ba622018-06-21 16:57:47 +0200303 def create_stream_crosswise_vrf(self, src_if, vrf_id, packet_sizes):
304 """
305 Create input packet stream for negative test for leaking across
306 different VRFs for defined interface using hosts list.
307
308 :param object src_if: Interface to create packet stream for.
309 :param int vrf_id: The FIB table / VRF ID where src_if is assigned.
310 :param list packet_sizes: List of required packet sizes.
311 :return: Stream of packets.
312 """
313 pkts = []
314 src_hosts = src_if.remote_hosts
315 vrf_lst = list(self.vrf_list)
316 vrf_lst.remove(vrf_id)
317 for vrf in vrf_lst:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200318 for dst_if in self.pg_if_sets[vrf]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200319 for dst_host in dst_if.remote_hosts:
320 src_host = random.choice(src_hosts)
321 pkt_info = self.create_packet_info(src_if, dst_if)
322 payload = self.info_to_payload(pkt_info)
323 p = (Ether(dst=src_if.local_mac, src=src_host.mac) /
324 IPv6(src=src_host.ip6, dst=dst_host.ip6) /
325 UDP(sport=1234, dport=1234) /
326 Raw(payload))
327 pkt_info.data = p.copy()
328 size = random.choice(packet_sizes)
329 self.extend_packet(p, size)
330 pkts.append(p)
331 self.logger.debug("Input stream created for port %s. Length: %u pkt(s)"
332 % (src_if.name, len(pkts)))
333 return pkts
334
Jan Gelety057bb8c2016-12-20 17:32:45 +0100335 def verify_capture(self, pg_if, capture):
336 """
337 Verify captured input packet stream for defined interface.
338
339 :param object pg_if: Interface to verify captured packet stream for.
340 :param list capture: Captured packet stream.
341 """
342 last_info = dict()
343 for i in self.pg_interfaces:
344 last_info[i.sw_if_index] = None
345 dst_sw_if_index = pg_if.sw_if_index
346 for packet in capture:
347 try:
348 ip = packet[IPv6]
349 udp = packet[UDP]
Paul Vinciguerraeaea4212019-03-06 11:58:06 -0800350 payload_info = self.payload_to_info(packet[Raw])
Jan Gelety057bb8c2016-12-20 17:32:45 +0100351 packet_index = payload_info.index
352 self.assertEqual(payload_info.dst, dst_sw_if_index)
353 self.logger.debug("Got packet on port %s: src=%u (id=%u)" %
354 (pg_if.name, payload_info.src, packet_index))
355 next_info = self.get_next_packet_info_for_interface2(
356 payload_info.src, dst_sw_if_index,
357 last_info[payload_info.src])
358 last_info[payload_info.src] = next_info
359 self.assertIsNotNone(next_info)
360 self.assertEqual(packet_index, next_info.index)
361 saved_packet = next_info.data
362 # Check standard fields
363 self.assertEqual(ip.src, saved_packet[IPv6].src)
364 self.assertEqual(ip.dst, saved_packet[IPv6].dst)
365 self.assertEqual(udp.sport, saved_packet[UDP].sport)
366 self.assertEqual(udp.dport, saved_packet[UDP].dport)
367 except:
368 self.logger.error(ppp("Unexpected or invalid packet:", packet))
369 raise
370 for i in self.pg_interfaces:
371 remaining_packet = self.get_next_packet_info_for_interface2(
372 i, dst_sw_if_index, last_info[i.sw_if_index])
373 self.assertIsNone(
374 remaining_packet,
375 "Port %u: Packet expected from source %u didn't arrive" %
376 (dst_sw_if_index, i.sw_if_index))
377
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200378 def verify_vrf(self, vrf_id, if_set_id=None):
Jan Gelety057bb8c2016-12-20 17:32:45 +0100379 """
380 Check if the FIB table / VRF ID is configured.
381
382 :param int vrf_id: The FIB table / VRF ID to be verified.
383 :return: 1 if the FIB table / VRF ID is configured, otherwise return 0.
384 """
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200385 if if_set_id is None:
386 if_set_id = vrf_id
Neale Ranns097fa662018-05-01 05:17:55 -0700387 ip6_fib_dump = self.vapi.ip_route_dump(vrf_id, True)
388 vrf_exist = len(ip6_fib_dump)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100389 vrf_count = 0
390 for ip6_fib_details in ip6_fib_dump:
Neale Ranns097fa662018-05-01 05:17:55 -0700391 addr = ip6_fib_details.route.prefix.network_address
392 found = False
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200393 for pg_if in self.pg_if_sets[if_set_id]:
Neale Ranns097fa662018-05-01 05:17:55 -0700394 if found:
395 break
396 for host in pg_if.remote_hosts:
397 if str(addr) == host.ip6:
398 vrf_count += 1
399 found = True
Jan Gelety95c87b52017-02-27 10:46:14 +0100400 break
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100401 if not vrf_exist and vrf_count == 0:
Jan Gelety057bb8c2016-12-20 17:32:45 +0100402 self.logger.info("IPv6 VRF ID %d is not configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100403 return VRFState.not_configured
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100404 elif vrf_exist and vrf_count == 0:
405 self.logger.info("IPv6 VRF ID %d has been reset" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100406 return VRFState.reset
Jan Gelety057bb8c2016-12-20 17:32:45 +0100407 else:
408 self.logger.info("IPv6 VRF ID %d is configured" % vrf_id)
Jan Gelety95c87b52017-02-27 10:46:14 +0100409 return VRFState.configured
Jan Gelety057bb8c2016-12-20 17:32:45 +0100410
411 def run_verify_test(self):
412 """
Jan Geletyd16ba622018-06-21 16:57:47 +0200413 Create packet streams for all configured pg interfaces, send all \
Jan Gelety057bb8c2016-12-20 17:32:45 +0100414 prepared packet streams and verify that:
Jan Geletyd16ba622018-06-21 16:57:47 +0200415 - all packets received correctly on all pg-ip6 interfaces assigned
416 to VRFs
417 - no packet received on all pg-ip6 interfaces not assigned to VRFs
Jan Gelety057bb8c2016-12-20 17:32:45 +0100418
Jan Geletyd16ba622018-06-21 16:57:47 +0200419 :raise RuntimeError: If no packet captured on pg-ip6 interface assigned
420 to VRF or if any packet is captured on pg-ip6 interface not
421 assigned to VRF.
Jan Gelety057bb8c2016-12-20 17:32:45 +0100422 """
423 # Test
424 # Create incoming packet streams for packet-generator interfaces
425 for pg_if in self.pg_interfaces:
426 pkts = self.create_stream(pg_if, self.pg_if_packet_sizes)
427 pg_if.add_stream(pkts)
428
429 # Enable packet capture and start packet sending
430 self.pg_enable_capture(self.pg_interfaces)
431 self.pg_start()
432
433 # Verify
434 # Verify outgoing packet streams per packet-generator interface
435 for pg_if in self.pg_interfaces:
436 if pg_if in self.pg_in_vrf:
437 capture = pg_if.get_capture(remark="interface is in VRF")
438 self.verify_capture(pg_if, capture)
439 elif pg_if in self.pg_not_in_vrf:
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100440 pg_if.assert_nothing_captured(remark="interface is not in VRF",
441 filter_out_fn=is_ipv6_misc_ext)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100442 self.logger.debug("No capture for interface %s" % pg_if.name)
443 else:
444 raise Exception("Unknown interface: %s" % pg_if.name)
445
Jan Geletyd16ba622018-06-21 16:57:47 +0200446 def run_crosswise_vrf_test(self):
447 """
448 Create packet streams for every pg-ip6 interface in VRF towards all
Dave Wallaced1706812021-08-12 18:36:02 -0400449 pg-ip6 interfaces in other VRFs, send all prepared packet streams and
Jan Geletyd16ba622018-06-21 16:57:47 +0200450 verify that:
Dave Wallaced1706812021-08-12 18:36:02 -0400451
452 - no packet received on all configured pg-ip6 interfaces
Jan Geletyd16ba622018-06-21 16:57:47 +0200453
454 :raise RuntimeError: If any packet is captured on any pg-ip6 interface.
455 """
456 # Test
457 # Create incoming packet streams for packet-generator interfaces
458 for vrf_id in self.vrf_list:
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200459 for pg_if in self.pg_if_sets[vrf_id]:
Jan Geletyd16ba622018-06-21 16:57:47 +0200460 pkts = self.create_stream_crosswise_vrf(
461 pg_if, vrf_id, self.pg_if_packet_sizes)
462 pg_if.add_stream(pkts)
463
464 # Enable packet capture and start packet sending
465 self.pg_enable_capture(self.pg_interfaces)
466 self.pg_start()
467
468 # Verify
469 # Verify outgoing packet streams per packet-generator interface
470 for pg_if in self.pg_interfaces:
471 pg_if.assert_nothing_captured(remark="interface is in other VRF",
472 filter_out_fn=is_ipv6_misc_ext)
473 self.logger.debug("No capture for interface %s" % pg_if.name)
474
Jan Gelety057bb8c2016-12-20 17:32:45 +0100475 def test_ip6_vrf_01(self):
476 """ IP6 VRF Multi-instance test 1 - create 4 VRFs
477 """
478 # Config 1
479 # Create 4 VRFs
480 self.create_vrf_and_assign_interfaces(4)
481
482 # Verify 1
483 for vrf_id in self.vrf_list:
Jan Gelety95c87b52017-02-27 10:46:14 +0100484 self.assert_equal(self.verify_vrf(vrf_id),
485 VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100486
487 # Test 1
488 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200489 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100490
Jan Gelety057bb8c2016-12-20 17:32:45 +0100491 def test_ip6_vrf_02(self):
492 """ IP6 VRF Multi-instance test 2 - reset 2 VRFs
493 """
494 # Config 2
495 # Delete 2 VRFs
Jan Gelety95c87b52017-02-27 10:46:14 +0100496 self.reset_vrf_and_remove_from_vrf_list(1)
497 self.reset_vrf_and_remove_from_vrf_list(2)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100498
499 # Verify 2
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100500 for vrf_id in self.vrf_reset_list:
Jan Gelety95c87b52017-02-27 10:46:14 +0100501 self.assert_equal(self.verify_vrf(vrf_id),
502 VRFState.reset, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100503 for vrf_id in self.vrf_list:
Jan Gelety95c87b52017-02-27 10:46:14 +0100504 self.assert_equal(self.verify_vrf(vrf_id),
505 VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100506
507 # Test 2
508 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200509 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100510
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100511 # Reset routes learned from ICMPv6 Neighbor Discovery
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200512 # for vrf_id in self.vrf_reset_list:
513 # self.reset_vrf_and_remove_from_vrf_list(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100514
Jan Gelety057bb8c2016-12-20 17:32:45 +0100515 def test_ip6_vrf_03(self):
516 """ IP6 VRF Multi-instance 3 - add 2 VRFs
517 """
518 # Config 3
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100519 # Add 1 of reset VRFs and 1 new VRF
520 self.create_vrf_and_assign_interfaces(1)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100521 self.create_vrf_and_assign_interfaces(1, start=5)
522
523 # Verify 3
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100524 for vrf_id in self.vrf_reset_list:
Jan Gelety95c87b52017-02-27 10:46:14 +0100525 self.assert_equal(self.verify_vrf(vrf_id),
526 VRFState.reset, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100527 for vrf_id in self.vrf_list:
Jan Gelety95c87b52017-02-27 10:46:14 +0100528 self.assert_equal(self.verify_vrf(vrf_id),
529 VRFState.configured, VRFState)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100530
531 # Test 3
532 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200533 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100534
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100535 # Reset routes learned from ICMPv6 Neighbor Discovery
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200536 # for vrf_id in self.vrf_reset_list:
537 # self.reset_vrf_and_remove_from_vrf_list(vrf_id)
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100538
Jan Gelety057bb8c2016-12-20 17:32:45 +0100539 def test_ip6_vrf_04(self):
540 """ IP6 VRF Multi-instance test 4 - reset 4 VRFs
541 """
542 # Config 4
Jan Gelety95c87b52017-02-27 10:46:14 +0100543 # Reset all VRFs (i.e. no VRF except VRF=0 configured)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100544 for i in range(len(self.vrf_list)):
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200545 # This call removes the first item of vrf_list as a side effect
Jan Gelety95c87b52017-02-27 10:46:14 +0100546 self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
Jan Gelety057bb8c2016-12-20 17:32:45 +0100547
548 # Verify 4
Jan Geletyb5b2ef52017-02-23 15:01:29 +0100549 for vrf_id in self.vrf_reset_list:
Jan Gelety95c87b52017-02-27 10:46:14 +0100550 self.assert_equal(self.verify_vrf(vrf_id),
551 VRFState.reset, VRFState)
552 vrf_list_length = len(self.vrf_list)
553 self.assertEqual(
554 vrf_list_length, 0,
555 "List of configured VRFs is not empty: %s != 0" % vrf_list_length)
Jan Gelety057bb8c2016-12-20 17:32:45 +0100556
557 # Test 4
558 self.run_verify_test()
Jan Geletyd16ba622018-06-21 16:57:47 +0200559 self.run_crosswise_vrf_test()
Jan Gelety057bb8c2016-12-20 17:32:45 +0100560
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200561 def test_ip6_vrf_05(self):
562 """ IP6 VRF Multi-instance test 5 - auto allocate vrf id
563 """
564 # Config 5
565 # Create several VRFs
566 # Set vrf_id manually first
567 self.create_vrf_by_id_and_assign_interfaces(1, 10)
568 # Set vrf_id automatically a few times
569 auto_vrf_id = [
570 self.create_vrf_by_id_and_assign_interfaces(i) for i in range(2, 5)
571 ]
572
573 # Verify 5
574 self.assert_equal(self.verify_vrf(10, 1), VRFState.configured,
575 VRFState)
576 for i, vrf in enumerate(auto_vrf_id):
577 self.assert_equal(self.verify_vrf(vrf, i+2),
578 VRFState.configured, VRFState)
579
580 # Test 5
581 self.run_verify_test()
582
583 # Config 5.1
584 # Reset VRFs
585 self.reset_vrf_and_remove_from_vrf_list(10, 1)
586 for i, vrf in enumerate(auto_vrf_id):
587 self.reset_vrf_and_remove_from_vrf_list(vrf, i+2)
588
589 # Verify 5.1
590 self.assert_equal(self.verify_vrf(10, 1), VRFState.reset, VRFState)
591 for i, vrf in enumerate(auto_vrf_id):
592 self.assert_equal(self.verify_vrf(vrf, i+2),
593 VRFState.reset, VRFState)
594
595 vrf_list_length = len(self.vrf_list)
596 self.assertEqual(
597 vrf_list_length, 0,
598 "List of configured VRFs is not empty: %s != 0" % vrf_list_length)
599
Nathan Skrzypczaka424dd12021-08-20 15:53:43 +0200600 # Cleanup our extra created VRFs
601 for vrf in auto_vrf_id:
602 self.delete_vrf(vrf)
603 self.delete_vrf(5)
604 self.delete_vrf(10)
605
Nathan Skrzypczak275bd792021-09-17 17:29:14 +0200606 def test_ip6_vrf_06(self):
607 """ IP6 VRF Multi-instance test 6 - recreate 4 VRFs
608 """
609 # Reconfigure all the VRFs
610 self.create_vrf_and_assign_interfaces(4)
611 # Verify
612 for vrf_id in self.vrf_list:
613 self.assert_equal(self.verify_vrf(vrf_id),
614 VRFState.configured, VRFState)
615 # Test
616 self.run_verify_test()
617 self.run_crosswise_vrf_test()
618 # Cleanup
619 for i in range(len(self.vrf_list)):
620 self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
621 # Verify
622 for vrf_id in self.vrf_reset_list:
623 self.assert_equal(self.verify_vrf(vrf_id),
624 VRFState.reset, VRFState)
625 vrf_list_length = len(self.vrf_list)
626 self.assertEqual(
627 vrf_list_length, 0,
628 "List of configured VRFs is not empty: %s != 0" % vrf_list_length)
629 # Test
630 self.run_verify_test()
631 self.run_crosswise_vrf_test()
632
Jan Gelety057bb8c2016-12-20 17:32:45 +0100633
634if __name__ == '__main__':
635 unittest.main(testRunner=VppTestRunner)