]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_static_routes_topo1.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / multicast_pim_dr_nondr_test / test_pim_dr_nondr_with_static_routes_topo1.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Copyright (c) 2020 by VMware, Inc. ("VMware")
6 # Used Copyright (c) 2018 by Network Device Education Foundation,
7 # Inc. ("NetDEF") in this file.
8 #
9
10 """
11 Following tests are covered to test multicast pim sm:
12
13 Test steps
14 - Create topology (setup module)
15 - Bring up topology
16
17 Following tests are covered:
18 1. Verify mroute while rebooting DR /Non DR nodes( r1, r2 , r3 on all the nodes)
19 """
20
21 import os
22 import sys
23 import json
24 import time
25 import datetime
26 from time import sleep
27 import pytest
28
29 # Save the Current Working Directory to find configuration files.
30 CWD = os.path.dirname(os.path.realpath(__file__))
31 sys.path.append(os.path.join(CWD, "../"))
32 sys.path.append(os.path.join(CWD, "../lib/"))
33
34 # Required to instantiate the topology builder class.
35
36 # pylint: disable=C0413
37 # Import topogen and topotest helpers
38 from lib.topogen import Topogen, get_topogen
39
40 from lib.common_config import (
41 start_topology,
42 write_test_header,
43 write_test_footer,
44 step,
45 reset_config_on_routers,
46 apply_raw_config,
47 add_interfaces_to_vlan,
48 stop_router,
49 start_router,
50 check_router_status,
51 topo_daemons,
52 required_linux_kernel_version,
53 )
54 from lib.pim import (
55 create_pim_config,
56 create_igmp_config,
57 verify_mroutes,
58 clear_mroute,
59 clear_pim_interface_traffic,
60 verify_pim_config,
61 verify_upstream_iif,
62 verify_multicast_flag_state,
63 McastTesterHelper,
64 )
65 from lib.topolog import logger
66 from lib.topojson import build_config_from_json
67
68 HELLO_TIMER = 1
69 HOLD_TIMER = 3
70
71 pytestmark = [pytest.mark.pimd]
72
73 TOPOLOGY = """
74
75 Descripton: Configuring static routes on r1/r2/r3/r4/r5 for RP reachablility.
76 IPs are assigned automatically to routers, start IP and subnet is defined in respective JSON file
77 JSON snippet:
78 "link_ip_start": {"ipv4": "10.0.0.0", "v4mask": 24},
79
80 r5 ------- i2
81 10.0.3.2/24| 10.0.0.2/24
82 |
83 10.0.3.1/24|
84 ------------ r4 ----------
85 | 10.0.1.2/24 10.0.2.2/24 |
86 10.0.1.1/24 | | 10.0.2.1/24
87 r1 ----------- s1 ---------- r2
88 10.0.4.2/24 | 10.0.4.3/24
89 |
90 |10.0.4.4/24
91 i1 -------- r3
92 10.0.4.1/24
93 Description:
94 i1, i2 - FRR running iperf to send IGMP
95 join and traffic
96 r1, r2, r3, r4, r5 - FRR ruter
97 s1 - OVS switch
98 """
99
100 # Global variables
101 VLAN_1 = 2501
102 GROUP_RANGE = "225.0.0.0/8"
103 IGMP_JOIN = "225.1.1.1"
104 VLAN_INTF_ADRESS_1 = "10.0.8.3/24"
105 SAME_VLAN_IP_1 = {"ip": "10.1.1.1", "subnet": "255.255.255.0", "cidr": "24"}
106 SAME_VLAN_IP_2 = {"ip": "10.1.1.2", "subnet": "255.255.255.0", "cidr": "24"}
107 SAME_VLAN_IP_3 = {"ip": "10.1.1.3", "subnet": "255.255.255.0", "cidr": "24"}
108 SAME_VLAN_IP_4 = {"ip": "10.1.1.4", "subnet": "255.255.255.0", "cidr": "24"}
109 GROUP_RANGE_1 = [
110 "225.1.1.1/32",
111 "225.1.1.2/32",
112 "225.1.1.3/32",
113 "225.1.1.4/32",
114 "225.1.1.5/32",
115 ]
116 IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
117 GROUP_RANGE_2 = [
118 "226.1.1.1/32",
119 "226.1.1.2/32",
120 "226.1.1.3/32",
121 "226.1.1.4/32",
122 "226.1.1.5/32",
123 ]
124 IGMP_JOIN_RANGE_2 = ["226.1.1.1", "226.1.1.2", "226.1.1.3", "226.1.1.4", "226.1.1.5"]
125 GROUP_RANGE_3 = [
126 "227.1.1.1/32",
127 "227.1.1.2/32",
128 "227.1.1.3/32",
129 "227.1.1.4/32",
130 "227.1.1.5/32",
131 ]
132 IGMP_JOIN_RANGE_3 = ["227.1.1.1", "227.1.1.2", "227.1.1.3", "227.1.1.4", "227.1.1.5"]
133
134 intf_r1_s1 = None
135 intf_r1_s1_addr = None
136 intf_r2_s1 = None
137 intf_r2_s1_addr = None
138 intf_r3_s1 = None
139 intf_r3_s1_addr = None
140 intf_i1_s1 = None
141 intf_i1_s1_addr = None
142
143
144 def setup_module(mod):
145 """
146 Sets up the pytest environment
147
148 * `mod`: module name
149 """
150
151 # Required linux kernel version for this suite to run.
152 result = required_linux_kernel_version("4.19")
153 if result is not True:
154 pytest.skip("Kernel requirements are not met")
155
156 testsuite_run_time = time.asctime(time.localtime(time.time()))
157 logger.info("Testsuite start time: {}".format(testsuite_run_time))
158 logger.info("=" * 40)
159 logger.info("Master Topology: \n {}".format(TOPOLOGY))
160
161 logger.info("Running setup_module to create topology")
162
163 testdir = os.path.dirname(os.path.realpath(__file__))
164 json_file = "{}/pim_dr_nondr_with_static_routes_topo1.json".format(testdir)
165 tgen = Topogen(json_file, mod.__name__)
166 global topo
167 topo = tgen.json_topo
168 # ... and here it calls Mininet initialization functions.
169
170 # Starting topology, create tmp files which are loaded to routers
171 # to start deamons and then start routers
172 start_topology(tgen)
173
174 # Don"t run this test if we have any failure.
175 if tgen.routers_have_failure():
176 pytest.skip(tgen.errors)
177
178 # Creating configuration from JSON
179 build_config_from_json(tgen, tgen.json_topo)
180
181 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
182 global app_helper
183 app_helper = McastTesterHelper(tgen)
184
185 logger.info("Running setup_module() done")
186
187
188 def teardown_module():
189 """Teardown the pytest environment"""
190
191 logger.info("Running teardown_module to delete topology")
192
193 tgen = get_topogen()
194
195 app_helper.cleanup()
196
197 # Stop toplogy and Remove tmp files
198 tgen.stop_topology()
199
200 logger.info(
201 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
202 )
203 logger.info("=" * 40)
204
205
206 #####################################################
207 #
208 # Local APIs
209 #
210 #####################################################
211
212
213 def pre_config_for_receiver_dr_tests(
214 tgen, topo, tc_name, highest_priority, lowest_priority
215 ):
216 """
217 API to do common pre-configuration for receiver test cases
218
219 parameters:
220 -----------
221 * `tgen`: topogen object
222 * `topo`: input json data
223 * `tc_name`: caller test case name
224 * `highest_priority`: router which will be having highest DR priority
225 * `lowest_priority`: router which will be having lowest DR priority
226 """
227
228 global intf_r1_s1, intf_r1_s1_addr, intf_r2_s1, intf_r2_s1_addr, intf_r3_s1, intf_r3_s1_addr, intf_i1_s1, intf_i1_s1_addr
229
230 step("Configure IGMP and PIM on switch connected receiver nodes")
231 step("Configure PIM on all upstream interfaces")
232
233 step("Configure link between R1, R2 ,R3 and receiver on" " same vlan")
234 step(
235 "Make sure {0} is DR initially configuring highest IP on {0} and R2 "
236 "second highest, {1} is lower".format(highest_priority, lowest_priority)
237 )
238
239 intf_r1_s1 = topo["routers"]["r1"]["links"]["s1"]["interface"]
240 intf_r1_s1_addr = topo["routers"]["r1"]["links"]["s1"]["ipv4"]
241
242 intf_r2_s1 = topo["routers"]["r2"]["links"]["s1"]["interface"]
243 intf_r2_s1_addr = topo["routers"]["r2"]["links"]["s1"]["ipv4"]
244
245 intf_r3_s1 = topo["routers"]["r3"]["links"]["s1"]["interface"]
246 intf_r3_s1_addr = topo["routers"]["r3"]["links"]["s1"]["ipv4"]
247
248 intf_i1_s1 = topo["routers"]["i1"]["links"]["s1"]["interface"]
249 intf_i1_s1_addr = topo["routers"]["i1"]["links"]["s1"]["ipv4"]
250
251 if lowest_priority == "r1":
252 lowest_pr_intf = intf_r1_s1
253 else:
254 lowest_pr_intf = intf_r3_s1
255
256 if highest_priority == "r1":
257 highest_pr_intf = intf_r1_s1
258 else:
259 highest_pr_intf = intf_r3_s1
260
261 vlan_input = {
262 lowest_priority: {
263 "vlan": {
264 VLAN_1: [
265 {
266 lowest_pr_intf: {
267 "ip": SAME_VLAN_IP_1["ip"],
268 "subnet": SAME_VLAN_IP_1["subnet"],
269 }
270 }
271 ]
272 }
273 },
274 "r2": {
275 "vlan": {
276 VLAN_1: [
277 {
278 intf_r2_s1: {
279 "ip": SAME_VLAN_IP_2["ip"],
280 "subnet": SAME_VLAN_IP_2["subnet"],
281 }
282 }
283 ]
284 }
285 },
286 highest_priority: {
287 "vlan": {
288 VLAN_1: [
289 {
290 highest_pr_intf: {
291 "ip": SAME_VLAN_IP_3["ip"],
292 "subnet": SAME_VLAN_IP_3["subnet"],
293 }
294 }
295 ]
296 }
297 },
298 "i1": {
299 "vlan": {
300 VLAN_1: [
301 {
302 intf_i1_s1: {
303 "ip": SAME_VLAN_IP_4["ip"],
304 "subnet": SAME_VLAN_IP_4["subnet"],
305 }
306 }
307 ]
308 }
309 },
310 }
311
312 add_interfaces_to_vlan(tgen, vlan_input)
313
314 raw_config = {
315 "r1": {
316 "raw_config": [
317 "interface {}".format(intf_r1_s1),
318 "no ip address {}".format(intf_r1_s1_addr),
319 "no ip pim",
320 ]
321 },
322 "r2": {
323 "raw_config": [
324 "interface {}".format(intf_r2_s1),
325 "no ip address {}".format(intf_r2_s1_addr),
326 "no ip pim",
327 ]
328 },
329 "r3": {
330 "raw_config": [
331 "interface {}".format(intf_r3_s1),
332 "no ip address {}".format(intf_r3_s1_addr),
333 "no ip pim",
334 ]
335 },
336 "i1": {
337 "raw_config": [
338 "interface {}".format(intf_i1_s1),
339 "no ip address {}".format(intf_i1_s1_addr),
340 ]
341 },
342 }
343
344 result = apply_raw_config(tgen, raw_config)
345 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
346
347 raw_config = {
348 lowest_priority: {
349 "raw_config": [
350 "interface {}.{}".format(lowest_pr_intf, VLAN_1),
351 "ip address {}/{}".format(SAME_VLAN_IP_1["ip"], SAME_VLAN_IP_1["cidr"]),
352 "ip pim",
353 "ip igmp",
354 "ip igmp version 2",
355 ]
356 },
357 "r2": {
358 "raw_config": [
359 "interface {}.{}".format(intf_r2_s1, VLAN_1),
360 "ip address {}/{}".format(SAME_VLAN_IP_2["ip"], SAME_VLAN_IP_2["cidr"]),
361 "ip pim",
362 "ip igmp",
363 "ip igmp version 2",
364 ]
365 },
366 highest_priority: {
367 "raw_config": [
368 "interface {}.{}".format(highest_pr_intf, VLAN_1),
369 "ip address {}/{}".format(SAME_VLAN_IP_3["ip"], SAME_VLAN_IP_3["cidr"]),
370 "ip pim",
371 "ip igmp",
372 "ip igmp version 2",
373 ]
374 },
375 "i1": {
376 "raw_config": [
377 "interface {}.{}".format(intf_i1_s1, VLAN_1),
378 "ip address {}/{}".format(SAME_VLAN_IP_4["ip"], SAME_VLAN_IP_4["cidr"]),
379 ]
380 },
381 }
382
383 result = apply_raw_config(tgen, raw_config)
384 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
385
386 for dut, intf in zip(["r1", "r2", "r3"], [intf_r1_s1, intf_r2_s1, intf_r3_s1]):
387 raw_config = {
388 dut: {
389 "raw_config": [
390 "interface {}.{}".format(intf, VLAN_1),
391 "ip pim hello {} {}".format(HELLO_TIMER, HOLD_TIMER),
392 ]
393 }
394 }
395 result = apply_raw_config(tgen, raw_config)
396 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
397
398 step("Configure R4 as RP on all the nodes for group range 224.0.0.0/24")
399
400 input_dict = {
401 "r4": {
402 "pim": {
403 "rp": [
404 {
405 "rp_addr": topo["routers"]["r4"]["links"]["lo"]["ipv4"].split(
406 "/"
407 )[0],
408 "group_addr_range": GROUP_RANGE_1,
409 }
410 ]
411 }
412 }
413 }
414
415 result = create_pim_config(tgen, topo, input_dict)
416 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
417
418 step("Send IGMP join for groups 226.1.1.1 to 226.1.1.5")
419
420 vlan_intf_i1_s1 = "{}.{}".format(intf_i1_s1, VLAN_1)
421 result = app_helper.run_join("i1", IGMP_JOIN_RANGE_1, join_intf=vlan_intf_i1_s1)
422 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
423
424 step("Using static routes instead OSPF: Enable OSPF between all the nodes")
425
426 step("Start traffic from R4 connected source")
427
428 result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "r5")
429 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
430
431 return True
432
433
434 def pre_config_for_source_dr_tests(
435 tgen, topo, tc_name, highest_priority, lowest_priority
436 ):
437 """
438 API to do common pre-configuration for source test cases
439
440 parameters:
441 -----------
442 * `tgen`: topogen object
443 * `topo`: input json data
444 * `tc_name`: caller test case name
445 * `highest_priority`: router which will be having highest DR priority
446 * `lowest_priority`: router which will be having lowest DR priority
447 """
448
449 global intf_r1_s1, intf_r1_s1_addr, intf_r2_s1, intf_r2_s1_addr, intf_r3_s1, intf_r3_s1_addr, intf_i1_s1, intf_i1_s1_addr
450
451 step("Configure IGMP and PIM on switch connected receiver nodes")
452 step("Configure PIM on all upstream interfaces")
453
454 step("Configure link between R1, R2 ,R3 and receiver on" " same vlan")
455 step(
456 "Make sure {0} is DR initially configuring highest IP on {0} and R2 "
457 "second highest, {1} is lower".format(highest_priority, lowest_priority)
458 )
459
460 intf_r1_s1 = topo["routers"]["r1"]["links"]["s1"]["interface"]
461 intf_r1_s1_addr = topo["routers"]["r1"]["links"]["s1"]["ipv4"]
462
463 intf_r2_s1 = topo["routers"]["r2"]["links"]["s1"]["interface"]
464 intf_r2_s1_addr = topo["routers"]["r2"]["links"]["s1"]["ipv4"]
465
466 intf_r3_s1 = topo["routers"]["r3"]["links"]["s1"]["interface"]
467 intf_r3_s1_addr = topo["routers"]["r3"]["links"]["s1"]["ipv4"]
468
469 intf_i1_s1 = topo["routers"]["i1"]["links"]["s1"]["interface"]
470 intf_i1_s1_addr = topo["routers"]["i1"]["links"]["s1"]["ipv4"]
471
472 if lowest_priority == "r1":
473 lowest_pr_intf = intf_r1_s1
474 else:
475 lowest_pr_intf = intf_r3_s1
476
477 if highest_priority == "r1":
478 highest_pr_intf = intf_r1_s1
479 else:
480 highest_pr_intf = intf_r3_s1
481
482 vlan_input = {
483 lowest_priority: {
484 "vlan": {
485 VLAN_1: [
486 {
487 lowest_pr_intf: {
488 "ip": SAME_VLAN_IP_1["ip"],
489 "subnet": SAME_VLAN_IP_1["subnet"],
490 }
491 }
492 ]
493 }
494 },
495 "r2": {
496 "vlan": {
497 VLAN_1: [
498 {
499 intf_r2_s1: {
500 "ip": SAME_VLAN_IP_2["ip"],
501 "subnet": SAME_VLAN_IP_2["subnet"],
502 }
503 }
504 ]
505 }
506 },
507 highest_priority: {
508 "vlan": {
509 VLAN_1: [
510 {
511 highest_pr_intf: {
512 "ip": SAME_VLAN_IP_3["ip"],
513 "subnet": SAME_VLAN_IP_3["subnet"],
514 }
515 }
516 ]
517 }
518 },
519 "i1": {
520 "vlan": {
521 VLAN_1: [
522 {
523 intf_i1_s1: {
524 "ip": SAME_VLAN_IP_4["ip"],
525 "subnet": SAME_VLAN_IP_4["subnet"],
526 }
527 }
528 ]
529 }
530 },
531 }
532
533 add_interfaces_to_vlan(tgen, vlan_input)
534
535 raw_config = {
536 "r1": {
537 "raw_config": [
538 "interface {}".format(intf_r1_s1),
539 "no ip address {}".format(intf_r1_s1_addr),
540 "no ip pim",
541 ]
542 },
543 "r2": {
544 "raw_config": [
545 "interface {}".format(intf_r2_s1),
546 "no ip address {}".format(intf_r2_s1_addr),
547 "no ip pim",
548 ]
549 },
550 "r3": {
551 "raw_config": [
552 "interface {}".format(intf_r3_s1),
553 "no ip address {}".format(intf_r3_s1_addr),
554 "no ip pim",
555 ]
556 },
557 "i1": {
558 "raw_config": [
559 "interface {}".format(intf_i1_s1),
560 "no ip address {}".format(intf_i1_s1_addr),
561 ]
562 },
563 }
564
565 result = apply_raw_config(tgen, raw_config)
566 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
567
568 step(
569 "Configure IGMP and PIM on switch connected receiver nodes , "
570 "configure PIM nbr with hello timer 1"
571 )
572
573 raw_config = {
574 lowest_priority: {
575 "raw_config": [
576 "interface {}.{}".format(lowest_pr_intf, VLAN_1),
577 "ip address {}/{}".format(SAME_VLAN_IP_1["ip"], SAME_VLAN_IP_1["cidr"]),
578 "ip pim",
579 ]
580 },
581 "r2": {
582 "raw_config": [
583 "interface {}.{}".format(intf_r2_s1, VLAN_1),
584 "ip address {}/{}".format(SAME_VLAN_IP_2["ip"], SAME_VLAN_IP_2["cidr"]),
585 "ip pim",
586 ]
587 },
588 highest_priority: {
589 "raw_config": [
590 "interface {}.{}".format(highest_pr_intf, VLAN_1),
591 "ip address {}/{}".format(SAME_VLAN_IP_3["ip"], SAME_VLAN_IP_3["cidr"]),
592 "ip pim",
593 ]
594 },
595 "i1": {
596 "raw_config": [
597 "interface {}.{}".format(intf_i1_s1, VLAN_1),
598 "ip address {}/{}".format(SAME_VLAN_IP_4["ip"], SAME_VLAN_IP_4["cidr"]),
599 ]
600 },
601 }
602
603 result = apply_raw_config(tgen, raw_config)
604 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
605
606 for dut, intf in zip(["r1", "r2", "r3"], [intf_r1_s1, intf_r2_s1, intf_r3_s1]):
607 raw_config = {
608 dut: {
609 "raw_config": [
610 "interface {}.{}".format(intf, VLAN_1),
611 "ip pim hello {} {}".format(HELLO_TIMER, HOLD_TIMER),
612 ]
613 }
614 }
615 result = apply_raw_config(tgen, raw_config)
616 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
617
618 step("Configure R4 as RP on all the nodes for group range 224.0.0.0/24")
619
620 input_dict = {
621 "r4": {
622 "pim": {
623 "rp": [
624 {
625 "rp_addr": topo["routers"]["r4"]["links"]["lo"]["ipv4"].split(
626 "/"
627 )[0],
628 "group_addr_range": GROUP_RANGE_1,
629 }
630 ]
631 }
632 }
633 }
634
635 result = create_pim_config(tgen, topo, input_dict)
636 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
637
638 step("Configure IGMP on R5 port and send IGMP join for groups " "(226.1.1.1-5)")
639
640 intf_r5_i2 = topo["routers"]["r5"]["links"]["i2"]["interface"]
641 input_dict = {
642 "r5": {"igmp": {"interfaces": {intf_r5_i2: {"igmp": {"version": "2"}}}}}
643 }
644 result = create_igmp_config(tgen, topo, input_dict)
645 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
646
647 input_src = {"i2": topo["routers"]["i2"]["links"]["r5"]["interface"]}
648
649 result = app_helper.run_join("i2", IGMP_JOIN_RANGE_1, "r5")
650 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
651
652 step("Using static routes instead OSPF: Enable OSPF between all the nodes")
653
654 step("Start traffic from Source node")
655
656 vlan_intf_i1_s1 = "{}.{}".format(intf_i1_s1, VLAN_1)
657 result = app_helper.run_traffic("i1", IGMP_JOIN_RANGE_1, bind_intf=vlan_intf_i1_s1)
658 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
659
660 return True
661
662
663 #####################################################
664 #
665 # Testcases
666 #
667 #####################################################
668
669
670 def test_pim_source_dr_functionality_while_rebooting_dr_non_dr_nodes_p1(request):
671 """
672 Verify mroute while rebooting DR /Non DR nodes( r1, r2 , r3 on all the nodes)
673 """
674
675 tgen = get_topogen()
676 tc_name = request.node.name
677 write_test_header(tc_name)
678
679 # Creating configuration from JSON
680 app_helper.stop_all_hosts()
681 clear_mroute(tgen)
682 check_router_status(tgen)
683 reset_config_on_routers(tgen)
684 clear_pim_interface_traffic(tgen, topo)
685
686 # Don"t run this test if we have any failure.
687 if tgen.routers_have_failure():
688 pytest.skip(tgen.errors)
689
690 result = pre_config_for_source_dr_tests(tgen, topo, tc_name, "r1", "r3")
691 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
692
693 step("R1 is the DR , verify using 'show ip pim interface json'")
694
695 vlan_intf_r1_s1 = "{}.{}".format(intf_r1_s1, VLAN_1)
696 input_dict_dr = {
697 "r1": {
698 "pim": {
699 "interfaces": {vlan_intf_r1_s1: {"drAddress": SAME_VLAN_IP_3["ip"]}}
700 }
701 }
702 }
703 result = verify_pim_config(tgen, input_dict_dr)
704 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
705
706 step(
707 "R2 is transit router for I1 to reach R4, mroute should have (s, g) mroute with "
708 "OIL towards R4, using 'show ip mroute json'"
709 )
710 step(
711 "R2 (s, g) upstream should be in join state verify using "
712 "'show ip pim upstream json'"
713 )
714 step(
715 "R1 has (S, G) mroute with NONE OIL and upstream as not joined, verify using "
716 "'show ip mroute json' 'show ip pim upstream json'"
717 )
718
719 source_i1 = SAME_VLAN_IP_4["ip"]
720 input_dict_r1_r2 = [
721 {
722 "dut": "r1",
723 "src_address": source_i1,
724 "oil": "none",
725 "iif": "{}.{}".format(
726 topo["routers"]["r1"]["links"]["s1"]["interface"], VLAN_1
727 ),
728 },
729 {
730 "dut": "r2",
731 "src_address": source_i1,
732 "oil": topo["routers"]["r2"]["links"]["r4"]["interface"],
733 "iif": "{}.{}".format(
734 topo["routers"]["r2"]["links"]["s1"]["interface"], VLAN_1
735 ),
736 },
737 ]
738
739 for data in input_dict_r1_r2:
740 result = verify_mroutes(
741 tgen,
742 data["dut"],
743 data["src_address"],
744 IGMP_JOIN_RANGE_1,
745 data["iif"],
746 data["oil"],
747 )
748 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
749
750 if data["dut"] == "r2":
751 result = verify_upstream_iif(
752 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
753 )
754 assert result is True, "Testcase {} : Failed Error: {}".format(
755 tc_name, result
756 )
757 else:
758 result = verify_upstream_iif(
759 tgen,
760 data["dut"],
761 data["iif"],
762 data["src_address"],
763 IGMP_JOIN_RANGE_1,
764 expected=False,
765 )
766 assert result is not True, (
767 "Testcase {} : Failed \n "
768 "Upstream is still joined state \n Error: {}".format(tc_name, result)
769 )
770
771 step("Reboot R3 node")
772 stop_router(tgen, "r3")
773
774 step(
775 "After reboot of R3 verify R1 continues to be DR, using 'show ip pim interface json'"
776 )
777
778 result = verify_pim_config(tgen, input_dict_dr)
779 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
780
781 step("R3 should not have any mroute and upstream")
782 step("R2 has mroute with OIL towards R4 /R1 , verify using 'show ip mroute'")
783 step(
784 "R2 has upstream with Join RejP state verify using 'show ip pim upstream json'"
785 )
786 step("R1 has mroute with none OIL and upstream with Not Join")
787
788 for data in input_dict_r1_r2:
789 result = verify_mroutes(
790 tgen,
791 data["dut"],
792 data["src_address"],
793 IGMP_JOIN_RANGE_1,
794 data["iif"],
795 data["oil"],
796 )
797 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
798
799 if data["dut"] == "r2":
800 result = verify_upstream_iif(
801 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
802 )
803 assert result is True, "Testcase {} : Failed Error: {}".format(
804 tc_name, result
805 )
806 else:
807 result = verify_upstream_iif(
808 tgen,
809 data["dut"],
810 data["iif"],
811 data["src_address"],
812 IGMP_JOIN_RANGE_1,
813 expected=False,
814 )
815 assert result is not True, (
816 "Testcase {} : Failed \n "
817 "Upstream is still joined state \n Error: {}".format(tc_name, result)
818 )
819
820 step("Reboot R2 node")
821 stop_router(tgen, "r2")
822
823 step(
824 "After reboot of R2, R1 continues to be DR verify using 'show ip pim interface json'"
825 )
826
827 result = verify_pim_config(tgen, input_dict_dr)
828 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
829
830 step(
831 "R3 and R2 should not have any mroute and upstream , verify using "
832 "'show ip mroute json' 'show ip pim upstream json'"
833 )
834 step("R1 has mroute created with empty OIL, using 'show ip mroute json'")
835 step(
836 "R1 has upstream with Not Join, Rej Prune , verify using 'show ip pim upstream json'"
837 )
838
839 for data in input_dict_r1_r2:
840 if data["dut"] == "r1":
841 result = verify_mroutes(
842 tgen,
843 data["dut"],
844 data["src_address"],
845 IGMP_JOIN_RANGE_1,
846 data["iif"],
847 data["oil"],
848 )
849 assert result is True, "Testcase {} : Failed Error: {}".format(
850 tc_name, result
851 )
852
853 result = verify_upstream_iif(
854 tgen,
855 data["dut"],
856 data["iif"],
857 data["src_address"],
858 IGMP_JOIN_RANGE_1,
859 expected=False,
860 )
861 assert result is not True, (
862 "Testcase {} : Failed \n "
863 "Upstream is still joined state \n Error: {}".format(tc_name, result)
864 )
865
866 step("Reboot R1 node using FRR stop")
867 stop_router(tgen, "r1")
868
869 step(
870 "After stop of all the routers, verify upstream and mroutes should "
871 "not present in any of them"
872 )
873
874 for data in input_dict_r1_r2:
875 result = verify_mroutes(
876 tgen,
877 data["dut"],
878 data["src_address"],
879 IGMP_JOIN_RANGE_1,
880 data["iif"],
881 data["oil"],
882 expected=False,
883 )
884 assert (
885 result is not True
886 ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format(
887 tc_name, result
888 )
889
890 step("start FRR for all the nodes")
891 start_router(tgen, "r1")
892 start_router(tgen, "r2")
893 start_router(tgen, "r3")
894
895 step("After start of all the routers, R1 became DR")
896
897 result = verify_pim_config(tgen, input_dict_dr)
898 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
899
900 for data in input_dict_r1_r2:
901 result = verify_mroutes(
902 tgen,
903 data["dut"],
904 data["src_address"],
905 IGMP_JOIN_RANGE_1,
906 data["iif"],
907 data["oil"],
908 )
909 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
910
911 if data["dut"] == "r2":
912 result = verify_upstream_iif(
913 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
914 )
915 assert result is True, "Testcase {} : Failed Error: {}".format(
916 tc_name, result
917 )
918
919 write_test_footer(tc_name)
920
921
922 if __name__ == "__main__":
923 args = ["-s"] + sys.argv[1:]
924 sys.exit(pytest.main(args))