]> git.proxmox.com Git - mirror_frr.git/blame - 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
CommitLineData
40c28c86 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
40c28c86 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#
40c28c86 9
10"""
11Following tests are covered to test multicast pim sm:
12
13Test steps
14- Create topology (setup module)
15- Bring up topology
16
17Following tests are covered:
181. Verify mroute while rebooting DR /Non DR nodes( r1, r2 , r3 on all the nodes)
19"""
20
21import os
22import sys
23import json
24import time
25import datetime
26from time import sleep
27import pytest
28
29# Save the Current Working Directory to find configuration files.
30CWD = os.path.dirname(os.path.realpath(__file__))
31sys.path.append(os.path.join(CWD, "../"))
32sys.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
38from lib.topogen import Topogen, get_topogen
39
40from 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)
54from lib.pim import (
55 create_pim_config,
56 create_igmp_config,
4fafd29f
KK
57 verify_mroutes,
58 clear_mroute,
59 clear_pim_interface_traffic,
40c28c86 60 verify_pim_config,
61 verify_upstream_iif,
62 verify_multicast_flag_state,
63 McastTesterHelper,
64)
65from lib.topolog import logger
66from lib.topojson import build_config_from_json
67
68HELLO_TIMER = 1
69HOLD_TIMER = 3
70
71pytestmark = [pytest.mark.pimd]
72
73TOPOLOGY = """
74
75Descripton: Configuring static routes on r1/r2/r3/r4/r5 for RP reachablility.
76IPs are assigned automatically to routers, start IP and subnet is defined in respective JSON file
77JSON 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
101VLAN_1 = 2501
102GROUP_RANGE = "225.0.0.0/8"
103IGMP_JOIN = "225.1.1.1"
104VLAN_INTF_ADRESS_1 = "10.0.8.3/24"
105SAME_VLAN_IP_1 = {"ip": "10.1.1.1", "subnet": "255.255.255.0", "cidr": "24"}
106SAME_VLAN_IP_2 = {"ip": "10.1.1.2", "subnet": "255.255.255.0", "cidr": "24"}
107SAME_VLAN_IP_3 = {"ip": "10.1.1.3", "subnet": "255.255.255.0", "cidr": "24"}
108SAME_VLAN_IP_4 = {"ip": "10.1.1.4", "subnet": "255.255.255.0", "cidr": "24"}
109GROUP_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]
116IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
117GROUP_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]
124IGMP_JOIN_RANGE_2 = ["226.1.1.1", "226.1.1.2", "226.1.1.3", "226.1.1.4", "226.1.1.5"]
125GROUP_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]
132IGMP_JOIN_RANGE_3 = ["227.1.1.1", "227.1.1.2", "227.1.1.3", "227.1.1.4", "227.1.1.5"]
133
134intf_r1_s1 = None
135intf_r1_s1_addr = None
136intf_r2_s1 = None
137intf_r2_s1_addr = None
138intf_r3_s1 = None
139intf_r3_s1_addr = None
140intf_i1_s1 = None
141intf_i1_s1_addr = None
142
143
144def 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
40c28c86 170 # Starting topology, create tmp files which are loaded to routers
171 # to start deamons and then start routers
991a971f 172 start_topology(tgen)
40c28c86 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
188def 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
4fafd29f 205
40c28c86 206#####################################################
207#
208# Local APIs
209#
210#####################################################
211
212
213def 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
434def 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
670def 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()
4fafd29f 681 clear_mroute(tgen)
40c28c86 682 check_router_status(tgen)
683 reset_config_on_routers(tgen)
4fafd29f 684 clear_pim_interface_traffic(tgen, topo)
40c28c86 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(
b2e37a56 707 "R2 is transit router for I1 to reach R4, mroute should have (s, g) mroute with "
40c28c86 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:
4fafd29f 740 result = verify_mroutes(
40c28c86 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
b2e37a56
DS
774 step(
775 "After reboot of R3 verify R1 continues to be DR, using 'show ip pim interface json'"
776 )
40c28c86 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:
4fafd29f 789 result = verify_mroutes(
40c28c86 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
b2e37a56
DS
823 step(
824 "After reboot of R2, R1 continues to be DR verify using 'show ip pim interface json'"
825 )
40c28c86 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 )
b2e37a56 834 step("R1 has mroute created with empty OIL, using 'show ip mroute json'")
40c28c86 835 step(
b2e37a56 836 "R1 has upstream with Not Join, Rej Prune , verify using 'show ip pim upstream json'"
40c28c86 837 )
838
839 for data in input_dict_r1_r2:
840 if data["dut"] == "r1":
4fafd29f 841 result = verify_mroutes(
40c28c86 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:
4fafd29f 875 result = verify_mroutes(
40c28c86 876 tgen,
877 data["dut"],
878 data["src_address"],
879 IGMP_JOIN_RANGE_1,
880 data["iif"],
881 data["oil"],
882 expected=False,
883 )
4fafd29f
KK
884 assert (
885 result is not True
886 ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format(
887 tc_name, result
40c28c86 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:
4fafd29f 901 result = verify_mroutes(
40c28c86 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
922if __name__ == "__main__":
923 args = ["-s"] + sys.argv[1:]
924 sys.exit(pytest.main(args))