misc: Remove the unused GBP fields from the buffer meta-data
[vpp.git] / test / test_ip6_vrf_multi_instance.py
1 #!/usr/bin/env python3
2 """IP6 VRF Multi-instance Test Case HLD:
3
4 **NOTES:**
5     - higher number of pg-ip6 interfaces causes problems => only 15 pg-ip6 \
6       interfaces in 5 VRFs are tested
7     - jumbo packets in configuration with 15 pg-ip6 interfaces leads to \
8       problems too
9
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**
20     - check VRF data by parsing output of ip_route_dump API command
21     - all packets received correctly in case of pg-ip6 interfaces in the
22       same VRF
23     - no packet received in case of pg-ip6 interfaces not in VRF
24     - no packet received in case of pg-ip6 interfaces in different VRFs
25
26 **config 2**
27     - reset 2 VRFs
28
29 **test 2**
30     - send IP6 packets between all pg-ip6 interfaces in all VRF groups
31
32 **verify 2**
33     - check VRF data by parsing output of ip_route_dump API command
34     - all packets received correctly in case of pg-ip6 interfaces in the
35       same VRF
36     - no packet received in case of pg-ip6 interfaces not in VRF
37     - no packet received in case of pg-ip6 interfaces in different VRFs
38
39 **config 3**
40     - add 1 of reset VRFs and 1 new VRF
41
42 **test 3**
43     - send IP6 packets between all pg-ip6 interfaces in all VRF groups
44
45 **verify 3**
46     - check VRF data by parsing output of ip_route_dump API command
47     - all packets received correctly in case of pg-ip6 interfaces in the
48       same VRF
49     - no packet received in case of pg-ip6 interfaces not in VRF
50     - no packet received in case of pg-ip6 interfaces in different VRFs
51
52 **config 4**
53     - reset all VRFs (i.e. no VRF except VRF=0 created)
54
55 **test 4**
56     - send IP6 packets between all pg-ip6 interfaces in all VRF groups
57
58 **verify 4**
59     - check VRF data by parsing output of ip_route_dump API command
60     - all packets received correctly in case of pg-ip6 interfaces in the
61       same VRF
62     - no packet received in case of pg-ip6 interfaces not in VRF
63     - no packet received in case of pg-ip6 interfaces in different VRFs
64 """
65
66 import unittest
67 import random
68 import socket
69
70 from scapy.packet import Raw
71 from scapy.layers.l2 import Ether
72 from scapy.layers.inet6 import UDP, IPv6, ICMPv6ND_NS, ICMPv6ND_RA, \
73     RouterAlert, IPv6ExtHdrHopByHop
74 from scapy.utils6 import in6_ismaddr, in6_isllsnmaddr, in6_getAddrType
75 from scapy.pton_ntop import inet_ntop
76
77 from framework import VppTestCase, VppTestRunner
78 from util import ppp
79 from vrf import VRFState
80
81
82 def 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
97
98 class 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)):
123                 multiplicand = i // cls.pg_ifs_per_vrf
124                 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
141             # Create list of reset VRFs
142             cls.vrf_reset_list = list()
143
144             # Create list of pg_interfaces in VRFs
145             cls.pg_in_vrf = list()
146
147             # Create list of pg_interfaces not in VRFs
148             cls.pg_not_in_vrf = [pg_if for pg_if in cls.pg_interfaces]
149
150             # Create mapping of pg_interfaces to VRF IDs
151             cls.pg_if_sets = dict()
152             for i in range(cls.nr_of_vrfs):
153                 set_id = i + 1
154                 pg_list = [
155                     cls.pg_interfaces[i * cls.pg_ifs_per_vrf + j]
156                     for j in range(cls.pg_ifs_per_vrf)]
157                 cls.pg_if_sets[set_id] = pg_list
158
159         except Exception:
160             super(TestIP6VrfMultiInst, cls).tearDownClass()
161             raise
162
163     @classmethod
164     def tearDownClass(cls):
165         super(TestIP6VrfMultiInst, cls).tearDownClass()
166
167     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()
179
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"))
183
184     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
198     def create_vrf_and_assign_interfaces(self, count, start=1):
199         """
200         Create required number of FIB tables / VRFs, put 3 pg-ip6 interfaces
201         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
209             self.vapi.ip_table_add_del(is_add=1,
210                                        table={'table_id': vrf_id, 'is_ip6': 1})
211             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)
214             if vrf_id in self.vrf_reset_list:
215                 self.vrf_reset_list.remove(vrf_id)
216             self._assign_interfaces(vrf_id, vrf_id)
217         self.logger.debug(self.vapi.ppcli("show ip6 fib"))
218         self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
219
220     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):
244         """
245         Reset required FIB table / VRF and remove it from VRF list.
246
247         :param int vrf_id: The FIB table / VRF ID to be reset.
248         """
249         if if_set_id is None:
250             if_set_id = vrf_id
251         self.vapi.ip_table_flush(table={'table_id': vrf_id, 'is_ip6': 1})
252         if vrf_id in self.vrf_list:
253             self.vrf_list.remove(vrf_id)
254         if vrf_id not in self.vrf_reset_list:
255             self.vrf_reset_list.append(vrf_id)
256         for j in range(self.pg_ifs_per_vrf):
257             pg_if = self.pg_if_sets[if_set_id][j]
258             pg_if.unconfig_ip6()
259             pg_if.set_table_ip6(0)
260             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)
264         self.logger.info("IPv6 VRF ID %d reset finished" % vrf_id)
265         self.logger.debug(self.vapi.ppcli("show ip6 fib"))
266         self.logger.debug(self.vapi.ppcli("show ip6 neighbors"))
267
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)
273         self.vapi.ip_table_add_del(is_add=0,
274                                    table={'table_id': vrf_id, 'is_ip6': 1})
275
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
303     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:
318             for dst_if in self.pg_if_sets[vrf]:
319                 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
335     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]
350                 payload_info = self.payload_to_info(packet[Raw])
351                 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
378     def verify_vrf(self, vrf_id, if_set_id=None):
379         """
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         """
385         if if_set_id is None:
386             if_set_id = vrf_id
387         ip6_fib_dump = self.vapi.ip_route_dump(vrf_id, True)
388         vrf_exist = len(ip6_fib_dump)
389         vrf_count = 0
390         for ip6_fib_details in ip6_fib_dump:
391             addr = ip6_fib_details.route.prefix.network_address
392             found = False
393             for pg_if in self.pg_if_sets[if_set_id]:
394                 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
400                         break
401         if not vrf_exist and vrf_count == 0:
402             self.logger.info("IPv6 VRF ID %d is not configured" % vrf_id)
403             return VRFState.not_configured
404         elif vrf_exist and vrf_count == 0:
405             self.logger.info("IPv6 VRF ID %d has been reset" % vrf_id)
406             return VRFState.reset
407         else:
408             self.logger.info("IPv6 VRF ID %d is configured" % vrf_id)
409             return VRFState.configured
410
411     def run_verify_test(self):
412         """
413         Create packet streams for all configured pg interfaces, send all \
414         prepared packet streams and verify that:
415             - 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
418
419         :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.
422         """
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:
440                 pg_if.assert_nothing_captured(remark="interface is not in VRF",
441                                               filter_out_fn=is_ipv6_misc_ext)
442                 self.logger.debug("No capture for interface %s" % pg_if.name)
443             else:
444                 raise Exception("Unknown interface: %s" % pg_if.name)
445
446     def run_crosswise_vrf_test(self):
447         """
448         Create packet streams for every pg-ip6 interface in VRF towards all
449         pg-ip6 interfaces in other VRFs, send all prepared packet streams and
450         verify that:
451
452         - no packet received on all configured pg-ip6 interfaces
453
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:
459             for pg_if in self.pg_if_sets[vrf_id]:
460                 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
475     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:
484             self.assert_equal(self.verify_vrf(vrf_id),
485                               VRFState.configured, VRFState)
486
487         # Test 1
488         self.run_verify_test()
489         self.run_crosswise_vrf_test()
490
491     def test_ip6_vrf_02(self):
492         """ IP6 VRF  Multi-instance test 2 - reset 2 VRFs
493         """
494         # Config 2
495         # Delete 2 VRFs
496         self.reset_vrf_and_remove_from_vrf_list(1)
497         self.reset_vrf_and_remove_from_vrf_list(2)
498
499         # Verify 2
500         for vrf_id in self.vrf_reset_list:
501             self.assert_equal(self.verify_vrf(vrf_id),
502                               VRFState.reset, VRFState)
503         for vrf_id in self.vrf_list:
504             self.assert_equal(self.verify_vrf(vrf_id),
505                               VRFState.configured, VRFState)
506
507         # Test 2
508         self.run_verify_test()
509         self.run_crosswise_vrf_test()
510
511         # Reset routes learned from ICMPv6 Neighbor Discovery
512         # for vrf_id in self.vrf_reset_list:
513         #     self.reset_vrf_and_remove_from_vrf_list(vrf_id)
514
515     def test_ip6_vrf_03(self):
516         """ IP6 VRF  Multi-instance 3 - add 2 VRFs
517         """
518         # Config 3
519         # Add 1 of reset VRFs and 1 new VRF
520         self.create_vrf_and_assign_interfaces(1)
521         self.create_vrf_and_assign_interfaces(1, start=5)
522
523         # Verify 3
524         for vrf_id in self.vrf_reset_list:
525             self.assert_equal(self.verify_vrf(vrf_id),
526                               VRFState.reset, VRFState)
527         for vrf_id in self.vrf_list:
528             self.assert_equal(self.verify_vrf(vrf_id),
529                               VRFState.configured, VRFState)
530
531         # Test 3
532         self.run_verify_test()
533         self.run_crosswise_vrf_test()
534
535         # Reset routes learned from ICMPv6 Neighbor Discovery
536         # for vrf_id in self.vrf_reset_list:
537         #     self.reset_vrf_and_remove_from_vrf_list(vrf_id)
538
539     def test_ip6_vrf_04(self):
540         """ IP6 VRF  Multi-instance test 4 - reset 4 VRFs
541         """
542         # Config 4
543         # Reset all VRFs (i.e. no VRF except VRF=0 configured)
544         for i in range(len(self.vrf_list)):
545             # This call removes the first item of vrf_list as a side effect
546             self.reset_vrf_and_remove_from_vrf_list(self.vrf_list[0])
547
548         # Verify 4
549         for vrf_id in self.vrf_reset_list:
550             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)
556
557         # Test 4
558         self.run_verify_test()
559         self.run_crosswise_vrf_test()
560
561     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
600         # 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
606     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
633
634 if __name__ == '__main__':
635     unittest.main(testRunner=VppTestRunner)