]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_uplink_topo1/test_multicast_pim_uplink_topo1.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / tests / topotests / multicast_pim_uplink_topo1 / test_multicast_pim_uplink_topo1.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2022 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation,
6 # Inc. ("NetDEF") in this file.
7 #
8 # Permission to use, copy, modify, and/or distribute this software
9 # for any purpose with or without fee is hereby granted, provided
10 # that the above copyright notice and this permission notice appear
11 # in all copies.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 # OF THIS SOFTWARE.
21 #
22
23 """
24 Following tests are covered to test multicast pim uplink:
25
26 1. Verify mroutes OIL and IIF updated correctly when receivers present inside
27 and outside of DUT
28 2. Verify mroutes OIL and IIF updated correctly when source present inside
29 and outside of DUT
30 3. Verify Mroutes and BSM forwarding when edge is transit node
31 4. Verify mroutes updated correctly after source interface shut/no shut
32 5. Verify mroutes updated correctly after receiver interface shut/no shut
33 6. Verify mroute updated correctly after sending IGMP prune and join
34 7. Verify mroute updated correctly after clear mroute
35 8. Verify (*,G) mroute entries after changing the RP configuration
36 9. Verify mroute entries after FRR service stop and start
37 """
38
39 import os
40 import sys
41 import json
42 import time
43 import pytest
44
45 # Save the Current Working Directory to find configuration files.
46 CWD = os.path.dirname(os.path.realpath(__file__))
47 sys.path.append(os.path.join(CWD, "../"))
48 sys.path.append(os.path.join(CWD, "../lib/"))
49
50 # Required to instantiate the topology builder class.
51
52 # pylint: disable=C0413
53 # Import topogen and topotest helpers
54 from lib.topogen import Topogen, get_topogen
55
56 from lib.common_config import (
57 start_topology,
58 write_test_header,
59 write_test_footer,
60 step,
61 reset_config_on_routers,
62 shutdown_bringup_interface,
63 start_router,
64 stop_router,
65 create_static_routes,
66 required_linux_kernel_version,
67 )
68 from lib.bgp import create_router_bgp
69 from lib.pim import (
70 create_pim_config,
71 create_igmp_config,
72 verify_igmp_groups,
73 verify_mroutes,
74 clear_pim_interface_traffic,
75 verify_upstream_iif,
76 clear_mroute,
77 verify_multicast_traffic,
78 verify_pim_rp_info,
79 verify_pim_interface_traffic,
80 verify_pim_state,
81 McastTesterHelper,
82 )
83 from lib.topolog import logger
84 from lib.topojson import build_config_from_json
85
86 # Global variables
87 GROUP_RANGE_1 = [
88 "225.1.1.1/32",
89 "225.1.1.2/32",
90 "225.1.1.3/32",
91 "225.1.1.4/32",
92 "225.1.1.5/32",
93 ]
94 IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
95 GROUP_RANGE_2 = [
96 "226.1.1.1/32",
97 "226.1.1.2/32",
98 "226.1.1.3/32",
99 "226.1.1.4/32",
100 "226.1.1.5/32",
101 ]
102 IGMP_JOIN_RANGE_2 = ["226.1.1.1", "226.1.1.2", "226.1.1.3", "226.1.1.4", "226.1.1.5"]
103 GROUP_RANGE_3 = [
104 "227.1.1.1/32",
105 "227.1.1.2/32",
106 "227.1.1.3/32",
107 "227.1.1.4/32",
108 "227.1.1.5/32",
109 ]
110 IGMP_JOIN_RANGE_3 = ["227.1.1.1", "227.1.1.2", "227.1.1.3", "227.1.1.4", "227.1.1.5"]
111
112 r1_r2_links = []
113 r1_r3_links = []
114 r2_r1_links = []
115 r3_r1_links = []
116 r2_r4_links = []
117 r4_r2_links = []
118 r4_r3_links = []
119 HELLO_TIMER = 1
120 HOLD_TIMER = 3
121
122 pytestmark = [pytest.mark.pimd]
123
124
125 def setup_module(mod):
126 """
127 Sets up the pytest environment
128
129 * `mod`: module name
130 """
131
132 # Required linux kernel version for this suite to run.
133 result = required_linux_kernel_version("4.19")
134 if result is not True:
135 pytest.skip("Kernel requirements are not met")
136
137 testsuite_run_time = time.asctime(time.localtime(time.time()))
138 logger.info("Testsuite start time: {}".format(testsuite_run_time))
139 logger.info("=" * 40)
140
141 logger.info("Running setup_module to create topology")
142
143 testdir = os.path.dirname(os.path.realpath(__file__))
144 json_file = "{}/multicast_pim_uplink_topo1.json".format(testdir)
145 tgen = Topogen(json_file, mod.__name__)
146 global topo
147 topo = tgen.json_topo
148 # ... and here it calls Mininet initialization functions.
149
150 # Starting topology, create tmp files which are loaded to routers
151 # to start deamons and then start routers
152 start_topology(tgen)
153
154 # Don"t run this test if we have any failure.
155 if tgen.routers_have_failure():
156 pytest.skip(tgen.errors)
157
158 # Creating configuration from JSON
159 build_config_from_json(tgen, tgen.json_topo)
160
161 # Pre-requisite data
162 get_interfaces_names(topo)
163
164 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
165 global app_helper
166 app_helper = McastTesterHelper(tgen)
167
168 logger.info("Running setup_module() done")
169
170
171 def teardown_module():
172 """Teardown the pytest environment"""
173
174 logger.info("Running teardown_module to delete topology")
175
176 tgen = get_topogen()
177
178 app_helper.cleanup()
179
180 # Stop toplogy and Remove tmp files
181 tgen.stop_topology()
182
183 logger.info(
184 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
185 )
186 logger.info("=" * 40)
187
188
189 #####################################################
190 #
191 # Local APIs
192 #
193 #####################################################
194
195
196 def get_interfaces_names(topo):
197 """
198 API to fetch interfaces names and create list, which further would be used
199 for verification
200
201 Parameters
202 ----------
203 * `topo` : inout JSON data
204 """
205
206 for link in range(1, 5):
207
208 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(link)]["interface"]
209 r1_r2_links.append(intf)
210
211 intf = topo["routers"]["r1"]["links"]["r3-link{}".format(link)]["interface"]
212 r1_r3_links.append(intf)
213
214 intf = topo["routers"]["r2"]["links"]["r1-link{}".format(link)]["interface"]
215 r2_r1_links.append(intf)
216
217 intf = topo["routers"]["r3"]["links"]["r1-link{}".format(link)]["interface"]
218 r3_r1_links.append(intf)
219
220 intf = topo["routers"]["r2"]["links"]["r4-link{}".format(link)]["interface"]
221 r2_r4_links.append(intf)
222
223 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(link)]["interface"]
224 r4_r2_links.append(intf)
225
226 intf = topo["routers"]["r4"]["links"]["r3-link{}".format(link)]["interface"]
227 r4_r3_links.append(intf)
228
229
230 def configure_static_routes_for_rp_reachability(tgen, topo):
231 """
232 API to configure static routes for rp reachability
233
234 Parameters
235 ----------
236 * `topo` : inout JSON data
237 """
238
239 for i in range(1, 5):
240 static_routes = {
241 "r1": {
242 "static_routes": [
243 {
244 "network": [
245 topo["routers"]["r2"]["links"]["lo"]["ipv4"],
246 topo["routers"]["i6"]["links"]["r4"]["ipv4"],
247 topo["routers"]["i7"]["links"]["r4"]["ipv4"],
248 topo["routers"]["r4"]["links"]["lo"]["ipv4"],
249 ],
250 "next_hop": topo["routers"]["r2"]["links"][
251 "r1-link{}".format(i)
252 ]["ipv4"].split("/")[0],
253 },
254 {
255 "network": [
256 topo["routers"]["r3"]["links"]["lo"]["ipv4"],
257 topo["routers"]["i6"]["links"]["r4"]["ipv4"],
258 topo["routers"]["i7"]["links"]["r4"]["ipv4"],
259 topo["routers"]["r4"]["links"]["lo"]["ipv4"],
260 ],
261 "next_hop": topo["routers"]["r3"]["links"][
262 "r1-link{}".format(i)
263 ]["ipv4"].split("/")[0],
264 },
265 ]
266 },
267 "r2": {
268 "static_routes": [
269 {
270 "network": [
271 topo["routers"]["i6"]["links"]["r4"]["ipv4"],
272 topo["routers"]["i7"]["links"]["r4"]["ipv4"],
273 topo["routers"]["r4"]["links"]["lo"]["ipv4"],
274 topo["routers"]["r3"]["links"]["lo"]["ipv4"],
275 ],
276 "next_hop": topo["routers"]["r4"]["links"][
277 "r2-link{}".format(i)
278 ]["ipv4"].split("/")[0],
279 },
280 {
281 "network": [
282 topo["routers"]["r1"]["links"]["lo"]["ipv4"],
283 topo["routers"]["r3"]["links"]["lo"]["ipv4"],
284 topo["routers"]["i1"]["links"]["r1"]["ipv4"],
285 topo["routers"]["i2"]["links"]["r1"]["ipv4"],
286 ],
287 "next_hop": topo["routers"]["r1"]["links"][
288 "r2-link{}".format(i)
289 ]["ipv4"].split("/")[0],
290 },
291 ]
292 },
293 "r3": {
294 "static_routes": [
295 {
296 "network": [
297 topo["routers"]["r4"]["links"]["lo"]["ipv4"],
298 topo["routers"]["i6"]["links"]["r4"]["ipv4"],
299 topo["routers"]["i7"]["links"]["r4"]["ipv4"],
300 topo["routers"]["r2"]["links"]["lo"]["ipv4"],
301 ],
302 "next_hop": topo["routers"]["r4"]["links"][
303 "r3-link{}".format(i)
304 ]["ipv4"].split("/")[0],
305 },
306 {
307 "network": [
308 topo["routers"]["r1"]["links"]["lo"]["ipv4"],
309 topo["routers"]["i1"]["links"]["r1"]["ipv4"],
310 topo["routers"]["i2"]["links"]["r1"]["ipv4"],
311 topo["routers"]["r2"]["links"]["lo"]["ipv4"],
312 ],
313 "next_hop": topo["routers"]["r1"]["links"][
314 "r3-link{}".format(i)
315 ]["ipv4"].split("/")[0],
316 },
317 ]
318 },
319 "r4": {
320 "static_routes": [
321 {
322 "network": [
323 topo["routers"]["r3"]["links"]["lo"]["ipv4"],
324 topo["routers"]["i1"]["links"]["r1"]["ipv4"],
325 topo["routers"]["i2"]["links"]["r1"]["ipv4"],
326 topo["routers"]["r1"]["links"]["lo"]["ipv4"],
327 ],
328 "next_hop": topo["routers"]["r3"]["links"][
329 "r4-link{}".format(i)
330 ]["ipv4"].split("/")[0],
331 },
332 {
333 "network": [
334 topo["routers"]["r2"]["links"]["lo"]["ipv4"],
335 topo["routers"]["i1"]["links"]["r1"]["ipv4"],
336 topo["routers"]["i2"]["links"]["r1"]["ipv4"],
337 topo["routers"]["r1"]["links"]["lo"]["ipv4"],
338 ],
339 "next_hop": topo["routers"]["r2"]["links"][
340 "r4-link{}".format(i)
341 ]["ipv4"].split("/")[0],
342 },
343 ]
344 },
345 }
346
347 result = create_static_routes(tgen, static_routes)
348 assert result is True, "API {} : Failed Error: {}".format(
349 sys._getframe().f_code.co_name, result
350 )
351
352
353 def verify_state_incremented(state_before, state_after):
354 """
355 API to compare interface traffic state incrementing
356
357 Parameters
358 ----------
359 * `state_before` : State dictionary for any particular instance
360 * `state_after` : State dictionary for any particular instance
361 """
362
363 for router, state_data in state_before.items():
364 for state, value in state_data.items():
365 if state_before[router][state] > state_after[router][state]:
366 errormsg = (
367 "[DUT: %s]: state %s value has not"
368 " incremented, Initial value: %s, "
369 "Current value: %s [FAILED!!]"
370 % (
371 router,
372 state,
373 state_before[router][state],
374 state_after[router][state],
375 )
376 )
377 return errormsg
378
379 logger.info(
380 "[DUT: %s]: State %s value is "
381 "incremented, Initial value: %s, Current value: %s"
382 " [PASSED!!]",
383 router,
384 state,
385 state_before[router][state],
386 state_after[router][state],
387 )
388
389 return True
390
391
392 #####################################################
393 #
394 # Testcases
395 #
396 #####################################################
397
398
399 def test_mroutes_updated_with_correct_oil_iif_when_receiver_is_in_and_outside_DUT_p0(
400 request,
401 ):
402 """
403 Verify mroutes OIL and IIF updated correctly when receivers present inside
404 and outside of DUT
405 """
406
407 tgen = get_topogen()
408 tc_name = request.node.name
409 write_test_header(tc_name)
410
411 # Creating configuration from JSON
412 app_helper.stop_all_hosts()
413 clear_mroute(tgen)
414 reset_config_on_routers(tgen)
415 clear_pim_interface_traffic(tgen, topo)
416
417 # Don"t run this test if we have any failure.
418 if tgen.routers_have_failure():
419 pytest.skip(tgen.errors)
420
421 step("Enable IGMP on DUT and R4 interface")
422 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
423 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
424 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
425 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
426
427 result = create_igmp_config(tgen, topo, input_dict)
428 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
429
430 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
431 input_join = {
432 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
433 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
434 }
435
436 for recvr, recvr_intf in input_join.items():
437 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
438 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
439
440 step("Configure RP as R2 for group range 225.1.1.1-5")
441
442 input_dict = {
443 "r2": {
444 "pim": {
445 "rp": [
446 {
447 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
448 "/"
449 )[0],
450 "group_addr_range": GROUP_RANGE_1,
451 }
452 ]
453 }
454 }
455 }
456
457 result = create_pim_config(tgen, topo, input_dict)
458 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
459
460 step("Done in base config: " "Configure EBGP peering between all the nodes")
461
462 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
463
464 step("Send traffic from R4 for group range 225.1.1.1-5")
465
466 input_src = {"i6": topo["routers"]["i6"]["links"]["r4"]["interface"]}
467
468 result = app_helper.run_traffic("i6", IGMP_JOIN_RANGE_1, "r4")
469 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
470
471 step(
472 "IGMP groups are received on DUT and R4 verify using 'show ip igmp groups'"
473 " and 'show ip igmp groups json'"
474 )
475
476 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
477 result = verify_igmp_groups(tgen, "r1", intf_r1_i1, IGMP_JOIN_RANGE_1)
478 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
479
480 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
481 result = verify_igmp_groups(tgen, "r4", intf_r4_i7, IGMP_JOIN_RANGE_1)
482 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
483
484 step("(*,G) IIF and OIL updated on both the nodes")
485
486 step(
487 "(S,G) IIF updated towards shortest path to source on both the nodes "
488 ", verify using 'show ip mroute' and 'show ip mroute json'"
489 )
490
491 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
492 input_dict_star_sg = [
493 {
494 "dut": "r1",
495 "src_address": "*",
496 "iif": r1_r2_links + r1_r3_links,
497 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
498 },
499 {
500 "dut": "r4",
501 "src_address": "*",
502 "iif": r4_r2_links + r4_r3_links,
503 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
504 },
505 {
506 "dut": "r1",
507 "src_address": source_i6,
508 "iif": r1_r2_links + r1_r3_links,
509 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
510 },
511 {
512 "dut": "r4",
513 "src_address": source_i6,
514 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
515 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
516 },
517 ]
518
519 for data in input_dict_star_sg:
520 result = verify_mroutes(
521 tgen,
522 data["dut"],
523 data["src_address"],
524 IGMP_JOIN_RANGE_1,
525 data["iif"],
526 data["oil"],
527 )
528 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
529
530 step(
531 "OIL is updated and traffic is received for all the groups on both "
532 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
533 )
534
535 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
536 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
537 input_traffic = {
538 "r1": {"traffic_sent": [intf_r1_i1]},
539 "r4": {"traffic_received": [intf_r4_i6]},
540 }
541 result = verify_multicast_traffic(tgen, input_traffic)
542 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
543
544 step("Random shut of upstream interface from DUT side")
545 for i in range(1, 5, 2):
546 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
547 shutdown_bringup_interface(tgen, "r1", intf, False)
548
549 step(
550 "After shut of upstream interface from DUT verify mroutes has moved "
551 "to another interface (R2 or R3) and updated with correct OIL/IIF using"
552 " 'show ip mroute json'"
553 )
554
555 for data in input_dict_star_sg:
556 if data["src_address"] == "*":
557 result = verify_mroutes(
558 tgen,
559 data["dut"],
560 data["src_address"],
561 IGMP_JOIN_RANGE_1,
562 data["iif"],
563 data["oil"],
564 )
565 assert result is True, "Testcase {} : Failed Error: {}".format(
566 tc_name, result
567 )
568
569 step("Random no shut of upstream interface from DUT side")
570 for i in range(1, 5, 2):
571 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
572 shutdown_bringup_interface(tgen, "r1", intf, True)
573
574 step(
575 "After no shut of upstream interface from DUT verify no change on"
576 "mroute using 'show ip mroute json'; 'show ip upstream json'"
577 )
578
579 for data in input_dict_star_sg:
580 if data["src_address"] == "*":
581 result = verify_mroutes(
582 tgen,
583 data["dut"],
584 data["src_address"],
585 IGMP_JOIN_RANGE_1,
586 data["iif"],
587 data["oil"],
588 )
589 assert result is True, "Testcase {} : Failed Error: {}".format(
590 tc_name, result
591 )
592
593 result = verify_upstream_iif(
594 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
595 )
596 assert result is True, "Testcase {} : Failed Error: {}".format(
597 tc_name, result
598 )
599
600 step("Shut of upstream interface in alternate fashion from R4 side")
601 for i in range(1, 5, 2):
602 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
603 shutdown_bringup_interface(tgen, "r4", intf, False)
604
605 step(
606 "After shut of upstream interface from R4 verify mroutes has moved "
607 "to another interface (R2 or R3) and updated with correct OIL/IIF using"
608 " 'show ip mroute json'"
609 )
610
611 for data in input_dict_star_sg:
612 if data["src_address"] == "*":
613 result = verify_mroutes(
614 tgen,
615 data["dut"],
616 data["src_address"],
617 IGMP_JOIN_RANGE_1,
618 data["iif"],
619 data["oil"],
620 )
621 assert result is True, "Testcase {} : Failed Error: {}".format(
622 tc_name, result
623 )
624
625 step("No shut of upstream interface in alternate fashion from R4 side")
626 for i in range(1, 5, 2):
627 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
628 shutdown_bringup_interface(tgen, "r4", intf, True)
629
630 step(
631 "After no shut of upstream interface from DUT verify no change on"
632 "mroute using 'show ip mroute json'; 'show ip upstream json'"
633 )
634
635 for data in input_dict_star_sg:
636 if data["src_address"] == "*":
637 result = verify_mroutes(
638 tgen,
639 data["dut"],
640 data["src_address"],
641 IGMP_JOIN_RANGE_1,
642 data["iif"],
643 data["oil"],
644 )
645 assert result is True, "Testcase {} : Failed Error: {}".format(
646 tc_name, result
647 )
648
649 result = verify_upstream_iif(
650 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
651 )
652 assert result is True, "Testcase {} : Failed Error: {}".format(
653 tc_name, result
654 )
655
656 step(
657 "Send different IGMP joins from DUT and R4 for group range (From DUT "
658 "225.1.1.1-5 and from R4 226.1.1.1-5)"
659 )
660
661 result = app_helper.run_join("i7", IGMP_JOIN_RANGE_2, "r4")
662 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
663
664 step("Send traffic for all the groups from R4")
665
666 input_src = {"i6": topo["routers"]["i6"]["links"]["r4"]["interface"]}
667 result = app_helper.run_traffic("i6", IGMP_JOIN_RANGE_1 + IGMP_JOIN_RANGE_2, "r4")
668 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
669
670 step(
671 "IGMP groups are received on DUT and R4 verify using 'show ip igmp groups'"
672 " and 'show ip igmp groups json'"
673 )
674
675 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
676 result = verify_igmp_groups(tgen, "r1", intf_r1_i1, IGMP_JOIN_RANGE_1)
677 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
678
679 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
680 result = verify_igmp_groups(
681 tgen, "r4", intf_r4_i7, IGMP_JOIN_RANGE_1 + IGMP_JOIN_RANGE_2
682 )
683 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
684
685 step("(*,G) IIF and OIL updated on both the nodes")
686
687 for data in input_dict_star_sg:
688 if data["src_address"] == "*":
689 result = verify_mroutes(
690 tgen,
691 data["dut"],
692 data["src_address"],
693 IGMP_JOIN_RANGE_1,
694 data["iif"],
695 data["oil"],
696 )
697 assert result is True, "Testcase {} : Failed Error: {}".format(
698 tc_name, result
699 )
700
701 step(
702 "(S,G) IIF updated towards shortest path to source on both the nodes "
703 ", verify using 'show ip mroute' and 'show ip mroute json'"
704 )
705
706 for data in input_dict_star_sg:
707 if data["src_address"] != "*":
708 result = verify_mroutes(
709 tgen,
710 data["dut"],
711 data["src_address"],
712 IGMP_JOIN_RANGE_1,
713 data["iif"],
714 data["oil"],
715 )
716 assert result is True, "Testcase {} : Failed Error: {}".format(
717 tc_name, result
718 )
719
720 step(
721 "OIL is updated and traffic is received for all the groups on both "
722 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
723 )
724
725 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
726 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
727 input_traffic = {
728 "r1": {"traffic_sent": [intf_r1_i1]},
729 "r4": {"traffic_received": [intf_r4_i6]},
730 }
731 result = verify_multicast_traffic(tgen, input_traffic)
732 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
733
734 step("Random shut of upstream interface from DUT side")
735 for i in range(1, 5, 2):
736 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
737 shutdown_bringup_interface(tgen, "r1", intf, False)
738
739 step(
740 "After shut of upstream interface from DUT verify mroutes has moved "
741 "to another interface (R2 or R3) and updated with correct OIL/IIF using"
742 " 'show ip mroute json'"
743 )
744
745 for data in input_dict_star_sg:
746 if data["src_address"] == "*":
747 result = verify_mroutes(
748 tgen,
749 data["dut"],
750 data["src_address"],
751 IGMP_JOIN_RANGE_1,
752 data["iif"],
753 data["oil"],
754 )
755 assert result is True, "Testcase {} : Failed Error: {}".format(
756 tc_name, result
757 )
758
759 step("Random no shut of upstream interface from DUT side")
760 for i in range(1, 5, 2):
761 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
762 shutdown_bringup_interface(tgen, "r1", intf, True)
763
764 step(
765 "After no shut of upstream interface from DUT verify no change on"
766 "mroute using 'show ip mroute json'; 'show ip upstream json'"
767 )
768
769 for data in input_dict_star_sg:
770 if data["src_address"] == "*":
771 result = verify_mroutes(
772 tgen,
773 data["dut"],
774 data["src_address"],
775 IGMP_JOIN_RANGE_1,
776 data["iif"],
777 data["oil"],
778 )
779 assert result is True, "Testcase {} : Failed Error: {}".format(
780 tc_name, result
781 )
782
783 result = verify_upstream_iif(
784 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
785 )
786 assert result is True, "Testcase {} : Failed Error: {}".format(
787 tc_name, result
788 )
789
790 write_test_footer(tc_name)
791
792
793 def test_mroutes_updated_with_correct_oil_iif_when_source_is_in_and_outside_DUT_p0(
794 request,
795 ):
796 """
797 Verify mroutes OIL and IIF updated correctly when source present inside
798 and outside of DUT
799 """
800
801 tgen = get_topogen()
802 tc_name = request.node.name
803 write_test_header(tc_name)
804
805 # Creating configuration from JSON
806 app_helper.stop_all_hosts()
807 clear_mroute(tgen)
808 reset_config_on_routers(tgen)
809 clear_pim_interface_traffic(tgen, topo)
810
811 # Don"t run this test if we have any failure.
812 if tgen.routers_have_failure():
813 pytest.skip(tgen.errors)
814
815 step("Enable IGMP on DUT and R4 interface")
816 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
817 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
818 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
819 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
820
821 result = create_igmp_config(tgen, topo, input_dict)
822 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
823
824 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
825 input_join = {
826 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
827 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
828 }
829
830 for recvr, recvr_intf in input_join.items():
831 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
832 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
833
834 step("Configure RP as R2 for group range 225.1.1.1-5")
835
836 input_dict = {
837 "r2": {
838 "pim": {
839 "rp": [
840 {
841 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
842 "/"
843 )[0],
844 "group_addr_range": GROUP_RANGE_1,
845 }
846 ]
847 }
848 }
849 }
850
851 result = create_pim_config(tgen, topo, input_dict)
852 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
853
854 step("Done in base config: " "Configure EBGP peering between all the nodes")
855
856 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
857
858 step("Send traffic from R4 for group range 225.1.1.1-5")
859
860 result = app_helper.run_traffic("i6", IGMP_JOIN_RANGE_1, "r4")
861 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
862
863 step(
864 "IGMP groups are received on DUT and R4 verify using 'show ip igmp groups'"
865 " and 'show ip igmp groups json'"
866 )
867
868 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
869 result = verify_igmp_groups(tgen, "r1", intf_r1_i1, IGMP_JOIN_RANGE_1)
870 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
871
872 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
873 result = verify_igmp_groups(tgen, "r4", intf_r4_i7, IGMP_JOIN_RANGE_1)
874 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
875
876 step("(*,G) IIF and OIL updated on both the nodes")
877
878 step(
879 "(S,G) IIF updated towards shortest path to source on both the nodes "
880 ", verify using 'show ip mroute' and 'show ip mroute json'"
881 )
882
883 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
884 input_dict_star_sg = [
885 {
886 "dut": "r1",
887 "src_address": "*",
888 "iif": r1_r2_links + r1_r3_links,
889 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
890 },
891 {
892 "dut": "r4",
893 "src_address": "*",
894 "iif": r4_r2_links + r4_r3_links,
895 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
896 },
897 {
898 "dut": "r1",
899 "src_address": source_i6,
900 "iif": r1_r2_links + r1_r3_links,
901 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
902 },
903 {
904 "dut": "r4",
905 "src_address": source_i6,
906 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
907 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
908 },
909 ]
910
911 for data in input_dict_star_sg:
912 result = verify_mroutes(
913 tgen,
914 data["dut"],
915 data["src_address"],
916 IGMP_JOIN_RANGE_1,
917 data["iif"],
918 data["oil"],
919 )
920 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
921
922 step(
923 "OIL is updated and traffic is received for all the groups on both "
924 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
925 )
926
927 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
928 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
929 input_traffic = {
930 "r1": {"traffic_sent": [intf_r1_i1]},
931 "r4": {"traffic_received": [intf_r4_i6]},
932 }
933 result = verify_multicast_traffic(tgen, input_traffic)
934 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
935
936 step("Random shut of upstream interface from DUT side")
937 for i in range(1, 5, 2):
938 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
939 shutdown_bringup_interface(tgen, "r1", intf, False)
940
941 step(
942 "After shut of upstream interface from DUT verify mroutes has moved "
943 "to another interface (R2 or R3) and updated with correct OIL/IIF using"
944 " 'show ip mroute json'"
945 )
946
947 for data in input_dict_star_sg:
948 if data["src_address"] == "*":
949 result = verify_mroutes(
950 tgen,
951 data["dut"],
952 data["src_address"],
953 IGMP_JOIN_RANGE_1,
954 data["iif"],
955 data["oil"],
956 )
957 assert result is True, "Testcase {} : Failed Error: {}".format(
958 tc_name, result
959 )
960
961 step("Random no shut of upstream interface from DUT side")
962 for i in range(1, 5, 2):
963 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
964 shutdown_bringup_interface(tgen, "r1", intf, True)
965
966 step(
967 "After no shut of upstream interface from DUT verify no change on"
968 "mroute using 'show ip mroute json'; 'show ip upstream json'"
969 )
970
971 for data in input_dict_star_sg:
972 if data["src_address"] == "*":
973 result = verify_mroutes(
974 tgen,
975 data["dut"],
976 data["src_address"],
977 IGMP_JOIN_RANGE_1,
978 data["iif"],
979 data["oil"],
980 )
981 assert result is True, "Testcase {} : Failed Error: {}".format(
982 tc_name, result
983 )
984
985 step("Random shut of upstream interface from R4 side")
986 for i in range(1, 5, 2):
987 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
988 shutdown_bringup_interface(tgen, "r4", intf, False)
989
990 step(
991 "After shut of upstream interface from R4 verify mroutes has moved "
992 "to another interface (R2 or R3) and updated with correct OIL/IIF using"
993 " 'show ip mroute json'"
994 )
995
996 for data in input_dict_star_sg:
997 if data["src_address"] == "*":
998 result = verify_mroutes(
999 tgen,
1000 data["dut"],
1001 data["src_address"],
1002 IGMP_JOIN_RANGE_1,
1003 data["iif"],
1004 data["oil"],
1005 )
1006 assert result is True, "Testcase {} : Failed Error: {}".format(
1007 tc_name, result
1008 )
1009
1010 step("Random no shut of upstream interface from R4 side")
1011 for i in range(1, 5, 2):
1012 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
1013 shutdown_bringup_interface(tgen, "r4", intf, True)
1014
1015 step(
1016 "After no shut of upstream interface from DUT verify no change on"
1017 "mroute using 'show ip mroute json'; 'show ip upstream json'"
1018 )
1019
1020 for data in input_dict_star_sg:
1021 if data["src_address"] == "*":
1022 result = verify_mroutes(
1023 tgen,
1024 data["dut"],
1025 data["src_address"],
1026 IGMP_JOIN_RANGE_1,
1027 data["iif"],
1028 data["oil"],
1029 )
1030 assert result is True, "Testcase {} : Failed Error: {}".format(
1031 tc_name, result
1032 )
1033
1034 step(
1035 "Send different IGMP joins from DUT and R4 for group range (From DUT "
1036 "225.1.1.1-5 and from R4 226.1.1.1-5)"
1037 )
1038
1039 result = app_helper.run_join("i7", IGMP_JOIN_RANGE_2, "r4")
1040 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1041
1042 step("Send traffic for all the groups from R4")
1043
1044 result = app_helper.run_traffic("i6", IGMP_JOIN_RANGE_1 + IGMP_JOIN_RANGE_2, "r4")
1045 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1046
1047 step(
1048 "IGMP groups are received on DUT and R4 verify using 'show ip igmp groups'"
1049 " and 'show ip igmp groups json'"
1050 )
1051
1052 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1053 result = verify_igmp_groups(tgen, "r1", intf_r1_i1, IGMP_JOIN_RANGE_1)
1054 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1055
1056 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
1057 result = verify_igmp_groups(
1058 tgen, "r4", intf_r4_i7, IGMP_JOIN_RANGE_1 + IGMP_JOIN_RANGE_2
1059 )
1060 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1061
1062 step("(*,G) IIF and OIL updated on both the nodes")
1063
1064 for data in input_dict_star_sg:
1065 if data["src_address"] == "*":
1066 result = verify_mroutes(
1067 tgen,
1068 data["dut"],
1069 data["src_address"],
1070 IGMP_JOIN_RANGE_1,
1071 data["iif"],
1072 data["oil"],
1073 )
1074 assert result is True, "Testcase {} : Failed Error: {}".format(
1075 tc_name, result
1076 )
1077
1078 step(
1079 "(S,G) IIF updated towards shortest path to source on both the nodes "
1080 ", verify using 'show ip mroute' and 'show ip mroute json'"
1081 )
1082
1083 for data in input_dict_star_sg:
1084 if data["src_address"] != "*":
1085 result = verify_mroutes(
1086 tgen,
1087 data["dut"],
1088 data["src_address"],
1089 IGMP_JOIN_RANGE_1,
1090 data["iif"],
1091 data["oil"],
1092 )
1093 assert result is True, "Testcase {} : Failed Error: {}".format(
1094 tc_name, result
1095 )
1096
1097 step(
1098 "OIL is updated and traffic is received for all the groups on both "
1099 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
1100 )
1101
1102 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
1103 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1104 input_traffic = {
1105 "r1": {"traffic_sent": [intf_r1_i1]},
1106 "r4": {"traffic_received": [intf_r4_i6]},
1107 }
1108 result = verify_multicast_traffic(tgen, input_traffic)
1109 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1110
1111 step("Random shut and no shut of upstream interface from DUT side")
1112
1113 step("Random shut of upstream interface from DUT side")
1114 for i in range(1, 5, 2):
1115 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
1116 shutdown_bringup_interface(tgen, "r1", intf, False)
1117
1118 step(
1119 "After shut of upstream interface from DUT verify mroutes has moved "
1120 "to another interface (R2 or R3) and updated with correct OIL/IIF using"
1121 " 'show ip mroute json'"
1122 )
1123
1124 for data in input_dict_star_sg:
1125 if data["src_address"] == "*":
1126 result = verify_mroutes(
1127 tgen,
1128 data["dut"],
1129 data["src_address"],
1130 IGMP_JOIN_RANGE_1,
1131 data["iif"],
1132 data["oil"],
1133 )
1134 assert result is True, "Testcase {} : Failed Error: {}".format(
1135 tc_name, result
1136 )
1137
1138 step("Random no shut of upstream interface from DUT side")
1139 for i in range(1, 5, 2):
1140 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
1141 shutdown_bringup_interface(tgen, "r1", intf, True)
1142
1143 step(
1144 "After no shut of upstream interface from DUT verify no change on"
1145 "mroute using 'show ip mroute json'; 'show ip upstream json'"
1146 )
1147
1148 for data in input_dict_star_sg:
1149 if data["src_address"] == "*":
1150 result = verify_mroutes(
1151 tgen,
1152 data["dut"],
1153 data["src_address"],
1154 IGMP_JOIN_RANGE_1,
1155 data["iif"],
1156 data["oil"],
1157 )
1158 assert result is True, "Testcase {} : Failed Error: {}".format(
1159 tc_name, result
1160 )
1161
1162 write_test_footer(tc_name)
1163
1164
1165 def test_verify_mroutes_forwarding_p0(request):
1166 """
1167 Verify Mroutes and BSM forwarding when edge is transit node
1168 """
1169
1170 tgen = get_topogen()
1171 tc_name = request.node.name
1172 write_test_header(tc_name)
1173
1174 # Creating configuration from JSON
1175 app_helper.stop_all_hosts()
1176 clear_mroute(tgen)
1177 reset_config_on_routers(tgen)
1178 clear_pim_interface_traffic(tgen, topo)
1179
1180 # Don"t run this test if we have any failure.
1181 if tgen.routers_have_failure():
1182 pytest.skip(tgen.errors)
1183
1184 step("To make DUT as transit node , shut all the links from R3 to R4 nodes")
1185 for i in range(1, 5):
1186 intf = topo["routers"]["r3"]["links"]["r4-link{}".format(i)]["interface"]
1187 shutdown_bringup_interface(tgen, "r3", intf, False)
1188
1189 intf = topo["routers"]["r4"]["links"]["r3-link{}".format(i)]["interface"]
1190 shutdown_bringup_interface(tgen, "r4", intf, False)
1191
1192 step("Enable IGMP on DUT and R3 interface")
1193 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1194 intf_r3_i5 = topo["routers"]["r3"]["links"]["i5"]["interface"]
1195 for dut, intf in zip(["r1", "r3"], [intf_r1_i1, intf_r3_i5]):
1196 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
1197
1198 result = create_igmp_config(tgen, topo, input_dict)
1199 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1200
1201 step("Send IGMP joins from DUT and R4 for group range 226.1.1.1-5")
1202 input_join = {
1203 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
1204 "i5": topo["routers"]["i5"]["links"]["r3"]["interface"],
1205 }
1206
1207 for recvr, recvr_intf in input_join.items():
1208 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_2, join_intf=recvr_intf)
1209 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1210
1211 step("Configure RP as R2 for group range 226.1.1.1-5")
1212
1213 input_dict = {
1214 "r2": {
1215 "pim": {
1216 "rp": [
1217 {
1218 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1219 "/"
1220 )[0],
1221 "group_addr_range": GROUP_RANGE_2,
1222 }
1223 ]
1224 }
1225 }
1226 }
1227
1228 result = create_pim_config(tgen, topo, input_dict)
1229 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1230
1231 step("Done in base config: " "Configure EBGP peering between all the nodes")
1232
1233 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
1234
1235 step("Send traffic from R4 for group range 226.1.1.1-5")
1236
1237 input_src = {
1238 "i6": topo["routers"]["i6"]["links"]["r4"]["interface"],
1239 "i2": topo["routers"]["i2"]["links"]["r1"]["interface"],
1240 }
1241
1242 for src, src_intf in input_src.items():
1243 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_2, bind_intf=src_intf)
1244 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1245
1246 step(
1247 "BSR and candidate RP info populated in R3 node verify using "
1248 "'show ip pim rp-info json'"
1249 )
1250
1251 rp_addr_r2 = topo["routers"]["r2"]["links"]["lo"]["ipv4"].split("/")[0]
1252
1253 result = verify_pim_rp_info(
1254 tgen, topo, "r2", GROUP_RANGE_2, "lo", rp_addr_r2, "Static"
1255 )
1256 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1257
1258 step("(*,G) IIF and OIL updated on both the nodes")
1259
1260 step(
1261 "(S,G) IIF updated towards shortest path to source on both the nodes "
1262 ", verify using 'show ip mroute' and 'show ip mroute json'"
1263 )
1264
1265 step(
1266 "DUT created (*,G) and (S,G) entries as transit node for 226.1.1.1-5 "
1267 "mroutes , OIL is local received and toward R3"
1268 )
1269
1270 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
1271 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
1272 input_dict_star_sg = [
1273 {
1274 "dut": "r1",
1275 "src_address": "*",
1276 "iif": r1_r2_links + r1_r3_links,
1277 "oil": r1_r3_links + [topo["routers"]["r1"]["links"]["i1"]["interface"]],
1278 },
1279 {
1280 "dut": "r1",
1281 "src_address": source_i2,
1282 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
1283 "oil": r1_r3_links + [topo["routers"]["r1"]["links"]["i1"]["interface"]],
1284 },
1285 {
1286 "dut": "r1",
1287 "src_address": source_i6,
1288 "iif": r1_r2_links + r1_r3_links,
1289 "oil": r1_r3_links + [topo["routers"]["r1"]["links"]["i1"]["interface"]],
1290 },
1291 {
1292 "dut": "r3",
1293 "src_address": "*",
1294 "iif": r3_r1_links,
1295 "oil": topo["routers"]["r3"]["links"]["i5"]["interface"],
1296 },
1297 {
1298 "dut": "r3",
1299 "src_address": source_i2,
1300 "iif": r3_r1_links,
1301 "oil": topo["routers"]["r3"]["links"]["i5"]["interface"],
1302 },
1303 {
1304 "dut": "r3",
1305 "src_address": source_i6,
1306 "iif": r3_r1_links,
1307 "oil": topo["routers"]["r3"]["links"]["i5"]["interface"],
1308 },
1309 ]
1310
1311 for data in input_dict_star_sg:
1312 result = verify_mroutes(
1313 tgen,
1314 data["dut"],
1315 data["src_address"],
1316 IGMP_JOIN_RANGE_2,
1317 data["iif"],
1318 data["oil"],
1319 )
1320 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1321
1322 step(
1323 "OIL is updated and traffic is received for all the groups on both "
1324 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
1325 )
1326
1327 intf_r3_i5 = topo["routers"]["r3"]["links"]["i5"]["interface"]
1328 intf_r1_i2 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1329 input_traffic = {
1330 "r3": {"traffic_sent": [intf_r3_i5]},
1331 "r1": {"traffic_sent": [intf_r1_i2]},
1332 }
1333 result = verify_multicast_traffic(tgen, input_traffic)
1334 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1335
1336 step(
1337 "Send different join from R3 (232.1.1.1-5) and traffic "
1338 "from R4 for same range"
1339 )
1340
1341 input_join = {"i5": topo["routers"]["i5"]["links"]["r3"]["interface"]}
1342 result = app_helper.run_join("i5", IGMP_JOIN_RANGE_3, "r3")
1343 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1344
1345 input_dict = {
1346 "r2": {
1347 "pim": {
1348 "rp": [
1349 {
1350 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1351 "/"
1352 )[0],
1353 "group_addr_range": GROUP_RANGE_3,
1354 }
1355 ]
1356 }
1357 }
1358 }
1359
1360 result = create_pim_config(tgen, topo, input_dict)
1361 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1362
1363 input_src = {"i6": topo["routers"]["i6"]["links"]["r4"]["interface"]}
1364 result = app_helper.run_traffic("i6", IGMP_JOIN_RANGE_3, "r4")
1365 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1366
1367 step("For different join (232.1.1.1-5) DUT created mroute OIL toward R3 only")
1368
1369 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
1370 input_dict_sg = [
1371 {"dut": "r1", "src_address": "*", "iif": r1_r2_links, "oil": r1_r3_links},
1372 {"dut": "r1", "src_address": source_i6, "iif": r1_r2_links, "oil": r1_r3_links},
1373 ]
1374
1375 for data in input_dict_sg:
1376 result = verify_mroutes(
1377 tgen,
1378 data["dut"],
1379 data["src_address"],
1380 IGMP_JOIN_RANGE_3,
1381 data["iif"],
1382 data["oil"],
1383 )
1384 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1385
1386 result = verify_upstream_iif(
1387 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_3
1388 )
1389 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1390
1391 step("Shut from DUT to R2 and no shut from DUT")
1392
1393 for i in range(1, 5):
1394 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
1395 shutdown_bringup_interface(tgen, "r1", intf, False)
1396
1397 step(
1398 "After Shut (R1-R2) link from DUT, verify IIF on DUT changed to "
1399 "different uplink interface on DUT 'show ip mroute json' for R4 so "
1400 "connected urce"
1401 )
1402
1403 input_dict_sg = [
1404 {
1405 "dut": "r1",
1406 "src_address": source_i2,
1407 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
1408 "oil": r1_r3_links + [topo["routers"]["r1"]["links"]["i1"]["interface"]],
1409 }
1410 ]
1411
1412 for data in input_dict_sg:
1413 result = verify_mroutes(
1414 tgen,
1415 data["dut"],
1416 data["src_address"],
1417 IGMP_JOIN_RANGE_2,
1418 data["iif"],
1419 data["oil"],
1420 )
1421 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1422
1423 step("Traffic is received fine for R4 source 'show ip multicast json' on DUT")
1424
1425 result = verify_multicast_traffic(tgen, input_traffic)
1426 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1427
1428 step("No shut from DUT to R2 and no shut from DUT")
1429
1430 for i in range(1, 5):
1431 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
1432 shutdown_bringup_interface(tgen, "r1", intf, True)
1433
1434 for data in input_dict_sg:
1435 result = verify_mroutes(
1436 tgen,
1437 data["dut"],
1438 data["src_address"],
1439 IGMP_JOIN_RANGE_2,
1440 data["iif"],
1441 data["oil"],
1442 )
1443 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1444
1445 step("Shut and no shut DUT to R2 within 30 sec from DUT")
1446
1447 for i in range(1, 5):
1448 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
1449 shutdown_bringup_interface(tgen, "r1", intf, False)
1450
1451 for i in range(1, 5):
1452 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
1453 shutdown_bringup_interface(tgen, "r1", intf, True)
1454
1455 step(
1456 "Shut and No shut in 30 sec time , verify on R2 added 2 entries in mroute "
1457 ", shut link OIL got timeout after sometime"
1458 )
1459
1460 for data in input_dict_star_sg:
1461 result = verify_mroutes(
1462 tgen,
1463 data["dut"],
1464 data["src_address"],
1465 IGMP_JOIN_RANGE_2,
1466 data["iif"],
1467 data["oil"],
1468 )
1469 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1470
1471 result = verify_upstream_iif(
1472 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_2
1473 )
1474 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1475
1476 write_test_footer(tc_name)
1477
1478
1479 def test_mroutes_updated_correctly_after_source_interface_shut_noshut_p1(request):
1480 """
1481 Verify mroutes updated correctly after source interface shut/no shut
1482 """
1483
1484 tgen = get_topogen()
1485 tc_name = request.node.name
1486 write_test_header(tc_name)
1487
1488 # Creating configuration from JSON
1489 app_helper.stop_all_hosts()
1490 clear_mroute(tgen)
1491 reset_config_on_routers(tgen)
1492 clear_pim_interface_traffic(tgen, topo)
1493
1494 # Don"t run this test if we have any failure.
1495 if tgen.routers_have_failure():
1496 pytest.skip(tgen.errors)
1497
1498 step("Enable IGMP on DUT and R4 interface")
1499 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1500 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
1501 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
1502 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
1503
1504 result = create_igmp_config(tgen, topo, input_dict)
1505 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1506
1507 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
1508 input_join = {
1509 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
1510 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
1511 }
1512
1513 for recvr, recvr_intf in input_join.items():
1514 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
1515 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1516
1517 step("Configure RP as R2 for group range 225.1.1.1-5")
1518
1519 input_dict = {
1520 "r2": {
1521 "pim": {
1522 "rp": [
1523 {
1524 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1525 "/"
1526 )[0],
1527 "group_addr_range": GROUP_RANGE_1,
1528 }
1529 ]
1530 }
1531 }
1532 }
1533
1534 result = create_pim_config(tgen, topo, input_dict)
1535 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1536
1537 step("Done in base config: " "Configure EBGP peering between all the nodes")
1538
1539 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
1540
1541 step("Send traffic from R4 for group range 225.1.1.1-5")
1542 step("Send traffic from DUT for group range 225.1.1.1-5")
1543
1544 input_src = {
1545 "i6": topo["routers"]["i6"]["links"]["r4"]["interface"],
1546 "i2": topo["routers"]["i2"]["links"]["r1"]["interface"],
1547 }
1548
1549 for src, src_intf in input_src.items():
1550 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
1551 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1552
1553 step("(*,G) IIF and OIL updated on both the nodes")
1554
1555 input_dict_starg = [
1556 {
1557 "dut": "r1",
1558 "src_address": "*",
1559 "iif": r1_r2_links + r1_r3_links,
1560 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
1561 },
1562 {
1563 "dut": "r4",
1564 "src_address": "*",
1565 "iif": r4_r2_links + r4_r3_links,
1566 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
1567 },
1568 ]
1569
1570 for data in input_dict_starg:
1571 result = verify_mroutes(
1572 tgen,
1573 data["dut"],
1574 data["src_address"],
1575 IGMP_JOIN_RANGE_1,
1576 data["iif"],
1577 data["oil"],
1578 )
1579 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1580
1581 result = verify_upstream_iif(
1582 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1583 )
1584 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1585
1586 step(
1587 "(S,G) IIF updated towards shortest path to source on both the nodes "
1588 ", verify using 'show ip mroute' and 'show ip mroute json'"
1589 )
1590
1591 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
1592 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
1593 input_dict_sg = [
1594 {
1595 "dut": "r1",
1596 "src_address": source_i6,
1597 "iif": r1_r2_links + r1_r3_links,
1598 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
1599 },
1600 {
1601 "dut": "r1",
1602 "src_address": source_i2,
1603 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
1604 "oil": r1_r3_links + [topo["routers"]["r1"]["links"]["i1"]["interface"]],
1605 },
1606 {
1607 "dut": "r4",
1608 "src_address": source_i6,
1609 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
1610 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
1611 },
1612 {
1613 "dut": "r4",
1614 "src_address": source_i2,
1615 "iif": r4_r2_links + r4_r3_links,
1616 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
1617 },
1618 ]
1619
1620 for data in input_dict_sg:
1621 result = verify_mroutes(
1622 tgen,
1623 data["dut"],
1624 data["src_address"],
1625 IGMP_JOIN_RANGE_1,
1626 data["iif"],
1627 data["oil"],
1628 )
1629 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1630
1631 step(
1632 "OIL is updated and traffic is received for all the groups on both "
1633 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
1634 )
1635
1636 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
1637 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1638 input_traffic = {
1639 "r1": {"traffic_sent": [intf_r1_i1]},
1640 "r4": {"traffic_received": [intf_r4_i6]},
1641 }
1642 result = verify_multicast_traffic(tgen, input_traffic)
1643 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1644
1645 step("On R1 for local IGMP receivers, OIL towards RP is removed")
1646
1647 input_dict = [
1648 {
1649 "dut": "r1",
1650 "src_address": source_i2,
1651 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
1652 "oil": topo["routers"]["r1"]["links"]["i2"]["interface"],
1653 }
1654 ]
1655
1656 for data in input_dict:
1657 result = verify_mroutes(
1658 tgen,
1659 data["dut"],
1660 data["src_address"],
1661 IGMP_JOIN_RANGE_1,
1662 data["iif"],
1663 data["oil"],
1664 expected=False,
1665 )
1666 assert (
1667 result is not True
1668 ), "Testcase {} : Failed " "Mroute IIF and OIF are same \n Error: {}".format(
1669 tc_name, result
1670 )
1671
1672 step("Shut and No shut source interface multiple time")
1673
1674 for i in range(0, 2):
1675 step("Shut and no shut the source interface from DUT")
1676 intf_r1_i2 = topo["routers"]["r1"]["links"]["i2"]["interface"]
1677 shutdown_bringup_interface(tgen, "r1", intf_r1_i2, False)
1678 shutdown_bringup_interface(tgen, "r1", intf_r1_i2, True)
1679
1680 step(
1681 "After shut/no shut of source interface verify all the (S,G) "
1682 "got re-learn and IIF/OIF pointing any of the links from R2 or "
1683 "R3 verify using 'show ip mroute json'"
1684 )
1685
1686 step(
1687 "(S,G) OIL on R1 has only respective receiver port and uplink port "
1688 " , RP side oil is removed"
1689 )
1690
1691 for data in input_dict_sg:
1692 result = verify_mroutes(
1693 tgen,
1694 data["dut"],
1695 data["src_address"],
1696 IGMP_JOIN_RANGE_1,
1697 data["iif"],
1698 data["oil"],
1699 )
1700 assert result is True, "Testcase {} : Failed Error: {}".format(
1701 tc_name, result
1702 )
1703
1704 step("No change seen on (*,G) mroutes")
1705
1706 for data in input_dict_starg:
1707 result = verify_mroutes(
1708 tgen,
1709 data["dut"],
1710 data["src_address"],
1711 IGMP_JOIN_RANGE_1,
1712 data["iif"],
1713 data["oil"],
1714 )
1715 assert result is True, "Testcase {} : Failed Error: {}".format(
1716 tc_name, result
1717 )
1718
1719 step(
1720 "Traffic is received for all the groups , verify using "
1721 "'show ip multicast count json'"
1722 )
1723
1724 result = verify_multicast_traffic(tgen, input_traffic)
1725 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1726
1727 step("Shut and no shut the source interface from R4")
1728
1729 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
1730 shutdown_bringup_interface(tgen, "r4", intf_r4_i6, False)
1731 shutdown_bringup_interface(tgen, "r4", intf_r4_i6, True)
1732
1733 step(
1734 "After shut/no shut of source interface verify all the (S,G) "
1735 "got re-learn and IIF/OIF pointing any of the links from R2 or "
1736 "R3 verify using 'show ip mroute json'"
1737 )
1738
1739 step(
1740 "(S,G) OIL on R1 has only respective receiver port and uplink port "
1741 " , RP side oil is removed"
1742 )
1743
1744 for data in input_dict_sg:
1745 result = verify_mroutes(
1746 tgen,
1747 data["dut"],
1748 data["src_address"],
1749 IGMP_JOIN_RANGE_1,
1750 data["iif"],
1751 data["oil"],
1752 )
1753 assert result is True, "Testcase {} : Failed Error: {}".format(
1754 tc_name, result
1755 )
1756
1757 step("No change seen on (*,G) mroutes")
1758
1759 for data in input_dict_starg:
1760 result = verify_mroutes(
1761 tgen,
1762 data["dut"],
1763 data["src_address"],
1764 IGMP_JOIN_RANGE_1,
1765 data["iif"],
1766 data["oil"],
1767 )
1768 assert result is True, "Testcase {} : Failed Error: {}".format(
1769 tc_name, result
1770 )
1771
1772 step(
1773 "Traffic is received for all the groups , verify using "
1774 "'show ip multicast count json'"
1775 )
1776
1777 result = verify_multicast_traffic(tgen, input_traffic)
1778 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1779
1780 step(
1781 "Shut source interface from R4 and no shut immediate after the "
1782 "same source upstream expires from DUT"
1783 )
1784
1785 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
1786 shutdown_bringup_interface(tgen, "r4", intf_r4_i6, False)
1787 shutdown_bringup_interface(tgen, "r4", intf_r4_i6, True)
1788
1789 step(
1790 "After no shut verify mroutes populated and multicast traffic resume ,"
1791 " verify using 'show ip mroute json' 'show ip multicast count json'"
1792 )
1793
1794 for data in input_dict_sg:
1795 result = verify_mroutes(
1796 tgen,
1797 data["dut"],
1798 data["src_address"],
1799 IGMP_JOIN_RANGE_1,
1800 data["iif"],
1801 data["oil"],
1802 )
1803 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1804
1805 result = verify_multicast_traffic(tgen, input_traffic)
1806 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1807
1808 step(
1809 "Shut source interface from DUT and no shut immediate after the "
1810 "same source upstream expires from R4"
1811 )
1812
1813 intf_r1_i2 = topo["routers"]["r1"]["links"]["i2"]["interface"]
1814 shutdown_bringup_interface(tgen, "r1", intf_r1_i2, False)
1815 shutdown_bringup_interface(tgen, "r1", intf_r1_i2, True)
1816
1817 step(
1818 "After no shut verify mroutes populated and multicast traffic resume ,"
1819 " verify using 'show ip mroute json' 'show ip multicast count json'"
1820 )
1821
1822 for data in input_dict_sg:
1823 result = verify_mroutes(
1824 tgen,
1825 data["dut"],
1826 data["src_address"],
1827 IGMP_JOIN_RANGE_1,
1828 data["iif"],
1829 data["oil"],
1830 )
1831 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1832
1833 result = verify_multicast_traffic(tgen, input_traffic)
1834 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1835
1836 write_test_footer(tc_name)
1837
1838
1839 def test_mroutes_updated_correctly_after_receiver_interface_shut_noshut_p1(request):
1840 """
1841 Verify mroutes updated correctly after receiver interface shut/no shut
1842 """
1843
1844 tgen = get_topogen()
1845 tc_name = request.node.name
1846 write_test_header(tc_name)
1847
1848 # Creating configuration from JSON
1849 app_helper.stop_all_hosts()
1850 clear_mroute(tgen)
1851 reset_config_on_routers(tgen)
1852 clear_pim_interface_traffic(tgen, topo)
1853
1854 # Don"t run this test if we have any failure.
1855 if tgen.routers_have_failure():
1856 pytest.skip(tgen.errors)
1857
1858 step("Enable IGMP on DUT and R4 interface")
1859 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1860 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
1861 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
1862 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
1863
1864 result = create_igmp_config(tgen, topo, input_dict)
1865 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1866
1867 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
1868 input_join = {
1869 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
1870 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
1871 }
1872
1873 for recvr, recvr_intf in input_join.items():
1874 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
1875 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1876
1877 step("Configure RP as R2 for group range 225.1.1.1-5")
1878
1879 input_dict = {
1880 "r2": {
1881 "pim": {
1882 "rp": [
1883 {
1884 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1885 "/"
1886 )[0],
1887 "group_addr_range": GROUP_RANGE_1,
1888 }
1889 ]
1890 }
1891 }
1892 }
1893
1894 result = create_pim_config(tgen, topo, input_dict)
1895 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1896
1897 step("Done in base config: " "Configure EBGP peering between all the nodes")
1898
1899 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
1900
1901 step("Send traffic from R4 for group range 225.1.1.1-5")
1902
1903 result = app_helper.run_traffic("i6", IGMP_JOIN_RANGE_1, "r4")
1904 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1905
1906 step("Send traffic from DUT for group range 225.1.1.1-5")
1907
1908 result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "r1")
1909 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1910
1911 step("(*,G) IIF and OIL updated on both the nodes")
1912
1913 input_dict_starg = [
1914 {
1915 "dut": "r1",
1916 "src_address": "*",
1917 "iif_r1_r2": r1_r2_links + r1_r3_links,
1918 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
1919 },
1920 {
1921 "dut": "r4",
1922 "src_address": "*",
1923 "iif_r1_r2": r4_r2_links + r4_r3_links,
1924 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
1925 },
1926 ]
1927
1928 for data in input_dict_starg:
1929 result = verify_mroutes(
1930 tgen,
1931 data["dut"],
1932 data["src_address"],
1933 IGMP_JOIN_RANGE_1,
1934 data["iif_r1_r2"],
1935 data["oil"],
1936 )
1937 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1938
1939 result = verify_upstream_iif(
1940 tgen, data["dut"], data["iif_r1_r2"], data["src_address"], IGMP_JOIN_RANGE_1
1941 )
1942 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1943
1944 step(
1945 "(S,G) IIF updated towards shortest path to source on both the nodes "
1946 ", verify using 'show ip mroute' and 'show ip mroute json'"
1947 )
1948
1949 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
1950 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
1951 input_dict_sg = [
1952 {
1953 "dut": "r1",
1954 "src_address": source_i6,
1955 "iif": r1_r2_links + r1_r3_links,
1956 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
1957 },
1958 {
1959 "dut": "r1",
1960 "src_address": source_i2,
1961 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
1962 "oil": r1_r3_links + [topo["routers"]["r1"]["links"]["i1"]["interface"]],
1963 },
1964 {
1965 "dut": "r4",
1966 "src_address": source_i6,
1967 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
1968 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
1969 },
1970 {
1971 "dut": "r4",
1972 "src_address": source_i2,
1973 "iif": r4_r2_links + r4_r3_links,
1974 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
1975 },
1976 ]
1977
1978 for data in input_dict_sg:
1979 result = verify_mroutes(
1980 tgen,
1981 data["dut"],
1982 data["src_address"],
1983 IGMP_JOIN_RANGE_1,
1984 data["iif"],
1985 data["oil"],
1986 )
1987 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1988
1989 step(
1990 "OIL is updated and traffic is received for all the groups on both "
1991 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
1992 )
1993
1994 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
1995 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
1996 input_traffic = {
1997 "r1": {"traffic_sent": [intf_r1_i1]},
1998 "r4": {"traffic_received": [intf_r4_i6]},
1999 }
2000 result = verify_multicast_traffic(tgen, input_traffic)
2001 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2002
2003 step("Shut and no shut the source interface from DUT")
2004 for i in range(1, 5):
2005 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
2006 shutdown_bringup_interface(tgen, "r1", intf, False)
2007
2008 for i in range(1, 5):
2009 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
2010 shutdown_bringup_interface(tgen, "r1", intf, True)
2011
2012 step(
2013 "After shut/no shut of source interface verify all the (S,G) "
2014 "got re-learn and IIF/OIF pointing any of the links from R2 or "
2015 "R3 verify using 'show ip mroute json'"
2016 )
2017
2018 step(
2019 "(S,G) OIL on R1 has only respective receiver port and uplink port "
2020 " , RP side oil is removed"
2021 )
2022
2023 for data in input_dict_sg:
2024 result = verify_mroutes(
2025 tgen,
2026 data["dut"],
2027 data["src_address"],
2028 IGMP_JOIN_RANGE_1,
2029 data["iif"],
2030 data["oil"],
2031 )
2032 assert result is True, "Testcase {} : Failed Error: {}".format(
2033 tc_name, result
2034 )
2035
2036 step(
2037 "Traffic is received for all the groups , verify using "
2038 "'show ip multicast count json'"
2039 )
2040
2041 result = verify_multicast_traffic(tgen, input_traffic)
2042 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2043
2044 step("Shut the receiver interface from R4")
2045 for i in range(1, 5):
2046 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
2047 shutdown_bringup_interface(tgen, "r4", intf, False)
2048
2049 for i in range(1, 5):
2050 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
2051 shutdown_bringup_interface(tgen, "r4", intf, True)
2052
2053 step(
2054 "After shut/no shut of source interface verify all the (S,G) "
2055 "got re-learn and IIF/OIF pointing any of the links from R2 or "
2056 "R3 verify using 'show ip mroute json'"
2057 )
2058
2059 step(
2060 "(S,G) OIL on R1 has only respective receiver port and uplink port "
2061 " , RP side oil is removed"
2062 )
2063
2064 for data in input_dict_sg:
2065 result = verify_mroutes(
2066 tgen,
2067 data["dut"],
2068 data["src_address"],
2069 IGMP_JOIN_RANGE_1,
2070 data["iif"],
2071 data["oil"],
2072 )
2073 assert result is True, "Testcase {} : Failed Error: {}".format(
2074 tc_name, result
2075 )
2076
2077 step(
2078 "Traffic is received for all the groups , verify using "
2079 "'show ip multicast count json'"
2080 )
2081
2082 result = verify_multicast_traffic(tgen, input_traffic)
2083 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2084
2085 step(
2086 "Shut and no shut the receiver interface from DUT after PIM upstream" " timeout"
2087 )
2088
2089 for i in range(1, 5):
2090 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
2091 shutdown_bringup_interface(tgen, "r1", intf, False)
2092
2093 for i in range(1, 5):
2094 intf = topo["routers"]["r1"]["links"]["r2-link{}".format(i)]["interface"]
2095 shutdown_bringup_interface(tgen, "r1", intf, True)
2096
2097 for data in input_dict_sg:
2098 result = verify_mroutes(
2099 tgen,
2100 data["dut"],
2101 data["src_address"],
2102 IGMP_JOIN_RANGE_1,
2103 data["iif"],
2104 data["oil"],
2105 )
2106 assert result is True, "Testcase {} : Failed Error: {}".format(
2107 tc_name, result
2108 )
2109
2110 step(
2111 "Traffic is received for all the groups , verify using "
2112 "'show ip multicast count json'"
2113 )
2114
2115 result = verify_multicast_traffic(tgen, input_traffic)
2116 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2117
2118 step(
2119 "Shut and no shut the receiver interface from R4 after PIM upstream " "timeout"
2120 )
2121
2122 for i in range(1, 5):
2123 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
2124 shutdown_bringup_interface(tgen, "r4", intf, False)
2125
2126 for i in range(1, 5):
2127 intf = topo["routers"]["r4"]["links"]["r2-link{}".format(i)]["interface"]
2128 shutdown_bringup_interface(tgen, "r4", intf, True)
2129
2130 for data in input_dict_sg:
2131 result = verify_mroutes(
2132 tgen,
2133 data["dut"],
2134 data["src_address"],
2135 IGMP_JOIN_RANGE_1,
2136 data["iif"],
2137 data["oil"],
2138 )
2139 assert result is True, "Testcase {} : Failed Error: {}".format(
2140 tc_name, result
2141 )
2142
2143 step(
2144 "Traffic is received for all the groups , verify using "
2145 "'show ip multicast count json'"
2146 )
2147
2148 result = verify_multicast_traffic(tgen, input_traffic)
2149 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2150
2151 write_test_footer(tc_name)
2152
2153
2154 def test_mroutes_updated_after_sending_IGMP_prune_and_join_p1(request):
2155 """
2156 Verify mroute updated correctly after sending IGMP prune and join
2157 """
2158
2159 tgen = get_topogen()
2160 tc_name = request.node.name
2161 write_test_header(tc_name)
2162
2163 # Creating configuration from JSON
2164 app_helper.stop_all_hosts()
2165 clear_mroute(tgen)
2166 reset_config_on_routers(tgen)
2167 clear_pim_interface_traffic(tgen, topo)
2168
2169 # Don"t run this test if we have any failure.
2170 if tgen.routers_have_failure():
2171 pytest.skip(tgen.errors)
2172
2173 step("Enable IGMP on DUT and R4 interface")
2174 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
2175 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
2176 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
2177 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
2178
2179 result = create_igmp_config(tgen, topo, input_dict)
2180 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2181
2182 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
2183 input_join = {
2184 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
2185 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
2186 }
2187
2188 for recvr, recvr_intf in input_join.items():
2189 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2190 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2191
2192 step("Configure RP as R2 for group range 225.1.1.1-5")
2193
2194 input_dict = {
2195 "r2": {
2196 "pim": {
2197 "rp": [
2198 {
2199 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2200 "/"
2201 )[0],
2202 "group_addr_range": GROUP_RANGE_1,
2203 }
2204 ]
2205 }
2206 }
2207 }
2208
2209 result = create_pim_config(tgen, topo, input_dict)
2210 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2211
2212 step("Done in base config: " "Configure EBGP peering between all the nodes")
2213
2214 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
2215
2216 step("Send traffic from R4 for group range 225.1.1.1-5")
2217 step("Send traffic from DUT for group range 225.1.1.1-5")
2218
2219 input_src = {
2220 "i6": topo["routers"]["i6"]["links"]["r4"]["interface"],
2221 "i2": topo["routers"]["i2"]["links"]["r1"]["interface"],
2222 }
2223
2224 for src, src_intf in input_src.items():
2225 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
2226 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2227
2228 step("(*,G) IIF and OIL updated on both the nodes")
2229
2230 input_dict_starg = [
2231 {
2232 "dut": "r1",
2233 "src_address": "*",
2234 "iif_r1_r2": r1_r2_links + r1_r3_links,
2235 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2236 },
2237 {
2238 "dut": "r4",
2239 "src_address": "*",
2240 "iif_r1_r2": r4_r2_links + r4_r3_links,
2241 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2242 },
2243 ]
2244
2245 for data in input_dict_starg:
2246 result = verify_mroutes(
2247 tgen,
2248 data["dut"],
2249 data["src_address"],
2250 IGMP_JOIN_RANGE_1,
2251 data["iif_r1_r2"],
2252 data["oil"],
2253 )
2254 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2255
2256 result = verify_upstream_iif(
2257 tgen, data["dut"], data["iif_r1_r2"], data["src_address"], IGMP_JOIN_RANGE_1
2258 )
2259 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2260
2261 step(
2262 "(S,G) IIF updated towards shortest path to source on both the nodes "
2263 ", verify using 'show ip mroute' and 'show ip mroute json'"
2264 )
2265
2266 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
2267 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
2268 input_dict_sg = [
2269 {
2270 "dut": "r1",
2271 "src_address": source_i6,
2272 "iif": r1_r2_links + r1_r3_links,
2273 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2274 },
2275 {
2276 "dut": "r1",
2277 "src_address": source_i2,
2278 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
2279 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2280 },
2281 {
2282 "dut": "r4",
2283 "src_address": source_i6,
2284 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
2285 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2286 },
2287 {
2288 "dut": "r4",
2289 "src_address": source_i2,
2290 "iif": r4_r2_links + r4_r3_links,
2291 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2292 },
2293 ]
2294
2295 for data in input_dict_sg:
2296 result = verify_mroutes(
2297 tgen,
2298 data["dut"],
2299 data["src_address"],
2300 IGMP_JOIN_RANGE_1,
2301 data["iif"],
2302 data["oil"],
2303 )
2304 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2305
2306 step(
2307 "OIL is updated and traffic is received for all the groups on both "
2308 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
2309 )
2310
2311 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
2312 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
2313 input_traffic = {
2314 "r1": {"traffic_sent": [intf_r1_i1]},
2315 "r4": {"traffic_received": [intf_r4_i6]},
2316 }
2317 result = verify_multicast_traffic(tgen, input_traffic)
2318 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2319
2320 step("Send IGMP prune and join for receivers connected on DUT")
2321 step("Send IGMP prune and join for receivers connected on R4")
2322
2323 app_helper.stop_all_hosts()
2324
2325 step(
2326 "After sending prune verify (*,G) and (S,G) entries got cleared "
2327 "from all the nodes"
2328 )
2329
2330 for data in input_dict_starg:
2331 result = verify_mroutes(
2332 tgen,
2333 data["dut"],
2334 data["src_address"],
2335 IGMP_JOIN_RANGE_1,
2336 data["iif_r1_r2"],
2337 data["oil"],
2338 expected=False,
2339 )
2340 assert (
2341 result is not True
2342 ), "Testcase {} : Failed " " mroute are still present \n Error: {}".format(
2343 tc_name, result
2344 )
2345
2346 for data in input_dict_sg:
2347 result = verify_mroutes(
2348 tgen,
2349 data["dut"],
2350 data["src_address"],
2351 IGMP_JOIN_RANGE_1,
2352 data["iif"],
2353 data["oil"],
2354 expected=False,
2355 )
2356 assert (
2357 result is not True
2358 ), "Testcase {} : Failed " " mroute are still present \n Error: {}".format(
2359 tc_name, result
2360 )
2361
2362 step(
2363 "After sending joins verify (*,G) and (S,G) entries got populated "
2364 "again correct OIL and IIF info (any of the link of R2 or R3) verify "
2365 "using 'show ip mroute json'"
2366 )
2367
2368 for recvr, recvr_intf in input_join.items():
2369 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2370 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2371
2372 for src, src_intf in input_src.items():
2373 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
2374 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2375
2376 for data in input_dict_starg:
2377 result = verify_mroutes(
2378 tgen,
2379 data["dut"],
2380 data["src_address"],
2381 IGMP_JOIN_RANGE_1,
2382 data["iif_r1_r2"],
2383 data["oil"],
2384 )
2385 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2386
2387 for data in input_dict_sg:
2388 result = verify_mroutes(
2389 tgen,
2390 data["dut"],
2391 data["src_address"],
2392 IGMP_JOIN_RANGE_1,
2393 data["iif"],
2394 data["oil"],
2395 )
2396 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2397
2398 step(
2399 "Multicast traffic receiver for all the groups verify using "
2400 "'show ip multicast count'"
2401 )
2402
2403 input_traffic = {
2404 "r1": {"traffic_sent": [intf_r1_i1]},
2405 "r4": {"traffic_received": [intf_r4_i6]},
2406 }
2407 result = verify_multicast_traffic(tgen, input_traffic)
2408 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2409
2410 write_test_footer(tc_name)
2411
2412
2413 def test_mroutes_updated_after_after_clear_mroute_p1(request):
2414 """
2415 Verify mroute updated correctly after clear mroute
2416 """
2417
2418 tgen = get_topogen()
2419 tc_name = request.node.name
2420 write_test_header(tc_name)
2421
2422 # Creating configuration from JSON
2423 app_helper.stop_all_hosts()
2424 clear_mroute(tgen)
2425 reset_config_on_routers(tgen)
2426 clear_pim_interface_traffic(tgen, topo)
2427
2428 # Don"t run this test if we have any failure.
2429 if tgen.routers_have_failure():
2430 pytest.skip(tgen.errors)
2431
2432 step("Enable IGMP on DUT and R4 interface")
2433 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
2434 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
2435 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
2436 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
2437
2438 result = create_igmp_config(tgen, topo, input_dict)
2439 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2440
2441 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
2442 input_join = {
2443 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
2444 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
2445 }
2446
2447 for recvr, recvr_intf in input_join.items():
2448 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2449 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2450
2451 step("Configure RP as R2 for group range 225.1.1.1-5")
2452
2453 input_dict = {
2454 "r2": {
2455 "pim": {
2456 "rp": [
2457 {
2458 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2459 "/"
2460 )[0],
2461 "group_addr_range": GROUP_RANGE_1,
2462 }
2463 ]
2464 }
2465 }
2466 }
2467
2468 result = create_pim_config(tgen, topo, input_dict)
2469 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2470
2471 step("Done in base config: " "Configure EBGP peering between all the nodes")
2472
2473 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
2474
2475 step("Send traffic from R4 for group range 225.1.1.1-5")
2476 step("Send traffic from DUT for group range 225.1.1.1-5")
2477
2478 input_src = {
2479 "i6": topo["routers"]["i6"]["links"]["r4"]["interface"],
2480 "i2": topo["routers"]["i2"]["links"]["r1"]["interface"],
2481 }
2482
2483 for src, src_intf in input_src.items():
2484 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
2485 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2486
2487 step("(*,G) IIF and OIL updated on both the nodes")
2488
2489 input_dict_starg = [
2490 {
2491 "dut": "r1",
2492 "src_address": "*",
2493 "iif_r1_r2": r1_r2_links + r1_r3_links,
2494 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2495 },
2496 {
2497 "dut": "r4",
2498 "src_address": "*",
2499 "iif_r1_r2": r4_r2_links + r4_r3_links,
2500 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2501 },
2502 ]
2503
2504 for data in input_dict_starg:
2505 result = verify_mroutes(
2506 tgen,
2507 data["dut"],
2508 data["src_address"],
2509 IGMP_JOIN_RANGE_1,
2510 data["iif_r1_r2"],
2511 data["oil"],
2512 )
2513 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2514
2515 result = verify_upstream_iif(
2516 tgen, data["dut"], data["iif_r1_r2"], data["src_address"], IGMP_JOIN_RANGE_1
2517 )
2518 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2519
2520 step(
2521 "(S,G) IIF updated towards shortest path to source on both the nodes "
2522 ", verify using 'show ip mroute' and 'show ip mroute json'"
2523 )
2524
2525 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
2526 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
2527 input_dict_sg = [
2528 {
2529 "dut": "r1",
2530 "src_address": source_i6,
2531 "iif": r1_r2_links + r1_r3_links,
2532 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2533 },
2534 {
2535 "dut": "r1",
2536 "src_address": source_i2,
2537 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
2538 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2539 },
2540 {
2541 "dut": "r4",
2542 "src_address": source_i6,
2543 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
2544 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2545 },
2546 {
2547 "dut": "r4",
2548 "src_address": source_i2,
2549 "iif": r4_r2_links + r4_r3_links,
2550 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2551 },
2552 ]
2553
2554 for data in input_dict_sg:
2555 result = verify_mroutes(
2556 tgen,
2557 data["dut"],
2558 data["src_address"],
2559 IGMP_JOIN_RANGE_1,
2560 data["iif"],
2561 data["oil"],
2562 )
2563 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2564
2565 step(
2566 "OIL is updated and traffic is received for all the groups on both "
2567 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
2568 )
2569
2570 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
2571 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
2572 input_traffic = {
2573 "r1": {"traffic_sent": [intf_r1_i1]},
2574 "r4": {"traffic_received": [intf_r4_i6]},
2575 }
2576 result = verify_multicast_traffic(tgen, input_traffic)
2577 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2578
2579 step("Clear ip mroute from DUT")
2580 clear_mroute(tgen, "r1")
2581
2582 step("Clear ip mroute from r4")
2583 clear_mroute(tgen, "r4")
2584
2585 step(
2586 "Multicast traffic receiver for all the groups verify using "
2587 "'show ip multicast count'"
2588 )
2589
2590 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
2591 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
2592 input_traffic = {
2593 "r1": {"traffic_sent": [intf_r1_i1]},
2594 "r4": {"traffic_received": [intf_r4_i6]},
2595 }
2596 result = verify_multicast_traffic(tgen, input_traffic)
2597 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2598
2599 write_test_footer(tc_name)
2600
2601
2602 def test_mroutes_updated_after_changing_rp_config_p1(request):
2603 """
2604 Verify (*,G) mroute entries after changing the RP configuration
2605 """
2606
2607 tgen = get_topogen()
2608 tc_name = request.node.name
2609 write_test_header(tc_name)
2610
2611 # Creating configuration from JSON
2612 app_helper.stop_all_hosts()
2613 clear_mroute(tgen)
2614 reset_config_on_routers(tgen)
2615 clear_pim_interface_traffic(tgen, topo)
2616
2617 # Don"t run this test if we have any failure.
2618 if tgen.routers_have_failure():
2619 pytest.skip(tgen.errors)
2620
2621 step("Unconfigure BGP from all nodes as using static routes")
2622
2623 input_dict = {}
2624 DUT = ["r1", "r2", "r3", "r4"]
2625 ASN = [100, 200, 300, 400]
2626 for dut, asn in zip(DUT, ASN):
2627 temp = {dut: {"bgp": {}}}
2628 input_dict.update(temp)
2629
2630 temp[dut]["bgp"].update({"local_as": asn, "delete": True})
2631
2632 result = create_router_bgp(tgen, topo, input_dict)
2633 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
2634
2635 step("Enable IGMP on DUT and R4 interface")
2636 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
2637 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
2638 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
2639 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
2640
2641 result = create_igmp_config(tgen, topo, input_dict)
2642 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2643
2644 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
2645 input_join = {
2646 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
2647 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
2648 }
2649
2650 for recvr, recvr_intf in input_join.items():
2651 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2652 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2653
2654 step("Configure RP as R2 for group range 225.1.1.1-5")
2655
2656 input_dict = {
2657 "r2": {
2658 "pim": {
2659 "rp": [
2660 {
2661 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2662 "/"
2663 )[0],
2664 "group_addr_range": GROUP_RANGE_1,
2665 }
2666 ]
2667 }
2668 }
2669 }
2670
2671 result = create_pim_config(tgen, topo, input_dict)
2672 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2673
2674 step("Configure static routes between nodes for making RP and source" "reachable")
2675
2676 configure_static_routes_for_rp_reachability(tgen, topo)
2677
2678 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
2679
2680 step("Send traffic from R4 for group range 225.1.1.1-5")
2681 step("Send traffic from DUT for group range 225.1.1.1-5")
2682
2683 input_src = {
2684 "i6": topo["routers"]["i6"]["links"]["r4"]["interface"],
2685 "i2": topo["routers"]["i2"]["links"]["r1"]["interface"],
2686 }
2687
2688 for src, src_intf in input_src.items():
2689 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
2690 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2691
2692 step("(*,G) IIF and OIL updated on both the nodes")
2693
2694 step(
2695 "(S,G) IIF updated towards shortest path to source on both the nodes "
2696 ", verify using 'show ip mroute' and 'show ip mroute json'"
2697 )
2698
2699 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
2700 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
2701 input_dict_star_sg = [
2702 {
2703 "dut": "r1",
2704 "src_address": "*",
2705 "iif": r1_r2_links + r1_r3_links,
2706 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2707 },
2708 {
2709 "dut": "r4",
2710 "src_address": "*",
2711 "iif": r4_r2_links + r4_r3_links,
2712 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2713 },
2714 {
2715 "dut": "r1",
2716 "src_address": source_i6,
2717 "iif": r1_r2_links + r1_r3_links,
2718 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2719 },
2720 {
2721 "dut": "r1",
2722 "src_address": source_i2,
2723 "iif": topo["routers"]["r1"]["links"]["i2"]["interface"],
2724 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2725 },
2726 {
2727 "dut": "r4",
2728 "src_address": source_i6,
2729 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
2730 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2731 },
2732 {
2733 "dut": "r4",
2734 "src_address": source_i2,
2735 "iif": r4_r2_links + r4_r3_links,
2736 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
2737 },
2738 ]
2739
2740 for data in input_dict_star_sg:
2741 result = verify_mroutes(
2742 tgen,
2743 data["dut"],
2744 data["src_address"],
2745 IGMP_JOIN_RANGE_1,
2746 data["iif"],
2747 data["oil"],
2748 )
2749 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2750
2751 step(
2752 "OIL is updated and traffic is received for all the groups on both "
2753 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
2754 )
2755
2756 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
2757 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
2758 input_traffic = {
2759 "r1": {"traffic_sent": [intf_r1_i1]},
2760 "r4": {"traffic_received": [intf_r4_i6]},
2761 }
2762 result = verify_multicast_traffic(tgen, input_traffic)
2763 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2764
2765 step(
2766 "Verify RP has (S,G) with none OIL or Upstream should be present using 'show ip mroute json'"
2767 " 'show ip pim upstream json'"
2768 )
2769
2770 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
2771 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
2772 input_dict_star_sg = [
2773 {"dut": "r2", "src_address": source_i2, "iif": r2_r1_links, "oil": r2_r4_links},
2774 {"dut": "r2", "src_address": source_i6, "iif": r2_r4_links, "oil": r2_r1_links},
2775 ]
2776
2777 for data in input_dict_star_sg:
2778 result = verify_mroutes(
2779 tgen,
2780 data["dut"],
2781 data["src_address"],
2782 IGMP_JOIN_RANGE_1,
2783 data["iif"],
2784 data["oil"],
2785 )
2786 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2787
2788 result = verify_upstream_iif(
2789 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
2790 )
2791 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2792
2793 step("Verify pim interface traffic before changing RP")
2794
2795 intf_traffic = topo["routers"]["r4"]["links"]["r3-link1"]["interface"]
2796 state_dict = {"r4": {intf_traffic: ["registerStopRx"]}}
2797 state_before = verify_pim_interface_traffic(tgen, state_dict)
2798 assert isinstance(
2799 state_before, dict
2800 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
2801 tc_name, result
2802 )
2803
2804 step("Change the RP to R3 loopback for same group range (225.1.1.1-5)")
2805
2806 input_dict = {
2807 "r2": {
2808 "pim": {
2809 "rp": [
2810 {
2811 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2812 "/"
2813 )[0],
2814 "group_addr_range": GROUP_RANGE_1,
2815 "delete": True,
2816 }
2817 ]
2818 }
2819 },
2820 "r3": {
2821 "pim": {
2822 "rp": [
2823 {
2824 "rp_addr": topo["routers"]["r3"]["links"]["lo"]["ipv4"].split(
2825 "/"
2826 )[0],
2827 "group_addr_range": GROUP_RANGE_1 + GROUP_RANGE_2,
2828 }
2829 ]
2830 }
2831 },
2832 }
2833
2834 result = create_pim_config(tgen, topo, input_dict)
2835 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2836
2837 step(
2838 "After changing the RP to R3 , verify (S,G) with none OIL and "
2839 "upstream got cleared from R2 and created on R3 verify using "
2840 "'show ip mroute json'; 'show ip pim upstream json'"
2841 )
2842
2843 for data in input_dict_star_sg:
2844 if data["src_address"] != "*":
2845 result = verify_mroutes(
2846 tgen,
2847 data["dut"],
2848 data["src_address"],
2849 IGMP_JOIN_RANGE_1,
2850 data["iif"],
2851 data["oil"],
2852 )
2853 assert result is True, "Testcase {} : Failed Error: {}".format(
2854 tc_name, result
2855 )
2856
2857 result = verify_upstream_iif(
2858 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
2859 )
2860 assert result is True, "Testcase {} : Failed Error: {}".format(
2861 tc_name, result
2862 )
2863
2864 step("(*,G) IIF on DUT is changed towards R3, verify using 'show ip mroute json'")
2865
2866 input_dict_star_g = [
2867 {
2868 "dut": "r1",
2869 "src_address": "*",
2870 "iif": r1_r3_links,
2871 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
2872 }
2873 ]
2874
2875 for data in input_dict_star_g:
2876 result = verify_mroutes(
2877 tgen,
2878 data["dut"],
2879 data["src_address"],
2880 IGMP_JOIN_RANGE_1,
2881 data["iif"],
2882 data["oil"],
2883 )
2884 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2885
2886 step(
2887 "R4 is sending null register packets to R3 'show ip pim multicast traffic json'"
2888 )
2889 step("Verify pim interface traffic after changing RP")
2890
2891 state_after = verify_pim_interface_traffic(tgen, state_dict)
2892 assert isinstance(
2893 state_before, dict
2894 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
2895 tc_name, result
2896 )
2897
2898 result = verify_state_incremented(state_before, state_after)
2899 assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
2900
2901 step("Send new IGMP join for new group range (226.1.1.1-5)")
2902
2903 input_join = {
2904 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
2905 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
2906 }
2907
2908 for recvr, recvr_intf in input_join.items():
2909 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_2, join_intf=recvr_intf)
2910 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2911
2912 step("Send traffic from R4 to same group range")
2913
2914 input_src = {
2915 "i6": topo["routers"]["i6"]["links"]["r4"]["interface"],
2916 "i2": topo["routers"]["i2"]["links"]["r1"]["interface"],
2917 }
2918
2919 for src, src_intf in input_src.items():
2920 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_2, bind_intf=src_intf)
2921 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2922
2923 step("(*.G) and (S,G) on LHR for group range (226.1.1.1-5)")
2924 step(
2925 "(*,G) joins sent towards new RP (R3) , mroute created verify using "
2926 "'show ip mroute json'"
2927 )
2928
2929 for data in input_dict_star_sg:
2930 result = verify_mroutes(
2931 tgen,
2932 data["dut"],
2933 data["src_address"],
2934 IGMP_JOIN_RANGE_2,
2935 data["iif"],
2936 data["oil"],
2937 )
2938 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2939
2940 result = verify_upstream_iif(
2941 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_2
2942 )
2943 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2944
2945 step(
2946 "Traffic is received for groups (226.1.1.1-5) , (S,G) mroute updated "
2947 "in DUT and R4 node verify using 'show ip multicast json'"
2948 )
2949
2950 result = verify_multicast_traffic(tgen, input_traffic)
2951 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2952
2953 step("Delete and Add the RP for group range 225.1.1.1-5 on DUT")
2954
2955 input_dict = {
2956 "r3": {
2957 "pim": {
2958 "rp": [
2959 {
2960 "rp_addr": topo["routers"]["r3"]["links"]["lo"]["ipv4"].split(
2961 "/"
2962 )[0],
2963 "group_addr_range": GROUP_RANGE_1,
2964 "delete": True,
2965 }
2966 ]
2967 }
2968 }
2969 }
2970
2971 result = create_pim_config(tgen, topo, input_dict)
2972 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2973
2974 step(
2975 "After delete of RP verify mroute got uninstall from DUT IIF updated as "
2976 "unknown in PIM state using 'show ip mroute' 'show ip pim state json'"
2977 )
2978 step(
2979 "No impact seen to on data path as RP config removed after SPT switchover "
2980 "verify uptime and traffic using 'show ip mroute' 'show ip mroute count json'"
2981 )
2982
2983 for data in input_dict_star_sg:
2984 if data["src_address"] == "*":
2985 result = verify_mroutes(
2986 tgen,
2987 data["dut"],
2988 data["src_address"],
2989 IGMP_JOIN_RANGE_1,
2990 data["iif"],
2991 data["oil"],
2992 expected=False,
2993 )
2994 assert result is not True, (
2995 "Testcase {} : Failed "
2996 "(*,G) entried are still present \n Error: {}".format(tc_name, result)
2997 )
2998
2999 else:
3000 result = verify_mroutes(
3001 tgen,
3002 data["dut"],
3003 data["src_address"],
3004 IGMP_JOIN_RANGE_1,
3005 data["iif"],
3006 data["oil"],
3007 )
3008 assert result is True, "Testcase {} : Failed Error: {}".format(
3009 tc_name, result
3010 )
3011
3012 iif = topo["routers"]["r1"]["links"]["i2"]["interface"]
3013 oil = topo["routers"]["r1"]["links"]["i1"]["interface"]
3014 result = verify_pim_state(tgen, "r1", iif, oil, IGMP_JOIN_RANGE_1, expected=False)
3015 assert result is not True, (
3016 "Testcase {} :Failed "
3017 "PIM state is not unknown after deleting RP \n Error: {}".format(
3018 tc_name, result
3019 )
3020 )
3021
3022 input_dict = {
3023 "r3": {
3024 "pim": {
3025 "rp": [
3026 {
3027 "rp_addr": topo["routers"]["r3"]["links"]["lo"]["ipv4"].split(
3028 "/"
3029 )[0],
3030 "group_addr_range": GROUP_RANGE_1,
3031 }
3032 ]
3033 }
3034 }
3035 }
3036
3037 result = create_pim_config(tgen, topo, input_dict)
3038 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3039
3040 step(
3041 "After Adding the RP verify IIF updated again towards RP , and DUT"
3042 " sending register packets towards RP, verify using 'show ip mroute'"
3043 " and 'show ip pim int traffic'"
3044 )
3045 step(
3046 "No impact seen to on data path as RP config removed after SPT "
3047 "switchover verify uptime and traffic using 'show ip mroute' "
3048 "'show ip mroute count json'"
3049 )
3050
3051 for data in input_dict_star_sg:
3052 result = verify_mroutes(
3053 tgen,
3054 data["dut"],
3055 data["src_address"],
3056 IGMP_JOIN_RANGE_1,
3057 data["iif"],
3058 data["oil"],
3059 )
3060 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3061
3062 result = verify_multicast_traffic(tgen, input_traffic)
3063 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3064
3065 write_test_footer(tc_name)
3066
3067
3068 def test_mroutes_after_restart_frr_services_p2(request):
3069 """
3070 Verify mroute entries after FRR service stop and start
3071 """
3072
3073 tgen = get_topogen()
3074 tc_name = request.node.name
3075 write_test_header(tc_name)
3076
3077 # Creating configuration from JSON
3078 app_helper.stop_all_hosts()
3079 clear_mroute(tgen)
3080 reset_config_on_routers(tgen)
3081 clear_pim_interface_traffic(tgen, topo)
3082
3083 # Don"t run this test if we have any failure.
3084 if tgen.routers_have_failure():
3085 pytest.skip(tgen.errors)
3086
3087 step("Enable IGMP on DUT and R4 interface")
3088 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
3089 intf_r4_i7 = topo["routers"]["r4"]["links"]["i7"]["interface"]
3090 for dut, intf in zip(["r1", "r4"], [intf_r1_i1, intf_r4_i7]):
3091 input_dict = {dut: {"igmp": {"interfaces": {intf: {"igmp": {"version": "2"}}}}}}
3092
3093 result = create_igmp_config(tgen, topo, input_dict)
3094 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3095
3096 step("Send IGMP joins from DUT and R4 for group range 225.1.1.1-5")
3097 input_join = {
3098 "i1": topo["routers"]["i1"]["links"]["r1"]["interface"],
3099 "i7": topo["routers"]["i7"]["links"]["r4"]["interface"],
3100 }
3101
3102 for recvr, recvr_intf in input_join.items():
3103 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
3104 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3105
3106 step("Configure RP as R2 for group range 225.1.1.1-5")
3107
3108 input_dict = {
3109 "r2": {
3110 "pim": {
3111 "rp": [
3112 {
3113 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
3114 "/"
3115 )[0],
3116 "group_addr_range": GROUP_RANGE_1,
3117 }
3118 ]
3119 }
3120 }
3121 }
3122
3123 result = create_pim_config(tgen, topo, input_dict)
3124 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3125
3126 step("Done in base config: " "Configure EBGP peering between all the nodes")
3127
3128 step("Done in base config: " "Enable PIM on all the interfaces of all the nodes")
3129
3130 step("Send traffic from R4 for group range 225.1.1.1-5")
3131
3132 result = app_helper.run_traffic("i6", IGMP_JOIN_RANGE_1, "r4")
3133 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3134
3135 step("Send traffic from DUT for group range 225.1.1.1-5")
3136
3137 result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "r1")
3138 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3139
3140 step("(*,G) IIF and OIL updated on both the nodes")
3141
3142 step(
3143 "(S,G) IIF updated towards shortest path to source on both the nodes "
3144 ", verify using 'show ip mroute' and 'show ip mroute json'"
3145 )
3146
3147 source_i6 = topo["routers"]["i6"]["links"]["r4"]["ipv4"].split("/")[0]
3148 source_i2 = topo["routers"]["i2"]["links"]["r1"]["ipv4"].split("/")[0]
3149 input_dict_star_sg = [
3150 {
3151 "dut": "r1",
3152 "src_address": "*",
3153 "iif": r1_r2_links + r1_r3_links,
3154 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
3155 },
3156 {
3157 "dut": "r4",
3158 "src_address": "*",
3159 "iif": r4_r2_links + r4_r3_links,
3160 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
3161 },
3162 {
3163 "dut": "r1",
3164 "src_address": source_i6,
3165 "iif": r1_r2_links + r1_r3_links,
3166 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
3167 },
3168 {
3169 "dut": "r1",
3170 "src_address": source_i2,
3171 "iif": r1_r2_links + [topo["routers"]["r1"]["links"]["i2"]["interface"]],
3172 "oil": topo["routers"]["r1"]["links"]["i1"]["interface"],
3173 },
3174 {
3175 "dut": "r4",
3176 "src_address": source_i6,
3177 "iif": topo["routers"]["r4"]["links"]["i6"]["interface"],
3178 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
3179 },
3180 {
3181 "dut": "r4",
3182 "src_address": source_i2,
3183 "iif": r4_r2_links + r4_r3_links,
3184 "oil": topo["routers"]["r4"]["links"]["i7"]["interface"],
3185 },
3186 ]
3187
3188 for data in input_dict_star_sg:
3189 result = verify_mroutes(
3190 tgen,
3191 data["dut"],
3192 data["src_address"],
3193 IGMP_JOIN_RANGE_1,
3194 data["iif"],
3195 data["oil"],
3196 )
3197 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3198
3199 step(
3200 "OIL is updated and traffic is received for all the groups on both "
3201 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
3202 )
3203
3204 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
3205 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
3206 input_traffic = {
3207 "r1": {"traffic_sent": [intf_r1_i1]},
3208 "r4": {"traffic_received": [intf_r4_i6]},
3209 }
3210 result = verify_multicast_traffic(tgen, input_traffic)
3211 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3212
3213 step("Stop the FRR services using kill -9 pid(s) from DUT")
3214 stop_router(tgen, "r1")
3215
3216 step("Start the FRR services from DUT")
3217 start_router(tgen, "r1")
3218
3219 step("(*,G) IIF and OIL updated on both the nodes")
3220
3221 for data in input_dict_star_sg:
3222 if data["src_address"] == "*":
3223 result = verify_mroutes(
3224 tgen,
3225 data["dut"],
3226 data["src_address"],
3227 IGMP_JOIN_RANGE_1,
3228 data["iif"],
3229 data["oil"],
3230 )
3231 assert result is True, "Testcase {} : Failed Error: {}".format(
3232 tc_name, result
3233 )
3234
3235 step(
3236 "(S,G) IIF updated towards shortest path to source on both the nodes "
3237 ", verify using 'show ip mroute' and 'show ip mroute json'"
3238 )
3239
3240 for data in input_dict_star_sg:
3241 if data["src_address"] != "*":
3242 result = verify_mroutes(
3243 tgen,
3244 data["dut"],
3245 data["src_address"],
3246 IGMP_JOIN_RANGE_1,
3247 data["iif"],
3248 data["oil"],
3249 )
3250 assert result is True, "Testcase {} : Failed Error: {}".format(
3251 tc_name, result
3252 )
3253
3254 step(
3255 "OIL is updated and traffic is received for all the groups on both "
3256 "the nodes , verify using 'show ip multicast'; 'show ip multicast json'"
3257 )
3258
3259 intf_r4_i6 = topo["routers"]["r4"]["links"]["i6"]["interface"]
3260 intf_r1_i1 = topo["routers"]["r1"]["links"]["i1"]["interface"]
3261 input_traffic = {
3262 "r1": {"traffic_sent": [intf_r1_i1]},
3263 "r4": {"traffic_received": [intf_r4_i6]},
3264 }
3265 result = verify_multicast_traffic(tgen, input_traffic)
3266 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3267
3268 step("Stop the traffic and do frr services stop/start")
3269 app_helper.stop_all_hosts()
3270
3271 stop_router(tgen, "r1")
3272 start_router(tgen, "r1")
3273
3274 step(
3275 "FRR services started with new PID , (S,G) not present "
3276 "on DUT and R4 , verify using 'show ip mroute json'"
3277 )
3278
3279 for data in input_dict_star_sg:
3280 if data["src_address"] != "*":
3281 result = verify_mroutes(
3282 tgen,
3283 data["dut"],
3284 data["src_address"],
3285 IGMP_JOIN_RANGE_1,
3286 data["iif"],
3287 data["oil"],
3288 expected=False,
3289 )
3290 assert (
3291 result is not True
3292 ), "Testcase {}: Failed " "mroutes are still present \n Error: {}".format(
3293 tc_name, result
3294 )
3295
3296 step("Stop FRR on R4 node")
3297
3298 stop_router(tgen, "r4")
3299
3300 step(
3301 "After stop of FRR on R4 node verify mroute on DUT should be "
3302 "pimreg/prune state"
3303 )
3304 step("No OIL created toward R2 on R11 node")
3305
3306 for data in input_dict_star_sg:
3307 result = verify_mroutes(
3308 tgen,
3309 data["dut"],
3310 data["src_address"],
3311 IGMP_JOIN_RANGE_1,
3312 data["iif"],
3313 data["oil"],
3314 expected=False,
3315 )
3316 assert (
3317 result is not True
3318 ), "Testcase {} : Failed " " Mroutes are still present \n Error: {}".format(
3319 tc_name, result
3320 )
3321
3322 step("Start FRR on R4 node")
3323
3324 start_router(tgen, "r4")
3325
3326 write_test_footer(tc_name)
3327
3328
3329 if __name__ == "__main__":
3330 args = ["-s"] + sys.argv[1:]
3331 sys.exit(pytest.main(args))