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