]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / tests / topotests / multicast_pim_sm_topo3 / test_multicast_pim_sm_topo3.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2020 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 sm:
25
26 Test steps
27 - Create topology (setup module)
28 - Bring up topology
29
30 Following tests are covered:
31
32 1. verify oil when join prune sent scenario_1 p0
33 2. verify oil when join prune sent scenario_2 p0
34 3. shut noshut source interface when upstream cleared from LHR p0(
35 4. shut noshut receiver interface when upstream cleared from LHR p0(
36 5. verify igmp clis p0
37 6. verify igmp cli generate query once p0
38 7. verify remove add igmp config to receiver interface p0
39 8. verify remove add igmp commands when pim configured p0
40 9. verify remove add pim commands when igmp configured p0
41 10. pim dr priority p0
42 11. pim hello timer p0
43 12. Verify mroute after removing RP sending IGMP prune p2
44 13. Verify prune is sent to LHR and FHR when PIM nbr went down
45 14. Verify mroute flag in LHR and FHR node
46 15. Verify IGMP prune processed correctly when same join received from IGMP and PIM
47 16. Verify multicast traffic flowing fine, when LHR connected to RP
48 17. Verify multicast traffic is flowing fine when FHR is connected to RP
49 """
50
51 import os
52 import re
53 import sys
54 import time
55 import datetime
56 import pytest
57 from time import sleep
58
59 pytestmark = pytest.mark.pimd
60
61 # Save the Current Working Directory to find configuration files.
62 CWD = os.path.dirname(os.path.realpath(__file__))
63 sys.path.append(os.path.join(CWD, "../"))
64 sys.path.append(os.path.join(CWD, "../lib/"))
65
66 # Required to instantiate the topology builder class.
67
68 # pylint: disable=C0413
69 # Import topogen and topotest helpers
70 from lib.topogen import Topogen, get_topogen
71
72 from lib.common_config import (
73 start_topology,
74 write_test_header,
75 write_test_footer,
76 step,
77 reset_config_on_routers,
78 shutdown_bringup_interface,
79 apply_raw_config,
80 check_router_status,
81 required_linux_kernel_version,
82 topo_daemons,
83 )
84 from lib.pim import (
85 create_pim_config,
86 create_igmp_config,
87 verify_igmp_groups,
88 verify_mroutes,
89 clear_mroute,
90 clear_pim_interface_traffic,
91 verify_igmp_config,
92 verify_pim_config,
93 verify_pim_interface,
94 verify_upstream_iif,
95 verify_multicast_traffic,
96 verify_pim_rp_info,
97 verify_multicast_flag_state,
98 McastTesterHelper,
99 verify_pim_interface_traffic,
100 )
101 from lib.topolog import logger
102 from lib.topojson import build_config_from_json
103
104 CWD = os.path.dirname(os.path.realpath(__file__))
105 pytestmark = pytest.mark.pimd
106
107 TOPOLOGY = """
108
109 i4-----c1-------------c2---i5
110 | |
111 | |
112 i1-----l1------r2-----f1---i2
113 | | | |
114 | | | |
115 i7 i6 i3 i8
116
117 Description:
118 i1, i2, i3. i4, i5, i6, i7, i8 - FRR running iperf to send IGMP
119 join and traffic
120 l1 - LHR
121 f1 - FHR
122 r2 - FRR router
123 c1 - FRR router
124 c2 - FRR router
125 """
126
127 # Global variables
128 VLAN_1 = 2501
129 GROUP_RANGE = "225.0.0.0/8"
130 IGMP_GROUP = "225.1.1.1/32"
131 IGMP_JOIN = "225.1.1.1"
132 VLAN_INTF_ADRESS_1 = "10.0.8.3/24"
133 GROUP_RANGE_1 = [
134 "225.1.1.1/32",
135 "225.1.1.2/32",
136 "225.1.1.3/32",
137 "225.1.1.4/32",
138 "225.1.1.5/32",
139 ]
140 IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
141 GROUP_RANGE_2 = [
142 "226.1.1.1/32",
143 "226.1.1.2/32",
144 "226.1.1.3/32",
145 "226.1.1.4/32",
146 "226.1.1.5/32",
147 ]
148 IGMP_JOIN_RANGE_2 = ["226.1.1.1", "226.1.1.2", "226.1.1.3", "226.1.1.4", "226.1.1.5"]
149 GROUP_RANGE_3 = [
150 "227.1.1.1/32",
151 "227.1.1.2/32",
152 "227.1.1.3/32",
153 "227.1.1.4/32",
154 "227.1.1.5/32",
155 ]
156 IGMP_JOIN_RANGE_3 = ["227.1.1.1", "227.1.1.2", "227.1.1.3", "227.1.1.4", "227.1.1.5"]
157
158 SAME_VLAN_IP_1 = {"ip": "10.1.1.1", "subnet": "255.255.255.0", "cidr": "24"}
159 SAME_VLAN_IP_2 = {"ip": "10.1.1.2", "subnet": "255.255.255.0", "cidr": "24"}
160 SAME_VLAN_IP_3 = {"ip": "10.1.1.3", "subnet": "255.255.255.0", "cidr": "24"}
161 SAME_VLAN_IP_4 = {"ip": "10.1.1.4", "subnet": "255.255.255.0", "cidr": "24"}
162
163
164 def setup_module(mod):
165 """
166 Sets up the pytest environment
167
168 * `mod`: module name
169 """
170
171 # Required linux kernel version for this suite to run.
172 result = required_linux_kernel_version("4.19")
173 if result is not True:
174 pytest.skip("Kernel version should be >= 4.19")
175
176 testsuite_run_time = time.asctime(time.localtime(time.time()))
177 logger.info("Testsuite start time: {}".format(testsuite_run_time))
178 logger.info("=" * 40)
179 logger.info("Master Topology: \n {}".format(TOPOLOGY))
180
181 logger.info("Running setup_module to create topology")
182
183 json_file = "{}/multicast_pim_sm_topo3.json".format(CWD)
184 tgen = Topogen(json_file, mod.__name__)
185 global topo
186 topo = tgen.json_topo
187 # ... and here it calls Mininet initialization functions.
188
189 # Starting topology, create tmp files which are loaded to routers
190 # to start daemons and then start routers
191 start_topology(tgen)
192
193 # Don"t run this test if we have any failure.
194 if tgen.routers_have_failure():
195 pytest.skip(tgen.errors)
196
197 # Creating configuration from JSON
198 build_config_from_json(tgen, topo)
199
200 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
201 global app_helper
202 app_helper = McastTesterHelper(tgen)
203
204 logger.info("Running setup_module() done")
205
206
207 def teardown_module():
208 """Teardown the pytest environment"""
209
210 logger.info("Running teardown_module to delete topology")
211
212 tgen = get_topogen()
213
214 app_helper.cleanup()
215
216 # Stop toplogy and Remove tmp files
217 tgen.stop_topology()
218
219 logger.info(
220 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
221 )
222 logger.info("=" * 40)
223
224
225 #####################################################
226 #
227 # Testcases
228 #
229 #####################################################
230
231
232 def verify_mroute_repopulated(uptime_before, uptime_after):
233 """
234 API to compare uptime for mroutes
235
236 Parameters
237 ----------
238 * `uptime_before` : Uptime dictionary for any particular instance
239 * `uptime_after` : Uptime dictionary for any particular instance
240 """
241
242 for group in uptime_before.keys():
243 for source in uptime_before[group].keys():
244 if set(uptime_before[group]) != set(uptime_after[group]):
245 errormsg = (
246 "mroute (%s, %s) has not come"
247 " up after mroute clear [FAILED!!]" % (source, group)
248 )
249 return errormsg
250
251 d1 = datetime.datetime.strptime(uptime_before[group][source], "%H:%M:%S")
252 d2 = datetime.datetime.strptime(uptime_after[group][source], "%H:%M:%S")
253 if d2 >= d1:
254 errormsg = "mroute (%s, %s) is not " "repopulated [FAILED!!]" % (
255 source,
256 group,
257 )
258 return errormsg
259
260 logger.info("mroute (%s, %s) is " "repopulated [PASSED!!]", source, group)
261
262 return True
263
264
265 def verify_state_incremented(state_before, state_after):
266 """
267 API to compare interface traffic state incrementing
268
269 Parameters
270 ----------
271 * `state_before` : State dictionary for any particular instance
272 * `state_after` : State dictionary for any particular instance
273 """
274
275 for ttype, v1 in state_before.items():
276 for intf, v2 in v1.items():
277 for state, value in v2.items():
278 if value >= state_after[ttype][intf][state]:
279 errormsg = "[DUT: %s]: state %s value has not incremented, Initial value: %s, Current value: %s [FAILED!!]" % (
280 intf,
281 state,
282 value,
283 state_after[ttype][intf][state],
284 )
285 return errormsg
286
287 logger.info(
288 "[DUT: %s]: State %s value is incremented, Initial value: %s, Current value: %s [PASSED!!]",
289 intf,
290 state,
291 value,
292 state_after[ttype][intf][state],
293 )
294
295 return True
296
297
298 def find_v2_query_msg_in_tcpdump(tgen, router, message, count, cap_file):
299 """
300 Find v2 query messages in tcpdump file
301
302 Parameters
303 ----------
304 * `tgen` : Topology handler
305 * `router` : Device under test
306 * `cap_file` : tcp dump file name
307
308 """
309
310 filepath = os.path.join(tgen.logdir, router, cap_file)
311 with open(filepath) as f:
312 if len(re.findall("{}".format(message), f.read())) < count:
313 errormsg = "[DUT: %s]: Verify Message: %s in tcpdump" " [FAILED!!]" % (
314 router,
315 message,
316 )
317 return errormsg
318
319 logger.info(
320 "[DUT: %s]: Found message: %s in tcpdump " " count: %s [PASSED!!]",
321 router,
322 message,
323 count,
324 )
325 return True
326
327
328 def find_tos_in_tcpdump(tgen, router, message, cap_file):
329 """
330 Find v2 query messages in tcpdump file
331
332 Parameters
333 ----------
334 * `tgen` : Topology handler
335 * `router` : Device under test
336 * `cap_file` : tcp dump file name
337
338 """
339
340 filepath = os.path.join(tgen.logdir, router, cap_file)
341 with open(filepath) as f:
342
343 if len(re.findall(message, f.read())) < 1:
344 errormsg = "[DUT: %s]: Verify Message: %s in tcpdump" " [FAILED!!]" % (
345 router,
346 message,
347 )
348 return errormsg
349
350 logger.info(
351 "[DUT: %s]: Found message: %s in tcpdump " "[PASSED!!]", router, message
352 )
353 return True
354
355
356 def verify_pim_stats_increament(stats_before, stats_after):
357 """
358 API to compare pim interface control plane traffic
359
360 Parameters
361 ----------
362 * `stats_before` : Stats dictionary for any particular instance
363 * `stats_after` : Stats dictionary for any particular instance
364 """
365
366 for router, stats_data in stats_before.items():
367 for stats, value in stats_data.items():
368 if stats_before[router][stats] >= stats_after[router][stats]:
369 errormsg = (
370 "[DUT: %s]: state %s value has not"
371 " incremented, Initial value: %s, "
372 "Current value: %s [FAILED!!]"
373 % (
374 router,
375 stats,
376 stats_before[router][stats],
377 stats_after[router][stats],
378 )
379 )
380 return errormsg
381
382 logger.info(
383 "[DUT: %s]: State %s value is "
384 "incremented, Initial value: %s, Current value: %s"
385 " [PASSED!!]",
386 router,
387 stats,
388 stats_before[router][stats],
389 stats_after[router][stats],
390 )
391
392 return True
393
394
395 def test_verify_oil_when_join_prune_sent_scenario_1_p1(request):
396 """
397 TC_21_1:
398 Verify OIL detail updated in (S,G) and (*,G) mroute when IGMP
399 join/prune is sent
400 """
401
402 tgen = get_topogen()
403 tc_name = request.node.name
404 write_test_header(tc_name)
405
406 # Don"t run this test if we have any failure.
407 if tgen.routers_have_failure():
408 pytest.skip(tgen.errors)
409
410 # Creating configuration from JSON
411 app_helper.stop_all_hosts()
412 clear_mroute(tgen)
413 reset_config_on_routers(tgen)
414 clear_pim_interface_traffic(tgen, topo)
415 check_router_status(tgen)
416
417 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
418 step(
419 "Enable IGMP of FRR1 interface and send IGMP joins "
420 " from FRR1 node for group range (226.1.1.1-5)"
421 )
422 step(
423 "Enable IGMP of FRR3 interface and send IGMP joins "
424 " from FRR3 node for group range (226.1.1.1-5)"
425 )
426
427 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
428 input_dict = {
429 "f1": {
430 "igmp": {
431 "interfaces": {
432 intf_f1_i8: {
433 "igmp": {"version": "2", "query": {"query-interval": 15}}
434 }
435 }
436 }
437 }
438 }
439 result = create_igmp_config(tgen, topo, input_dict)
440 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
441
442 input_join = {
443 "i1": topo["routers"]["i1"]["links"]["l1"]["interface"],
444 "i8": topo["routers"]["i8"]["links"]["f1"]["interface"],
445 }
446
447 for recvr, recvr_intf in input_join.items():
448 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
449 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
450
451 step("Configure static RP for (226.1.1.1-5) in R2")
452
453 input_dict = {
454 "r2": {
455 "pim": {
456 "rp": [
457 {
458 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
459 "/"
460 )[0],
461 "group_addr_range": GROUP_RANGE,
462 }
463 ]
464 }
465 }
466 }
467
468 result = create_pim_config(tgen, topo, input_dict)
469 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
470
471 step(
472 "Configure one source on FRR3 for all the groups and send" " multicast traffic"
473 )
474
475 input_src = {"i2": topo["routers"]["i2"]["links"]["f1"]["interface"]}
476
477 for src, src_intf in input_src.items():
478 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
479 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
480
481 source_i2 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
482 input_dict_all = [
483 {
484 "dut": "l1",
485 "src_address": "*",
486 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
487 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
488 },
489 {
490 "dut": "l1",
491 "src_address": source_i2,
492 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
493 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
494 },
495 {
496 "dut": "r2",
497 "src_address": "*",
498 "iif": "lo",
499 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
500 },
501 {
502 "dut": "r2",
503 "src_address": source_i2,
504 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
505 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
506 },
507 {
508 "dut": "f1",
509 "src_address": "*",
510 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
511 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
512 },
513 {
514 "dut": "f1",
515 "src_address": source_i2,
516 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
517 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
518 },
519 ]
520
521 step("Verify mroutes and iff upstream")
522
523 for data in input_dict_all:
524 result = verify_mroutes(
525 tgen,
526 data["dut"],
527 data["src_address"],
528 IGMP_JOIN_RANGE_1,
529 data["iif"],
530 data["oil"],
531 )
532 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
533
534 for data in input_dict_all:
535 result = verify_upstream_iif(
536 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
537 )
538 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
539
540 step("Send the IGMP prune from ixia to (226.1.1.1-5) receiver on " "FRR1 node")
541
542 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
543 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, False)
544
545 step(
546 "After receiving the IGMP prune from FRR1 , verify traffic "
547 "immediately stopped for this receiver 'show ip multicast'"
548 )
549
550 input_traffic = {"l1": {"traffic_sent": [intf_l1_i1]}}
551 result = verify_multicast_traffic(tgen, input_traffic, expected=False)
552 assert result is not True, (
553 "Testcase {} : Failed \n "
554 "Expected: [{}]: Multicast traffic should be stopped \n "
555 "Found: {}".format(tc_name, "l1", result)
556 )
557
558 step(
559 "IGMP groups are remove from FRR1 node 'show ip igmp groups'"
560 " FRR3 IGMP still present"
561 )
562
563 dut = "l1"
564 result = verify_igmp_groups(
565 tgen, dut, intf_l1_i1, IGMP_JOIN_RANGE_1, expected=False
566 )
567 assert result is not True, (
568 "Testcase {} : Failed \n "
569 "Expected: [{}]: IGMP groups should be deleted \n "
570 "Found: {}".format(tc_name, dut, result)
571 )
572
573 dut = "f1"
574 result = verify_igmp_groups(tgen, dut, intf_f1_i8, IGMP_JOIN_RANGE_1)
575 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
576
577 step(
578 "(*,G) and (S,G) OIL got removed immediately after receiving"
579 " prune 'show ip pim state' and 'show ip mroute' on FRR1 node,"
580 " no impact on FRR3 receiver"
581 )
582
583 input_dict_l1 = [
584 {
585 "dut": "l1",
586 "src_address": "*",
587 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
588 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
589 },
590 {
591 "dut": "l1",
592 "src_address": source_i2,
593 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
594 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
595 },
596 ]
597
598 step("Verify mroutes and iff upstream")
599
600 for data in input_dict_l1:
601 result = verify_mroutes(
602 tgen,
603 data["dut"],
604 data["src_address"],
605 IGMP_JOIN_RANGE_1,
606 data["iif"],
607 data["oil"],
608 expected=False,
609 )
610 assert result is not True, (
611 "Testcase {} : Failed \n "
612 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
613 "Found: {}".format(tc_name, data["dut"], result)
614 )
615
616 for data in input_dict_l1:
617 result = verify_upstream_iif(
618 tgen,
619 data["dut"],
620 data["iif"],
621 data["src_address"],
622 IGMP_JOIN_RANGE_1,
623 expected=False,
624 )
625 assert result is not True, (
626 "Testcase {} : Failed \n "
627 "Expected: [{}]: Upstream IIF {} should not be present \n "
628 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
629 )
630
631 input_dict_f1 = [
632 {
633 "dut": "f1",
634 "src_address": "*",
635 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
636 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
637 },
638 {
639 "dut": "f1",
640 "src_address": source_i2,
641 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
642 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
643 },
644 ]
645
646 step("Verify mroutes and iff upstream")
647
648 for data in input_dict_f1:
649 result = verify_mroutes(
650 tgen,
651 data["dut"],
652 data["src_address"],
653 IGMP_JOIN_RANGE_1,
654 data["iif"],
655 data["oil"],
656 )
657 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
658
659 for data in input_dict_f1:
660 result = verify_upstream_iif(
661 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
662 )
663 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
664
665 step("Send the IGMP prune from ixia to (226.1.1.1-5) receiver on " " FRR3 node")
666
667 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
668 shutdown_bringup_interface(tgen, "f1", intf_f1_i8, False)
669
670 step(
671 "After receiving the IGMP prune from FRR3s , verify traffic "
672 "immediately stopped for this receiver 'show ip multicast'"
673 )
674
675 input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
676 result = verify_multicast_traffic(tgen, input_traffic, expected=False)
677 assert result is not True, (
678 "Testcase {} : Failed \n "
679 "Expected: [{}]: Multicast traffic should be stopped \n "
680 "Found: {}".format(tc_name, "f1", result)
681 )
682
683 step(
684 "IGMP groups are remove from FRR1 node 'show ip igmp groups'"
685 " FRR3 IGMP still present"
686 )
687
688 dut = "f1"
689 result = verify_igmp_groups(
690 tgen, dut, intf_f1_i8, IGMP_JOIN_RANGE_1, expected=False
691 )
692 assert result is not True, (
693 "Testcase {} : Failed \n "
694 "Expected: [{}]: IGMP groups should be deleted \n "
695 "Found: {}".format(tc_name, dut, result)
696 )
697
698 step(
699 "(*,G) and (S,G) OIL got prune state (none) from all the nodes"
700 "FRR1, FRR3 verify using 'show ip mroute'"
701 )
702
703 input_dict_l1 = [
704 {
705 "dut": "l1",
706 "src_address": "*",
707 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
708 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
709 },
710 {
711 "dut": "l1",
712 "src_address": source_i2,
713 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
714 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
715 },
716 ]
717
718 step("Verify mroutes and iff upstream")
719
720 for data in input_dict_l1:
721 result = verify_mroutes(
722 tgen,
723 data["dut"],
724 data["src_address"],
725 IGMP_JOIN_RANGE_1,
726 data["iif"],
727 data["oil"],
728 expected=False,
729 )
730 assert result is not True, (
731 "Testcase {} : Failed \n "
732 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
733 "Found: {}".format(tc_name, data["dut"], result)
734 )
735
736 for data in input_dict_l1:
737 result = verify_upstream_iif(
738 tgen,
739 data["dut"],
740 data["iif"],
741 data["src_address"],
742 IGMP_JOIN_RANGE_1,
743 expected=False,
744 )
745 assert result is not True, (
746 "Testcase {} : Failed \n "
747 "Expected: [{}]: Upstream IIF {} should not be present \n "
748 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
749 )
750
751 shutdown_bringup_interface(tgen, "f1", intf_f1_i8, True)
752 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, True)
753
754 for data in input_dict_l1:
755 result = verify_upstream_iif(
756 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
757 )
758 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
759
760 write_test_footer(tc_name)
761
762
763 def test_verify_oil_when_join_prune_sent_scenario_2_p1(request):
764 """
765 TC_21_2: Verify OIL detail updated in (S,G) and (*,G) mroute when IGMP
766 join/prune is sent
767 """
768
769 tgen = get_topogen()
770 tc_name = request.node.name
771 write_test_header(tc_name)
772
773 # Don"t run this test if we have any failure.
774 if tgen.routers_have_failure():
775 pytest.skip(tgen.errors)
776
777 # Creating configuration from JSON
778 app_helper.stop_all_hosts()
779 clear_mroute(tgen)
780 reset_config_on_routers(tgen)
781 clear_pim_interface_traffic(tgen, topo)
782 check_router_status(tgen)
783
784 step("Removing FRR3 to simulate topo " "FHR(FRR1)---LHR(FRR2)")
785
786 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
787 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["interface"]
788 intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"]
789 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, False)
790 shutdown_bringup_interface(tgen, "f1", intf_f1_c2, False)
791 shutdown_bringup_interface(tgen, "f1", intf_f1_r2, False)
792
793 step("Enable the PIM on all the interfaces of FRR1, FRR2")
794 step(
795 "Enable IGMP of FRR1 interface and send IGMP joins "
796 " from FRR1 node for group range (226.1.1.1-5)"
797 )
798 step(
799 "Enable IGMP of FRR3 interface and send IGMP joins "
800 " from FRR3 node for group range (226.1.1.1-5)"
801 )
802
803 intf_r2_i3 = topo["routers"]["r2"]["links"]["i3"]["interface"]
804 input_dict = {
805 "r2": {
806 "igmp": {
807 "interfaces": {
808 intf_r2_i3: {
809 "igmp": {"version": "2", "query": {"query-interval": 15}}
810 }
811 }
812 }
813 }
814 }
815 result = create_igmp_config(tgen, topo, input_dict)
816 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
817
818 input_join = {
819 "i1": topo["routers"]["i1"]["links"]["l1"]["interface"],
820 "i3": topo["routers"]["i3"]["links"]["r2"]["interface"],
821 }
822
823 for recvr, recvr_intf in input_join.items():
824 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
825 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
826
827 step("Configure static RP for (226.1.1.1-5) in R2")
828
829 input_dict = {
830 "r2": {
831 "pim": {
832 "rp": [
833 {
834 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
835 "/"
836 )[0],
837 "group_addr_range": GROUP_RANGE,
838 }
839 ]
840 }
841 }
842 }
843
844 result = create_pim_config(tgen, topo, input_dict)
845 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
846 input_dict_all = [
847 {
848 "dut": "l1",
849 "src_address": "*",
850 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
851 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
852 },
853 {
854 "dut": "r2",
855 "src_address": "*",
856 "iif": "lo",
857 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
858 },
859 {
860 "dut": "r2",
861 "src_address": "*",
862 "iif": "lo",
863 "oil": topo["routers"]["r2"]["links"]["i3"]["interface"],
864 },
865 ]
866
867 step("Verify mroutes and iff upstream")
868
869 for data in input_dict_all:
870 result = verify_mroutes(
871 tgen,
872 data["dut"],
873 data["src_address"],
874 IGMP_JOIN_RANGE_1,
875 data["iif"],
876 data["oil"],
877 )
878 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
879
880 for data in input_dict_all:
881 result = verify_upstream_iif(
882 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
883 )
884 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
885
886 step("Send the IGMP prune from ixia to (226.1.1.1-5) receiver on " "FRR3(r2) node")
887
888 intf_r2_i3 = topo["routers"]["r2"]["links"]["i3"]["interface"]
889 shutdown_bringup_interface(tgen, "r2", intf_r2_i3, False)
890
891 step(
892 "After sending IGMP prune from FRR3(r2) node verify (*,G) OIL "
893 "immediately removed for local receiver mroute should have "
894 " PIM protocol , IGMP should be removed verify using "
895 "'show ip mroute' no impact seen on FRR1(l1) (*,G)"
896 )
897
898 input_dict_r2 = [
899 {
900 "dut": "r2",
901 "src_address": "*",
902 "iif": "lo",
903 "oil": topo["routers"]["r2"]["links"]["i3"]["interface"],
904 }
905 ]
906
907 for data in input_dict_r2:
908 result = verify_mroutes(
909 tgen,
910 data["dut"],
911 data["src_address"],
912 IGMP_JOIN_RANGE_1,
913 data["iif"],
914 data["oil"],
915 expected=False,
916 )
917 assert result is not True, (
918 "Testcase {} : Failed \n "
919 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
920 "Found: {}".format(tc_name, data["dut"], result)
921 )
922
923 input_dict_l1_r2 = [
924 {
925 "dut": "l1",
926 "src_address": "*",
927 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
928 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
929 },
930 {
931 "dut": "r2",
932 "src_address": "*",
933 "iif": "lo",
934 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
935 },
936 ]
937
938 step("Verify mroutes and iff upstream")
939
940 for data in input_dict_l1_r2:
941 result = verify_mroutes(
942 tgen,
943 data["dut"],
944 data["src_address"],
945 IGMP_JOIN_RANGE_1,
946 data["iif"],
947 data["oil"],
948 )
949 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
950
951 step("Send the IGMP prune from ixia to (226.1.1.1-5) receiver on " "FRR1(l1) node")
952
953 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
954 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, False)
955
956 step(
957 "After sending IGMP prune from FRR1 node verify (*,G) OIL"
958 "got removed immediately from FRR1 node"
959 )
960
961 input_dict_l1 = [
962 {
963 "dut": "l1",
964 "src_address": "*",
965 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
966 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
967 }
968 ]
969
970 for data in input_dict_l1:
971 result = verify_mroutes(
972 tgen,
973 data["dut"],
974 data["src_address"],
975 IGMP_JOIN_RANGE_1,
976 data["iif"],
977 data["oil"],
978 expected=False,
979 )
980 assert result is not True, (
981 "Testcase {} : Failed \n "
982 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
983 "Found: {}".format(tc_name, data["dut"], result)
984 )
985
986 step("After prune is sent verify upstream got removed in FRR1 node")
987
988 for data in input_dict_l1:
989 result = verify_upstream_iif(
990 tgen,
991 data["dut"],
992 data["iif"],
993 data["src_address"],
994 IGMP_JOIN_RANGE_1,
995 expected=False,
996 )
997 assert result is not True, (
998 "Testcase {} : Failed \n "
999 "Expected: [{}]: Upstream IIF {} should not be present \n "
1000 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
1001 )
1002
1003 write_test_footer(tc_name)
1004
1005
1006 def test_shut_noshut_source_interface_when_upstream_cleared_from_LHR_p1(request):
1007 """
1008 TC_26: Verify shut/no shut of source interface after upstream got cleared
1009 from LHR
1010 """
1011
1012 tgen = get_topogen()
1013 tc_name = request.node.name
1014 write_test_header(tc_name)
1015
1016 # Don"t run this test if we have any failure.
1017 if tgen.routers_have_failure():
1018 pytest.skip(tgen.errors)
1019
1020 # Creating configuration from JSON
1021 app_helper.stop_all_hosts()
1022 clear_mroute(tgen)
1023 reset_config_on_routers(tgen)
1024 clear_pim_interface_traffic(tgen, topo)
1025 check_router_status(tgen)
1026
1027 step("Enable the PIM on all the interfaces of FRR1, R2 and FRR3" " routers")
1028 step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-225.1.1.10)")
1029
1030 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
1031
1032 for recvr, recvr_intf in input_join.items():
1033 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
1034 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1035
1036 step("Configure RP on R2 (loopback interface) for " "the group range 225.0.0.0/8")
1037
1038 input_dict = {
1039 "r2": {
1040 "pim": {
1041 "rp": [
1042 {
1043 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1044 "/"
1045 )[0],
1046 "group_addr_range": GROUP_RANGE_1,
1047 }
1048 ]
1049 }
1050 }
1051 }
1052
1053 result = create_pim_config(tgen, topo, input_dict)
1054 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1055
1056 step("Send multicast traffic from FRR3 to 225.1.1.1-225.1.1.10" " receiver")
1057
1058 input_src = {"i2": topo["routers"]["i2"]["links"]["f1"]["interface"]}
1059
1060 for src, src_intf in input_src.items():
1061 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
1062 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1063
1064 step(
1065 "'show ip mroute' showing correct RPF and OIF interface for (*,G)"
1066 " and (S,G) entries on all the nodes"
1067 )
1068
1069 source_i2 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
1070 input_dict_all = [
1071 {
1072 "dut": "l1",
1073 "src_address": "*",
1074 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1075 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1076 },
1077 {
1078 "dut": "l1",
1079 "src_address": source_i2,
1080 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1081 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1082 },
1083 {
1084 "dut": "r2",
1085 "src_address": "*",
1086 "iif": "lo",
1087 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
1088 },
1089 {
1090 "dut": "r2",
1091 "src_address": source_i2,
1092 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
1093 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
1094 },
1095 {
1096 "dut": "f1",
1097 "src_address": source_i2,
1098 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
1099 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
1100 },
1101 ]
1102
1103 step(
1104 "'show ip pim upstream' and 'show ip pim upstream-rpf' showing"
1105 " correct OIL and IIF on all the nodes"
1106 )
1107
1108 for data in input_dict_all:
1109 result = verify_mroutes(
1110 tgen,
1111 data["dut"],
1112 data["src_address"],
1113 IGMP_JOIN_RANGE_1,
1114 data["iif"],
1115 data["oil"],
1116 )
1117 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1118
1119 for data in input_dict_all:
1120 result = verify_upstream_iif(
1121 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1122 )
1123 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1124
1125 step("Shut the source interface from FRR3")
1126 intf_f1_i2 = topo["routers"]["f1"]["links"]["i2"]["interface"]
1127 shutdown_bringup_interface(tgen, "f1", intf_f1_i2, False)
1128
1129 step(
1130 "After shut of source interface verify (S,G) mroutes are cleared"
1131 " from all the nodes"
1132 )
1133
1134 intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"]
1135 result = verify_mroutes(
1136 tgen, "f1", source_i2, IGMP_JOIN_RANGE_1, intf_f1_i2, intf_f1_r2, expected=False
1137 )
1138 assert result is not True, (
1139 "Testcase {} : Failed \n "
1140 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
1141 "Found: {}".format(tc_name, "f1", result)
1142 )
1143
1144 step(
1145 "After waiting for (S,G) timeout from FRR1 for same"
1146 " source verify that (S,G) is flushed from FRR1 node"
1147 " 'show ip pim upstream' 'show ip mroute' "
1148 )
1149
1150 result = verify_upstream_iif(
1151 tgen, "l1", "Unknown", source_i2, IGMP_JOIN_RANGE_1, expected=False
1152 )
1153 assert result is not True, (
1154 "Testcase {} : Failed \n "
1155 "Expected: [{}]: Upstream IIF should be Unknown \n "
1156 "Found: {}".format(tc_name, "l1", result)
1157 )
1158
1159 step("No shut the Source interface just after the upstream is expired" " from FRR1")
1160 shutdown_bringup_interface(tgen, "f1", intf_f1_i2, True)
1161
1162 step(
1163 "After no shut of source interface , verify all the (S,G) is "
1164 " populated again on 'show ip mroute' 'show ip pim upstream' "
1165 " with proper OIL and IIF detail"
1166 )
1167
1168 for data in input_dict_all:
1169 result = verify_mroutes(
1170 tgen,
1171 data["dut"],
1172 data["src_address"],
1173 IGMP_JOIN_RANGE_1,
1174 data["iif"],
1175 data["oil"],
1176 )
1177 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1178
1179 for data in input_dict_all:
1180 result = verify_upstream_iif(
1181 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1182 )
1183 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1184
1185 step("shut and no shut the source interface immediately")
1186 shutdown_bringup_interface(tgen, "f1", intf_f1_i2, False)
1187 shutdown_bringup_interface(tgen, "f1", intf_f1_i2, True)
1188
1189 step(
1190 "All the mroutes got updated with proper OIL after no shut of"
1191 "interface verify using 'show ip mroute'"
1192 )
1193
1194 for data in input_dict_all:
1195 result = verify_mroutes(
1196 tgen,
1197 data["dut"],
1198 data["src_address"],
1199 IGMP_JOIN_RANGE_1,
1200 data["iif"],
1201 data["oil"],
1202 )
1203 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1204
1205 for data in input_dict_all:
1206 result = verify_upstream_iif(
1207 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1208 )
1209 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1210
1211 write_test_footer(tc_name)
1212
1213
1214 def test_shut_noshut_receiver_interface_when_upstream_cleared_from_LHR_p1(request):
1215 """
1216 TC_27: Verify shut/no shut of receiver interface after upstream got
1217 cleared from LHR
1218 """
1219
1220 tgen = get_topogen()
1221 tc_name = request.node.name
1222 write_test_header(tc_name)
1223
1224 # Don"t run this test if we have any failure.
1225 if tgen.routers_have_failure():
1226 pytest.skip(tgen.errors)
1227
1228 # Creating configuration from JSON
1229 app_helper.stop_all_hosts()
1230 clear_mroute(tgen)
1231 reset_config_on_routers(tgen)
1232 clear_pim_interface_traffic(tgen, topo)
1233 check_router_status(tgen)
1234
1235 step("Enable the PIM on all the interfaces of FRR1, R2 and FRR3" " routers")
1236 step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-225.1.1.10)")
1237
1238 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
1239
1240 for recvr, recvr_intf in input_join.items():
1241 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
1242 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1243
1244 step("Configure RP on R2 (loopback interface) for " "the group range 225.0.0.0/8")
1245
1246 input_dict = {
1247 "r2": {
1248 "pim": {
1249 "rp": [
1250 {
1251 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1252 "/"
1253 )[0],
1254 "group_addr_range": GROUP_RANGE_1,
1255 }
1256 ]
1257 }
1258 }
1259 }
1260
1261 result = create_pim_config(tgen, topo, input_dict)
1262 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1263
1264 step("Send multicast traffic from FRR3 to 225.1.1.1-225.1.1.10" " receiver")
1265
1266 input_src = {"i2": topo["routers"]["i2"]["links"]["f1"]["interface"]}
1267
1268 for src, src_intf in input_src.items():
1269 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
1270 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1271
1272 step(
1273 "'show ip mroute' showing correct RPF and OIF interface for (*,G)"
1274 " and (S,G) entries on all the nodes"
1275 )
1276
1277 source_i2 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
1278 input_dict_all = [
1279 {
1280 "dut": "l1",
1281 "src_address": "*",
1282 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1283 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1284 },
1285 {
1286 "dut": "l1",
1287 "src_address": source_i2,
1288 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1289 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1290 },
1291 {
1292 "dut": "r2",
1293 "src_address": "*",
1294 "iif": "lo",
1295 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
1296 },
1297 {
1298 "dut": "r2",
1299 "src_address": source_i2,
1300 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
1301 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
1302 },
1303 {
1304 "dut": "f1",
1305 "src_address": source_i2,
1306 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
1307 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
1308 },
1309 ]
1310
1311 for data in input_dict_all:
1312 result = verify_mroutes(
1313 tgen,
1314 data["dut"],
1315 data["src_address"],
1316 IGMP_JOIN_RANGE_1,
1317 data["iif"],
1318 data["oil"],
1319 )
1320 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1321
1322 step(
1323 "'show ip pim upstream' and 'show ip pim upstream-rpf' showing"
1324 " correct OIL and IIF on all the nodes"
1325 )
1326
1327 for data in input_dict_all:
1328 result = verify_upstream_iif(
1329 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1330 )
1331 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1332
1333 step("Shut the source interface FRR1")
1334 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
1335 intf_f1_i2 = topo["routers"]["f1"]["links"]["i2"]["interface"]
1336 intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"]
1337 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, False)
1338
1339 step(
1340 "After waiting for (S,G) timeout from FRR1 for same"
1341 " source verify that (S,G) is flushed from FRR1 node"
1342 " 'show ip pim upstream' 'show ip mroute' "
1343 )
1344
1345 result = verify_upstream_iif(
1346 tgen, "l1", "Unknown", source_i2, IGMP_JOIN_RANGE_1, expected=False
1347 )
1348 assert result is not True, (
1349 "Testcase {} : Failed \n "
1350 "Expected: [{}]: Upstream IIF should be Unknown \n "
1351 "Found: {}".format(tc_name, "l1", result)
1352 )
1353
1354 step("No shut the Source interface just after the upstream is expired" " from FRR1")
1355 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, True)
1356
1357 step(
1358 "After no shut of source interface , verify all the (S,G) is "
1359 " populated again on 'show ip mroute' 'show ip pim upstream' "
1360 " with proper OIL and IIF detail"
1361 )
1362
1363 for data in input_dict_all:
1364 result = verify_mroutes(
1365 tgen,
1366 data["dut"],
1367 data["src_address"],
1368 IGMP_JOIN_RANGE_1,
1369 data["iif"],
1370 data["oil"],
1371 )
1372 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1373
1374 for data in input_dict_all:
1375 result = verify_upstream_iif(
1376 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1377 )
1378 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1379
1380 step("shut and no shut the source interface immediately")
1381 shutdown_bringup_interface(tgen, "f1", intf_f1_i2, False)
1382 shutdown_bringup_interface(tgen, "f1", intf_f1_i2, True)
1383
1384 step(
1385 "After no shut of receiver interface , verify all the (S,G) is "
1386 "populated again on 'show ip mroute' 'show ip pim upstream' "
1387 "with proper OIL and IIF detail"
1388 )
1389
1390 for data in input_dict_all:
1391 result = verify_mroutes(
1392 tgen,
1393 data["dut"],
1394 data["src_address"],
1395 IGMP_JOIN_RANGE_1,
1396 data["iif"],
1397 data["oil"],
1398 )
1399 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1400
1401 for data in input_dict_all:
1402 result = verify_upstream_iif(
1403 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1404 )
1405 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1406
1407 write_test_footer(tc_name)
1408
1409
1410 def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request):
1411 """
1412 TC_33: Verify removing and adding IGMP config from the receiver interface
1413 """
1414 tgen = get_topogen()
1415 tc_name = request.node.name
1416 write_test_header(tc_name)
1417
1418 # Don"t run this test if we have any failure.
1419 if tgen.routers_have_failure():
1420 pytest.skip(tgen.errors)
1421
1422 # Creating configuration from JSON
1423 app_helper.stop_all_hosts()
1424 clear_mroute(tgen)
1425 reset_config_on_routers(tgen)
1426 clear_pim_interface_traffic(tgen, topo)
1427 check_router_status(tgen)
1428
1429 step("Enable PIM on all routers")
1430 step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-225.1.1.10)")
1431
1432 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
1433
1434 for recvr, recvr_intf in input_join.items():
1435 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
1436 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1437
1438 step("Configure RP for (226.1.1.1-5) and (232.1.1.1-5) in cisco-1(f1)")
1439
1440 input_dict = {
1441 "r2": {
1442 "pim": {
1443 "rp": [
1444 {
1445 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1446 "/"
1447 )[0],
1448 "group_addr_range": GROUP_RANGE,
1449 }
1450 ]
1451 }
1452 }
1453 }
1454
1455 result = create_pim_config(tgen, topo, input_dict)
1456 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1457
1458 step("Configure source on FRR3 and start the traffic for" " (225.1.1.1-225.1.1.10)")
1459
1460 input_src = {"i2": topo["routers"]["i2"]["links"]["f1"]["interface"]}
1461
1462 for src, src_intf in input_src.items():
1463 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
1464 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1465
1466 step("Configure source on FRR1 and start the traffic for" " (225.1.1.1-225.1.1.10)")
1467
1468 input_src = {"i6": topo["routers"]["i6"]["links"]["l1"]["interface"]}
1469
1470 for src, src_intf in input_src.items():
1471 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
1472 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1473
1474 source_i6 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0]
1475 source_i2 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
1476 input_dict_all = [
1477 {
1478 "dut": "l1",
1479 "src_address": "*",
1480 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1481 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1482 },
1483 {
1484 "dut": "l1",
1485 "src_address": source_i6,
1486 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
1487 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1488 },
1489 {
1490 "dut": "l1",
1491 "src_address": source_i2,
1492 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1493 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1494 },
1495 {
1496 "dut": "r2",
1497 "src_address": "*",
1498 "iif": "lo",
1499 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
1500 },
1501 {
1502 "dut": "f1",
1503 "src_address": source_i2,
1504 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
1505 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
1506 },
1507 ]
1508
1509 for data in input_dict_all:
1510 result = verify_mroutes(
1511 tgen,
1512 data["dut"],
1513 data["src_address"],
1514 IGMP_JOIN_RANGE_1,
1515 data["iif"],
1516 data["oil"],
1517 )
1518 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1519
1520 for data in input_dict_all:
1521 result = verify_upstream_iif(
1522 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1523 )
1524 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1525
1526 step(
1527 "Remove igmp 'no ip igmp' and 'no ip igmp version 2' from"
1528 " receiver interface of FRR1"
1529 )
1530
1531 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
1532 input_dict_2 = {
1533 "l1": {
1534 "igmp": {
1535 "interfaces": {
1536 intf_l1_i1: {
1537 "igmp": {
1538 "version": "2",
1539 "delete": True,
1540 }
1541 }
1542 }
1543 }
1544 }
1545 }
1546 result = create_igmp_config(tgen, topo, input_dict_2)
1547 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1548
1549 step("IGMP join removed from FRR1 , verify using " "'show ip igmp groups json'")
1550
1551 dut = "l1"
1552 interface = topo["routers"]["l1"]["links"]["i1"]["interface"]
1553 result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN_RANGE_1, expected=False)
1554 assert result is not True, (
1555 "Testcase {} : Failed \n "
1556 "Expected: [{}]: IGMP groups should not be present \n "
1557 "Found: {}".format(tc_name, dut, result)
1558 )
1559
1560 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
1561 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
1562 intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"]
1563 intf_f1_i2 = topo["routers"]["f1"]["links"]["i2"]["interface"]
1564 input_traffic = {
1565 "l1": {"traffic_received": [intf_l1_r2], "traffic_sent": [intf_l1_i1]},
1566 "f1": {"traffic_sent": [intf_f1_r2], "traffic_received": [intf_f1_i2]},
1567 }
1568 result = verify_multicast_traffic(tgen, input_traffic)
1569 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1570
1571 step(
1572 "Configure igmp 'ip igmp' and 'ip igmp version 2' from "
1573 "receiver interface of FRR1"
1574 )
1575
1576 input_dict_2 = {
1577 "l1": {
1578 "igmp": {
1579 "interfaces": {
1580 intf_l1_i1: {
1581 "igmp": {"version": "2", "query": {"query-interval": 15}}
1582 }
1583 }
1584 }
1585 }
1586 }
1587 result = create_igmp_config(tgen, topo, input_dict_2)
1588 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1589
1590 step(
1591 "After adding IGMP on receiver interface verify (S,G) and (*,G)"
1592 " entries got populated and traffic is resumed on FRR1 and FRR3 node"
1593 )
1594
1595 step(
1596 "Verify OIL/IIF and drJoinDesired using 'show ip mroute , and traffic"
1597 " using show ip pim upstream and show ip multicast'"
1598 )
1599
1600 for data in input_dict_all:
1601 result = verify_mroutes(
1602 tgen,
1603 data["dut"],
1604 data["src_address"],
1605 IGMP_JOIN_RANGE_1,
1606 data["iif"],
1607 data["oil"],
1608 )
1609 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1610
1611 for data in input_dict_all:
1612 result = verify_upstream_iif(
1613 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1614 )
1615 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1616
1617 result = verify_multicast_traffic(tgen, input_traffic)
1618 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1619
1620 step("Verify that no core is observed")
1621 if tgen.routers_have_failure():
1622 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
1623
1624 step(
1625 "Remove igmp 'no ip igmp' and 'no ip igmp version 2' from"
1626 " receiver interface of FRR1"
1627 )
1628
1629 input_dict_2 = {
1630 "l1": {
1631 "igmp": {
1632 "interfaces": {
1633 intf_l1_i1: {
1634 "igmp": {
1635 "version": "2",
1636 "delete": True,
1637 }
1638 }
1639 }
1640 }
1641 }
1642 }
1643
1644 result = create_igmp_config(tgen, topo, input_dict_2)
1645 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1646
1647 step("IGMP join removed from FRR1 , verify using " "'show ip igmp groups json'")
1648
1649 dut = "l1"
1650 interface = topo["routers"]["l1"]["links"]["i1"]["interface"]
1651 result = verify_igmp_groups(tgen, dut, interface, IGMP_JOIN_RANGE_1, expected=False)
1652 assert result is not True, (
1653 "Testcase {} : Failed \n "
1654 "Expected: [{}]: IGMP groups should not be present \n "
1655 "Found: {}".format(tc_name, dut, result)
1656 )
1657
1658 result = verify_multicast_traffic(tgen, input_traffic)
1659 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1660
1661 step(
1662 "Configure igmp 'ip igmp' and 'ip igmp version 2' from "
1663 "receiver interface of FRR1"
1664 )
1665
1666 input_dict_2 = {
1667 "l1": {
1668 "igmp": {
1669 "interfaces": {
1670 intf_l1_i1: {
1671 "igmp": {"version": "2", "query": {"query-interval": 15}}
1672 }
1673 }
1674 }
1675 }
1676 }
1677 result = create_igmp_config(tgen, topo, input_dict_2)
1678 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1679
1680 step(
1681 "After adding IGMP on receiver interface verify (S,G) and (*,G)"
1682 " entries got populated and traffic is resumed on FRR1 and FRR3 node"
1683 )
1684
1685 step(
1686 "Verify OIL/IIF and drJoinDesired using 'show ip mroute , and traffic"
1687 " using show ip pim upstream and show ip multicast'"
1688 )
1689
1690 input_dict_l1_f1 = [
1691 {
1692 "dut": "l1",
1693 "src_address": "*",
1694 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1695 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1696 },
1697 {
1698 "dut": "l1",
1699 "src_address": source_i6,
1700 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
1701 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1702 },
1703 {
1704 "dut": "l1",
1705 "src_address": source_i2,
1706 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1707 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1708 },
1709 {
1710 "dut": "f1",
1711 "src_address": source_i2,
1712 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
1713 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
1714 },
1715 ]
1716
1717 for data in input_dict_l1_f1:
1718 result = verify_mroutes(
1719 tgen,
1720 data["dut"],
1721 data["src_address"],
1722 IGMP_JOIN_RANGE_1,
1723 data["iif"],
1724 data["oil"],
1725 )
1726 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1727
1728 for data in input_dict_l1_f1:
1729 result = verify_upstream_iif(
1730 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1731 )
1732 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1733
1734 result = verify_multicast_traffic(tgen, input_traffic)
1735 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1736
1737 step("Verify that no core is observed")
1738 if tgen.routers_have_failure():
1739 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
1740
1741 step("Remove ip igmp and send igmp prune from FRR1 interface")
1742
1743 input_dict_2 = {
1744 "l1": {
1745 "igmp": {
1746 "interfaces": {
1747 intf_l1_i1: {
1748 "igmp": {
1749 "version": "2",
1750 "delete": True,
1751 }
1752 }
1753 }
1754 }
1755 }
1756 }
1757 result = create_igmp_config(tgen, topo, input_dict_2)
1758 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1759 step(
1760 "Verification: After removing igmp 'no ip igmp' and "
1761 " sending prune verify mroute and upstream got removed"
1762 " from FRR1 verify using 'show ip mroute' and "
1763 "'show ip pim upstream'"
1764 )
1765
1766 dut = "l1"
1767 iif = topo["routers"]["l1"]["links"]["i6"]["interface"]
1768 oil = topo["routers"]["l1"]["links"]["i1"]["interface"]
1769 source = source_i6
1770 result = verify_mroutes(
1771 tgen, dut, source, IGMP_JOIN_RANGE_1, iif, oil, expected=False
1772 )
1773 assert result is not True, (
1774 "Testcase {} : Failed \n "
1775 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
1776 "Found: {}".format(tc_name, dut, result)
1777 )
1778
1779 write_test_footer(tc_name)
1780
1781
1782 def test_verify_remove_add_igmp_commands_when_pim_configured_p0(request):
1783 """
1784 TC_34: Verify removing and adding IGMP commands when PIM is already
1785 configured
1786 """
1787
1788 tgen = get_topogen()
1789 tc_name = request.node.name
1790 write_test_header(tc_name)
1791
1792 # Don"t run this test if we have any failure.
1793 if tgen.routers_have_failure():
1794 pytest.skip(tgen.errors)
1795
1796 # Creating configuration from JSON
1797 app_helper.stop_all_hosts()
1798 clear_mroute(tgen)
1799 reset_config_on_routers(tgen)
1800 clear_pim_interface_traffic(tgen, topo)
1801 check_router_status(tgen)
1802
1803 step("Enable PIM on all routers")
1804 step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-225.1.1.10)")
1805
1806 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
1807
1808 for recvr, recvr_intf in input_join.items():
1809 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
1810 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1811
1812 step("Configure RP for (226.1.1.1-5) and (232.1.1.1-5) in cisco-1(f1)")
1813
1814 input_dict = {
1815 "r2": {
1816 "pim": {
1817 "rp": [
1818 {
1819 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
1820 "/"
1821 )[0],
1822 "group_addr_range": GROUP_RANGE,
1823 }
1824 ]
1825 }
1826 }
1827 }
1828
1829 result = create_pim_config(tgen, topo, input_dict)
1830 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1831
1832 step("Configure source on FRR3 and start the traffic for" " (225.1.1.1-225.1.1.10)")
1833
1834 input_src = {"i2": topo["routers"]["i2"]["links"]["f1"]["interface"]}
1835
1836 for src, src_intf in input_src.items():
1837 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
1838 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1839
1840 step("Configure source on FRR1 and start the traffic for" " (225.1.1.1-225.1.1.10)")
1841
1842 input_src = {"i6": topo["routers"]["i6"]["links"]["l1"]["interface"]}
1843
1844 for src, src_intf in input_src.items():
1845 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
1846 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1847
1848 source_i6 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0]
1849 source_i2 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
1850 input_dict_all = [
1851 {
1852 "dut": "l1",
1853 "src_address": "*",
1854 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1855 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1856 },
1857 {
1858 "dut": "l1",
1859 "src_address": source_i6,
1860 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
1861 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1862 },
1863 {
1864 "dut": "l1",
1865 "src_address": source_i2,
1866 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
1867 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
1868 },
1869 {
1870 "dut": "r2",
1871 "src_address": "*",
1872 "iif": "lo",
1873 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
1874 },
1875 {
1876 "dut": "f1",
1877 "src_address": source_i2,
1878 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
1879 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
1880 },
1881 ]
1882
1883 for data in input_dict_all:
1884 result = verify_mroutes(
1885 tgen,
1886 data["dut"],
1887 data["src_address"],
1888 IGMP_JOIN_RANGE_1,
1889 data["iif"],
1890 data["oil"],
1891 )
1892 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1893
1894 for data in input_dict_all:
1895 result = verify_upstream_iif(
1896 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
1897 )
1898 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1899
1900 step(
1901 "Verification: After configuring IGMP related config , "
1902 "verify config is present in the interface "
1903 "'show ip igmp interface ensxx json'"
1904 )
1905
1906 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
1907 input_dict_1 = {
1908 "l1": {
1909 "igmp": {
1910 "interfaces": {
1911 intf_l1_i1: {
1912 "igmp": {
1913 "version": "2",
1914 "query": {
1915 "query-max-response-time": 40,
1916 "query-interval": 5,
1917 },
1918 }
1919 }
1920 }
1921 }
1922 }
1923 }
1924
1925 result = verify_igmp_config(tgen, input_dict_1)
1926 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1927
1928 step(
1929 "Remove igmp 'no ip igmp' and 'no ip igmp version 2' from"
1930 " receiver interface of FRR1"
1931 )
1932
1933 input_dict_2 = {
1934 "l1": {
1935 "igmp": {
1936 "interfaces": {
1937 intf_l1_i1: {
1938 "igmp": {
1939 "version": "2",
1940 "delete": True,
1941 }
1942 }
1943 }
1944 }
1945 }
1946 }
1947
1948 result = create_igmp_config(tgen, topo, input_dict_2)
1949 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1950
1951 step(
1952 "Verification: After removing the config CLI got removed "
1953 "'show ip igmp interface ensxx json'"
1954 )
1955
1956 result = verify_igmp_config(tgen, input_dict_1, expected=False)
1957 assert result is not True, (
1958 "Testcase {} : Failed \n "
1959 "Expected: [{}]: IGMP interface should be removed \n "
1960 "Found: {}".format(tc_name, data["dut"], result)
1961 )
1962
1963 step("Verify that no core is observed")
1964 if tgen.routers_have_failure():
1965 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
1966
1967 step("Configure 'ip igmp last-member-query-count 10' on FRR1" " receiver interface")
1968
1969 input_dict_3 = {
1970 "l1": {
1971 "igmp": {
1972 "interfaces": {
1973 "l1-i1-eth1": {"igmp": {"query": {"last-member-query-count": 5}}}
1974 }
1975 }
1976 }
1977 }
1978 result = create_igmp_config(tgen, topo, input_dict_3)
1979 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1980
1981 result = verify_igmp_config(tgen, input_dict_3)
1982 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1983
1984 step("Remove 'ip igmp last-member-query-count 10' on FRR1" " receiver interface")
1985
1986 input_dict_3 = {
1987 "l1": {
1988 "igmp": {
1989 "interfaces": {
1990 "l1-i1-eth1": {
1991 "igmp": {
1992 "query": {"last-member-query-count": "", "delete": True}
1993 }
1994 }
1995 }
1996 }
1997 }
1998 }
1999 result = create_igmp_config(tgen, topo, input_dict_3)
2000 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2001
2002 input_dict_3 = {
2003 "l1": {
2004 "igmp": {
2005 "interfaces": {
2006 "l1-i1-eth1": {"igmp": {"query": {"last-member-query-count": 2}}}
2007 }
2008 }
2009 }
2010 }
2011 result = verify_igmp_config(tgen, input_dict_3)
2012 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2013
2014 step("Verify that no core is observed")
2015 if tgen.routers_have_failure():
2016 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2017
2018 step(
2019 "Configure 'ip igmp last-member-query-interval 20' on FRR1"
2020 " receiver interface"
2021 )
2022
2023 input_dict_3 = {
2024 "l1": {
2025 "igmp": {
2026 "interfaces": {
2027 "l1-i1-eth1": {
2028 "igmp": {"query": {"last-member-query-interval": 20}}
2029 }
2030 }
2031 }
2032 }
2033 }
2034 result = create_igmp_config(tgen, topo, input_dict_3)
2035 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2036
2037 result = verify_igmp_config(tgen, input_dict_3)
2038 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2039
2040 step("Remove 'ip igmp last-member-query-count 10' on FRR1" " receiver interface")
2041
2042 input_dict_3 = {
2043 "l1": {
2044 "igmp": {
2045 "interfaces": {
2046 "l1-i1-eth1": {
2047 "igmp": {
2048 "query": {"last-member-query-interval": "", "delete": True}
2049 }
2050 }
2051 }
2052 }
2053 }
2054 }
2055 result = create_igmp_config(tgen, topo, input_dict_3)
2056 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2057
2058 input_dict_3 = {
2059 "l1": {
2060 "igmp": {
2061 "interfaces": {
2062 "l1-i1-eth1": {
2063 "igmp": {"query": {"last-member-query-interval": 10}}
2064 }
2065 }
2066 }
2067 }
2068 }
2069 result = verify_igmp_config(tgen, input_dict_3)
2070 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2071
2072 step("Verify that no core is observed")
2073 if tgen.routers_have_failure():
2074 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2075
2076 write_test_footer(tc_name)
2077
2078
2079 def test_verify_remove_add_pim_commands_when_igmp_configured_p1(request):
2080 """
2081 TC_35: Verify removing and adding PIM commands when IGMP is already
2082 configured
2083 """
2084
2085 tgen = get_topogen()
2086 tc_name = request.node.name
2087 write_test_header(tc_name)
2088
2089 # Don"t run this test if we have any failure.
2090 if tgen.routers_have_failure():
2091 pytest.skip(tgen.errors)
2092
2093 # Creating configuration from JSON
2094 app_helper.stop_all_hosts()
2095 clear_mroute(tgen)
2096 reset_config_on_routers(tgen)
2097 clear_pim_interface_traffic(tgen, topo)
2098 check_router_status(tgen)
2099
2100 step("Configure 'ip pim' on receiver interface on FRR1")
2101 step("Enable PIM on all routers")
2102 step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-225.1.1.10)")
2103
2104 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
2105
2106 for recvr, recvr_intf in input_join.items():
2107 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2108 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2109
2110 step("Configure RP for (226.1.1.1-5) and (232.1.1.1-5) in cisco-1(f1)")
2111
2112 input_dict = {
2113 "r2": {
2114 "pim": {
2115 "rp": [
2116 {
2117 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2118 "/"
2119 )[0],
2120 "group_addr_range": GROUP_RANGE,
2121 }
2122 ]
2123 }
2124 }
2125 }
2126
2127 result = create_pim_config(tgen, topo, input_dict)
2128 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2129
2130 step("Remove 'no ip pim' on receiver interface on FRR1")
2131
2132 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
2133 raw_config = {
2134 "l1": {"raw_config": ["interface {}".format(intf_l1_i1), "no ip pim"]}
2135 }
2136 result = apply_raw_config(tgen, raw_config)
2137 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2138
2139 step("Verify that no core is observed")
2140 if tgen.routers_have_failure():
2141 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2142
2143 step("Configure 'ip pim bsm' on receiver interface on FRR1")
2144
2145 raw_config = {
2146 "l1": {"raw_config": ["interface {}".format(intf_l1_i1), "ip pim bsm"]}
2147 }
2148 result = apply_raw_config(tgen, raw_config)
2149 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2150
2151 step("Remove 'no ip pim bsm' on receiver interface on FRR1")
2152
2153 raw_config = {
2154 "l1": {"raw_config": ["interface {}".format(intf_l1_i1), "no ip pim bsm"]}
2155 }
2156 result = apply_raw_config(tgen, raw_config)
2157 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2158
2159 step("Verify that no core is observed")
2160 if tgen.routers_have_failure():
2161 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2162
2163 step("Configure 'ip pim drpriority' on receiver interface on FRR1")
2164
2165 raw_config = {
2166 "l1": {
2167 "raw_config": ["interface {}".format(intf_l1_i1), "ip pim drpriority 10"]
2168 }
2169 }
2170 result = apply_raw_config(tgen, raw_config)
2171 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2172
2173 step(
2174 "Verification: After configuring PIM related config, "
2175 "verify config is present in the interface "
2176 "'show ip pim interface ensxx json'"
2177 )
2178
2179 input_dict_dr = {"l1": {"pim": {"interfaces": {intf_l1_i1: {"drPriority": 10}}}}}
2180 result = verify_pim_config(tgen, input_dict_dr)
2181 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2182
2183 step("Remove 'no ip pim drpriority' on receiver interface on FRR1")
2184
2185 raw_config = {
2186 "l1": {
2187 "raw_config": ["interface {}".format(intf_l1_i1), "no ip pim drpriority 10"]
2188 }
2189 }
2190 result = apply_raw_config(tgen, raw_config)
2191 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2192
2193 step(
2194 "Verification: After removing the config CLI got removed "
2195 "'show ip pim interface ensxx json'"
2196 )
2197
2198 input_dict_dr = {"l1": {"pim": {"interfaces": {intf_l1_i1: {"drPriority": 1}}}}}
2199 result = verify_pim_config(tgen, input_dict_dr)
2200 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2201
2202 step("Verify that no core is observed")
2203 if tgen.routers_have_failure():
2204 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2205
2206 step("Configure 'ip pim hello' on receiver interface on FRR1")
2207
2208 raw_config = {
2209 "l1": {"raw_config": ["interface {}".format(intf_l1_i1), "ip pim hello 50"]}
2210 }
2211 result = apply_raw_config(tgen, raw_config)
2212 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2213
2214 step(
2215 "Verification: After configuring PIM related config, "
2216 "verify config is present in the interface "
2217 "'show ip pim interface ensxx json'"
2218 )
2219
2220 input_dict_dr = {"l1": {"pim": {"interfaces": {intf_l1_i1: {"helloPeriod": 50}}}}}
2221 result = verify_pim_config(tgen, input_dict_dr)
2222 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2223
2224 step("Remove 'no ip pim hello' on receiver interface on FRR1")
2225
2226 raw_config = {
2227 "l1": {"raw_config": ["interface {}".format(intf_l1_i1), "no ip pim hello"]}
2228 }
2229 result = apply_raw_config(tgen, raw_config)
2230 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2231
2232 step(
2233 "Verification: After removing the config CLI got removed "
2234 "'show ip pim interface ensxx json'"
2235 )
2236
2237 input_dict_dr = {"l1": {"pim": {"interfaces": {intf_l1_i1: {"helloPeriod": 30}}}}}
2238 result = verify_pim_config(tgen, input_dict_dr)
2239 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2240
2241 step("Verify that no core is observed")
2242 if tgen.routers_have_failure():
2243 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2244
2245 step("Configure 'ip pim unicast-bsm' on receiver interface on FRR1")
2246
2247 raw_config = {
2248 "l1": {"raw_config": ["interface {}".format(intf_l1_i1), "ip pim unicast-bsm"]}
2249 }
2250 result = apply_raw_config(tgen, raw_config)
2251 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2252
2253 step("Remove 'no ip pim hello' on receiver interface on FRR1")
2254
2255 raw_config = {
2256 "l1": {
2257 "raw_config": ["interface {}".format(intf_l1_i1), "no ip pim unicast-bsm"]
2258 }
2259 }
2260 result = apply_raw_config(tgen, raw_config)
2261 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2262
2263 step("Verify that no core is observed")
2264 if tgen.routers_have_failure():
2265 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2266
2267 write_test_footer(tc_name)
2268
2269
2270 def test_pim_dr_priority_p0(request):
2271 """
2272 TC_36: Verify highest DR priority become the PIM DR
2273 """
2274
2275 tgen = get_topogen()
2276 tc_name = request.node.name
2277 write_test_header(tc_name)
2278
2279 # Don"t run this test if we have any failure.
2280 if tgen.routers_have_failure():
2281 pytest.skip(tgen.errors)
2282
2283 # Creating configuration from JSON
2284 app_helper.stop_all_hosts()
2285 clear_mroute(tgen)
2286 reset_config_on_routers(tgen)
2287 clear_pim_interface_traffic(tgen, topo)
2288 check_router_status(tgen)
2289
2290 step("Configure 'ip pim' on receiver interface on FRR1")
2291 step("Enable PIM on all routers")
2292 step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-225.1.1.10)")
2293
2294 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
2295
2296 for recvr, recvr_intf in input_join.items():
2297 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2298 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2299
2300 step("Configure RP for (226.1.1.1-5) and (232.1.1.1-5) in cisco-1(f1)")
2301
2302 input_dict = {
2303 "r2": {
2304 "pim": {
2305 "rp": [
2306 {
2307 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2308 "/"
2309 )[0],
2310 "group_addr_range": GROUP_RANGE,
2311 }
2312 ]
2313 }
2314 }
2315 }
2316
2317 result = create_pim_config(tgen, topo, input_dict)
2318 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2319
2320 input_src = {"i2": topo["routers"]["i2"]["links"]["f1"]["interface"]}
2321
2322 for src, src_intf in input_src.items():
2323 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
2324 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2325
2326 source_i2 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
2327 input_dict_all = [
2328 {
2329 "dut": "l1",
2330 "src_address": "*",
2331 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
2332 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
2333 },
2334 {
2335 "dut": "l1",
2336 "src_address": source_i2,
2337 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
2338 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
2339 },
2340 {
2341 "dut": "r2",
2342 "src_address": "*",
2343 "iif": "lo",
2344 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
2345 },
2346 {
2347 "dut": "f1",
2348 "src_address": source_i2,
2349 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
2350 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
2351 },
2352 ]
2353
2354 for data in input_dict_all:
2355 result = verify_mroutes(
2356 tgen,
2357 data["dut"],
2358 data["src_address"],
2359 IGMP_JOIN_RANGE_1,
2360 data["iif"],
2361 data["oil"],
2362 )
2363 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2364
2365 for data in input_dict_all:
2366 result = verify_upstream_iif(
2367 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
2368 )
2369 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2370
2371 step("Configure 'ip pim drpriority 10' on receiver interface on FRR1(LHR)")
2372
2373 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
2374 raw_config = {
2375 "l1": {
2376 "raw_config": ["interface {}".format(intf_l1_r2), "ip pim drpriority 10"]
2377 }
2378 }
2379 result = apply_raw_config(tgen, raw_config)
2380 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2381
2382 step(
2383 "DR config is successful on FRR1 node , verify using "
2384 " 'show ip pim interface json'"
2385 )
2386
2387 input_dict_dr = {"l1": {"pim": {"interfaces": {intf_l1_r2: {"drPriority": 10}}}}}
2388 result = verify_pim_config(tgen, input_dict_dr)
2389 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2390
2391 for data in input_dict_all:
2392 result = verify_mroutes(
2393 tgen,
2394 data["dut"],
2395 data["src_address"],
2396 IGMP_JOIN_RANGE_1,
2397 data["iif"],
2398 data["oil"],
2399 )
2400 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2401
2402 for data in input_dict_all:
2403 result = verify_upstream_iif(
2404 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
2405 )
2406 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2407
2408 step("Configure 'ip pim drpriority 20' on receiver interface on FRR3(FHR)")
2409
2410 intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"]
2411 raw_config = {
2412 "f1": {
2413 "raw_config": ["interface {}".format(intf_f1_r2), "ip pim drpriority 20"]
2414 }
2415 }
2416 result = apply_raw_config(tgen, raw_config)
2417 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2418
2419 step(
2420 "DR config is successful on FRR3 node , verify using "
2421 " 'show ip pim interface json'"
2422 )
2423
2424 input_dict_dr = {"f1": {"pim": {"interfaces": {intf_f1_r2: {"drPriority": 20}}}}}
2425 result = verify_pim_config(tgen, input_dict_dr)
2426 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2427
2428 for data in input_dict_all:
2429 result = verify_mroutes(
2430 tgen,
2431 data["dut"],
2432 data["src_address"],
2433 IGMP_JOIN_RANGE_1,
2434 data["iif"],
2435 data["oil"],
2436 )
2437 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2438
2439 for data in input_dict_all:
2440 result = verify_upstream_iif(
2441 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
2442 )
2443 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2444
2445 step(
2446 "PIM is enable on FRR1, FRR2 interface and neighbor is up, "
2447 " verify using 'show ip pim interface'"
2448 )
2449
2450 result = verify_pim_interface(tgen, topo, "l1")
2451 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2452
2453 result = verify_pim_interface(tgen, topo, "f1")
2454 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2455
2456 step(
2457 "Highet IP become PIM DR , verify using "
2458 "'show ip pim interface json' and 'show ip pim neighbor'"
2459 )
2460 step("Highest priority become PIM DR")
2461
2462 dr_address = topo["routers"]["l1"]["links"]["r2"]["ipv4"].split("/")[0]
2463 input_dict_dr = {
2464 "l1": {"pim": {"interfaces": {intf_l1_r2: {"drAddress": dr_address}}}}
2465 }
2466 result = verify_pim_config(tgen, input_dict_dr)
2467 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2468
2469 dr_address = topo["routers"]["f1"]["links"]["r2"]["ipv4"].split("/")[0]
2470 input_dict_dr = {
2471 "f1": {"pim": {"interfaces": {intf_f1_r2: {"drAddress": dr_address}}}}
2472 }
2473 result = verify_pim_config(tgen, input_dict_dr)
2474 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2475
2476 step("Remove 'no ip pim drpriority' on receiver interface on FRR1")
2477
2478 raw_config = {
2479 "l1": {
2480 "raw_config": ["interface {}".format(intf_l1_r2), "no ip pim drpriority 10"]
2481 }
2482 }
2483 result = apply_raw_config(tgen, raw_config)
2484 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2485
2486 step("Remove 'no ip pim drpriority' on receiver interface on FRR3")
2487
2488 raw_config = {
2489 "f1": {
2490 "raw_config": ["interface {}".format(intf_f1_r2), "no ip pim drpriority 20"]
2491 }
2492 }
2493 result = apply_raw_config(tgen, raw_config)
2494 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2495
2496 step(
2497 "After removing drpriority , config got removed from both the "
2498 "nodes and highest IP become PIM DR"
2499 )
2500
2501 input_dict_dr = {"l1": {"pim": {"interfaces": {intf_l1_r2: {"drPriority": 1}}}}}
2502 result = verify_pim_config(tgen, input_dict_dr)
2503 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2504
2505 input_dict_dr = {"f1": {"pim": {"interfaces": {intf_f1_r2: {"drPriority": 1}}}}}
2506 result = verify_pim_config(tgen, input_dict_dr)
2507 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2508
2509 dr_address = topo["routers"]["r2"]["links"]["l1"]["ipv4"].split("/")[0]
2510 input_dict_dr = {
2511 "l1": {"pim": {"interfaces": {intf_l1_r2: {"drAddress": dr_address}}}}
2512 }
2513 result = verify_pim_config(tgen, input_dict_dr)
2514 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2515
2516 dr_address = topo["routers"]["r2"]["links"]["f1"]["ipv4"].split("/")[0]
2517 input_dict_dr = {
2518 "f1": {"pim": {"interfaces": {intf_f1_r2: {"drAddress": dr_address}}}}
2519 }
2520 result = verify_pim_config(tgen, input_dict_dr)
2521 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2522
2523 for data in input_dict_all:
2524 result = verify_mroutes(
2525 tgen,
2526 data["dut"],
2527 data["src_address"],
2528 IGMP_JOIN_RANGE_1,
2529 data["iif"],
2530 data["oil"],
2531 )
2532 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2533
2534 for data in input_dict_all:
2535 result = verify_upstream_iif(
2536 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
2537 )
2538 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2539
2540 write_test_footer(tc_name)
2541
2542
2543 def test_pim_hello_timer_p1(request):
2544 """
2545 TC_37: Verify PIM hello is sent on configured timer
2546 """
2547
2548 tgen = get_topogen()
2549 tc_name = request.node.name
2550 write_test_header(tc_name)
2551
2552 # Don"t run this test if we have any failure.
2553 if tgen.routers_have_failure():
2554 pytest.skip(tgen.errors)
2555
2556 # Creating configuration from JSON
2557 app_helper.stop_all_hosts()
2558 clear_mroute(tgen)
2559 reset_config_on_routers(tgen)
2560 clear_pim_interface_traffic(tgen, topo)
2561 check_router_status(tgen)
2562
2563 step("Configure 'ip pim' on receiver interface on FRR1")
2564 step("Enable PIM on all routers")
2565 step("Enable IGMP on FRR1 interface and send IGMP join " "(225.1.1.1-225.1.1.10)")
2566
2567 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
2568
2569 for recvr, recvr_intf in input_join.items():
2570 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2571 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2572
2573 step("Configure RP for (226.1.1.1-5) and (232.1.1.1-5) in cisco-1(f1)")
2574
2575 input_dict = {
2576 "r2": {
2577 "pim": {
2578 "rp": [
2579 {
2580 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2581 "/"
2582 )[0],
2583 "group_addr_range": GROUP_RANGE,
2584 }
2585 ]
2586 }
2587 }
2588 }
2589
2590 result = create_pim_config(tgen, topo, input_dict)
2591 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2592
2593 step("Configure PIM hello interval timer 100 on FRR1 node (FRR1-FRR2 link)")
2594
2595 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
2596 raw_config = {
2597 "l1": {"raw_config": ["interface {}".format(intf_l1_r2), "ip pim hello 100"]}
2598 }
2599 result = apply_raw_config(tgen, raw_config)
2600 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2601
2602 step(
2603 "PIM hello interval is configured on interface verify using "
2604 "'show ip pim interface'"
2605 )
2606
2607 input_dict_hello = {
2608 "l1": {"pim": {"interfaces": {intf_l1_r2: {"helloPeriod": 100}}}}
2609 }
2610 result = verify_pim_config(tgen, input_dict_hello)
2611 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2612
2613 step("Modify hello timer to 180 and then 50sec")
2614
2615 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
2616 raw_config = {
2617 "l1": {"raw_config": ["interface {}".format(intf_l1_r2), "ip pim hello 180"]}
2618 }
2619 result = apply_raw_config(tgen, raw_config)
2620 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2621
2622 step(
2623 "PIM hello interval is configured on interface verify using "
2624 "'show ip pim interface'"
2625 )
2626
2627 input_dict_hello = {
2628 "l1": {"pim": {"interfaces": {intf_l1_r2: {"helloPeriod": 180}}}}
2629 }
2630 result = verify_pim_config(tgen, input_dict_hello)
2631 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2632
2633 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
2634 raw_config = {
2635 "l1": {"raw_config": ["interface {}".format(intf_l1_r2), "ip pim hello 50"]}
2636 }
2637 result = apply_raw_config(tgen, raw_config)
2638 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2639
2640 step(
2641 "PIM hello interval is configured on interface verify using "
2642 "'show ip pim interface'"
2643 )
2644
2645 input_dict_hello = {
2646 "l1": {"pim": {"interfaces": {intf_l1_r2: {"helloPeriod": 50}}}}
2647 }
2648 result = verify_pim_config(tgen, input_dict_hello)
2649 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2650
2651 step("Verify that no core is observed")
2652 if tgen.routers_have_failure():
2653 assert False, "Testcase {}: Failed Error: {}".format(tc_name, result)
2654
2655 write_test_footer(tc_name)
2656
2657
2658 def test_mroute_after_removing_RP_sending_IGMP_prune_p2(request):
2659 """
2660 TC_39 Verify mroute after removing the RP and sending IGMP prune
2661 """
2662
2663 tgen = get_topogen()
2664 tc_name = request.node.name
2665 write_test_header(tc_name)
2666
2667 # Don"t run this test if we have any failure.
2668 if tgen.routers_have_failure():
2669 pytest.skip(tgen.errors)
2670
2671 # Creating configuration from JSON
2672 app_helper.stop_all_hosts()
2673 clear_mroute(tgen)
2674 reset_config_on_routers(tgen)
2675 clear_pim_interface_traffic(tgen, topo)
2676 check_router_status(tgen)
2677
2678 step(
2679 "Remove cisco connected link to simulate topo "
2680 "LHR(FRR1(f1))----RP(cisco(f1)---FHR(FRR3(l1))"
2681 )
2682
2683 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
2684 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["interface"]
2685 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, False)
2686 shutdown_bringup_interface(tgen, "f1", intf_f1_c2, False)
2687
2688 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
2689 step(
2690 "Enable IGMP of FRR1 interface and send IGMP joins "
2691 " from FRR1 node for group range (225.1.1.1-5)"
2692 )
2693
2694 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
2695 input_dict = {
2696 "f1": {
2697 "igmp": {
2698 "interfaces": {
2699 intf_f1_i8: {
2700 "igmp": {"version": "2", "query": {"query-interval": 15}}
2701 }
2702 }
2703 }
2704 }
2705 }
2706 result = create_igmp_config(tgen, topo, input_dict)
2707 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2708
2709 input_join = {"i8": topo["routers"]["i8"]["links"]["f1"]["interface"]}
2710
2711 for recvr, recvr_intf in input_join.items():
2712 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2713 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2714
2715 step("Configure static RP for (225.1.1.1-5) as R2")
2716
2717 input_dict = {
2718 "r2": {
2719 "pim": {
2720 "rp": [
2721 {
2722 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2723 "/"
2724 )[0],
2725 "group_addr_range": GROUP_RANGE,
2726 }
2727 ]
2728 }
2729 }
2730 }
2731
2732 result = create_pim_config(tgen, topo, input_dict)
2733 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2734
2735 step(
2736 "Send traffic from FHR to all the groups ( 225.1.1.1 to 225.1.1.5) and send"
2737 " multicast traffic"
2738 )
2739
2740 input_src = {"i6": topo["routers"]["i6"]["links"]["l1"]["interface"]}
2741
2742 for src, src_intf in input_src.items():
2743 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
2744 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2745
2746 source_i2 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0]
2747
2748 input_dict_all = [
2749 {
2750 "dut": "l1",
2751 "src_address": source_i2,
2752 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
2753 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
2754 },
2755 {
2756 "dut": "f1",
2757 "src_address": "*",
2758 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
2759 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
2760 },
2761 {
2762 "dut": "f1",
2763 "src_address": source_i2,
2764 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
2765 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
2766 },
2767 ]
2768
2769 step("Verify mroutes and iff upstream")
2770
2771 for data in input_dict_all:
2772 result = verify_mroutes(
2773 tgen,
2774 data["dut"],
2775 data["src_address"],
2776 IGMP_JOIN_RANGE_1,
2777 data["iif"],
2778 data["oil"],
2779 )
2780 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2781
2782 for data in input_dict_all:
2783 result = verify_upstream_iif(
2784 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
2785 )
2786 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2787
2788 step("Remove the RP config for both the range from all the nodes")
2789
2790 input_dict = {
2791 "r2": {
2792 "pim": {
2793 "rp": [
2794 {
2795 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2796 "/"
2797 )[0],
2798 "group_addr_range": GROUP_RANGE,
2799 "delete": True,
2800 }
2801 ]
2802 }
2803 }
2804 }
2805
2806 result = create_pim_config(tgen, topo, input_dict)
2807 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2808
2809 input_dict_starg = [
2810 {
2811 "dut": "f1",
2812 "src_address": "*",
2813 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
2814 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
2815 }
2816 ]
2817
2818 input_dict_sg = [
2819 {
2820 "dut": "l1",
2821 "src_address": source_i2,
2822 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
2823 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
2824 },
2825 {
2826 "dut": "f1",
2827 "src_address": source_i2,
2828 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
2829 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
2830 },
2831 ]
2832
2833 for data in input_dict_starg:
2834 result = verify_mroutes(
2835 tgen,
2836 data["dut"],
2837 data["src_address"],
2838 IGMP_JOIN_RANGE_1,
2839 data["iif"],
2840 data["oil"],
2841 expected=False,
2842 )
2843 assert result is not True, (
2844 "Testcase {} : Failed \n "
2845 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
2846 "Found: {}".format(tc_name, data["dut"], result)
2847 )
2848
2849 for data in input_dict_sg:
2850 result = verify_mroutes(
2851 tgen,
2852 data["dut"],
2853 data["src_address"],
2854 IGMP_JOIN_RANGE_1,
2855 data["iif"],
2856 data["oil"],
2857 )
2858 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2859
2860 step("Send prune from receiver-1 (using ctrl+c) on iperf interface")
2861 app_helper.stop_all_hosts()
2862
2863 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
2864 input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
2865 traffic_before = verify_multicast_traffic(tgen, input_traffic, return_traffic=True)
2866 assert isinstance(traffic_before, dict), (
2867 "Testcase {} : Failed \n traffic_before is not dictionary \n "
2868 "Error: {}".format(tc_name, result)
2869 )
2870
2871 step("IGMP groups are remove from FRR1 node 'show ip igmp groups'")
2872
2873 dut = "f1"
2874 result = verify_igmp_groups(
2875 tgen, dut, intf_f1_i8, IGMP_JOIN_RANGE_1, expected=False
2876 )
2877 assert result is not True, (
2878 "Testcase {} : Failed \n "
2879 "Expected: [{}]: IGMP groups should not present \n "
2880 "Found: {}".format(tc_name, dut, result)
2881 )
2882
2883 step(
2884 "After receiving the IGMP prune from FRR1 , verify traffic "
2885 "immediately stopped for this receiver 'show ip multicast'"
2886 )
2887
2888 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
2889 input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
2890 traffic_after = verify_multicast_traffic(tgen, input_traffic, return_traffic=True)
2891 assert isinstance(traffic_after, dict), (
2892 "Testcase {} : Failed \n traffic_after is not dictionary \n "
2893 "Error: {}".format(tc_name, result)
2894 )
2895
2896 result = verify_state_incremented(traffic_before, traffic_after)
2897 assert result is not True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2898 logger.info("Expected Behaviour: {}".format(result))
2899
2900 step("Configure static RP for (225.1.1.1-5) as R2 loopback interface")
2901
2902 input_dict = {
2903 "r2": {
2904 "pim": {
2905 "rp": [
2906 {
2907 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
2908 "/"
2909 )[0],
2910 "group_addr_range": GROUP_RANGE,
2911 }
2912 ]
2913 }
2914 }
2915 }
2916
2917 result = create_pim_config(tgen, topo, input_dict)
2918 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2919
2920 step("Send IGMP joins again from LHR,check IGMP joins and starg received")
2921
2922 for recvr, recvr_intf in input_join.items():
2923 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
2924 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
2925
2926 for data in input_dict_starg:
2927 result = verify_mroutes(
2928 tgen,
2929 data["dut"],
2930 data["src_address"],
2931 IGMP_JOIN_RANGE_1,
2932 data["iif"],
2933 data["oil"],
2934 )
2935 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2936
2937 step("Send traffic from FHR and verify mroute upstream")
2938
2939 for src, src_intf in input_src.items():
2940 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
2941 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2942
2943 source_i2 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0]
2944
2945 for data in input_dict_sg:
2946 result = verify_mroutes(
2947 tgen,
2948 data["dut"],
2949 data["src_address"],
2950 IGMP_JOIN_RANGE_1,
2951 data["iif"],
2952 data["oil"],
2953 )
2954 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
2955
2956 write_test_footer(tc_name)
2957
2958
2959 def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request):
2960 """
2961 TC_38 Verify prune is sent to LHR and FHR when PIM nbr went down
2962 """
2963
2964 tgen = get_topogen()
2965 tc_name = request.node.name
2966 write_test_header(tc_name)
2967
2968 # Don"t run this test if we have any failure.
2969 if tgen.routers_have_failure():
2970 pytest.skip(tgen.errors)
2971
2972 # Creating configuration from JSON
2973 app_helper.stop_all_hosts()
2974 clear_mroute(tgen)
2975 reset_config_on_routers(tgen)
2976 clear_pim_interface_traffic(tgen, topo)
2977 check_router_status(tgen)
2978
2979 step(
2980 "Remove cisco connected link to simulate topo "
2981 "LHR(FRR1(f1))----RP(cisco(f1)---FHR(FRR3(l1))"
2982 )
2983
2984 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
2985 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["interface"]
2986 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, False)
2987 shutdown_bringup_interface(tgen, "f1", intf_f1_c2, False)
2988
2989 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
2990 step(
2991 "Enable IGMP of FRR1 interface and send IGMP joins "
2992 " from FRR1 node for group range (225.1.1.1-5)"
2993 )
2994
2995 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
2996 input_dict = {
2997 "f1": {
2998 "igmp": {
2999 "interfaces": {
3000 intf_f1_i8: {
3001 "igmp": {"version": "2", "query": {"query-interval": 15}}
3002 }
3003 }
3004 }
3005 }
3006 }
3007 result = create_igmp_config(tgen, topo, input_dict)
3008 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3009
3010 input_join = {"i8": topo["routers"]["i8"]["links"]["f1"]["interface"]}
3011
3012 for recvr, recvr_intf in input_join.items():
3013 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
3014 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3015
3016 step("Configure static RP for (225.1.1.1-5) as R2")
3017
3018 input_dict = {
3019 "r2": {
3020 "pim": {
3021 "rp": [
3022 {
3023 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
3024 "/"
3025 )[0],
3026 "group_addr_range": GROUP_RANGE,
3027 }
3028 ]
3029 }
3030 }
3031 }
3032
3033 result = create_pim_config(tgen, topo, input_dict)
3034 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3035
3036 step(
3037 "Send traffic from FHR to all the groups ( 225.1.1.1 to 225.1.1.5) and send"
3038 " multicast traffic"
3039 )
3040
3041 input_src = {
3042 "i6": topo["routers"]["i6"]["links"]["l1"]["interface"],
3043 "i2": topo["routers"]["i2"]["links"]["f1"]["interface"],
3044 }
3045
3046 for src, src_intf in input_src.items():
3047 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
3048 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3049
3050 source_i2 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0]
3051 source_i1 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
3052
3053 input_dict_all = [
3054 {
3055 "dut": "l1",
3056 "src_address": source_i2,
3057 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
3058 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
3059 },
3060 {
3061 "dut": "f1",
3062 "src_address": "*",
3063 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
3064 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3065 },
3066 {
3067 "dut": "f1",
3068 "src_address": source_i1,
3069 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
3070 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3071 },
3072 {
3073 "dut": "f1",
3074 "src_address": source_i2,
3075 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
3076 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3077 },
3078 ]
3079
3080 step("Verify mroutes and iff upstream")
3081
3082 for data in input_dict_all:
3083 result = verify_mroutes(
3084 tgen,
3085 data["dut"],
3086 data["src_address"],
3087 IGMP_JOIN_RANGE_1,
3088 data["iif"],
3089 data["oil"],
3090 )
3091 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3092
3093 for data in input_dict_all:
3094 result = verify_upstream_iif(
3095 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3096 )
3097 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3098 step("Verify mcast traffic received")
3099 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
3100 input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
3101
3102 result = verify_multicast_traffic(tgen, input_traffic)
3103 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3104
3105 step("Shut the link from LHR to RP from RP node")
3106
3107 intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["interface"]
3108 shutdown_bringup_interface(tgen, "r2", intf_r2_f1, False)
3109
3110 step("Verify RP info after Shut the link from LHR to RP from RP node")
3111 dut = "f1"
3112 rp_address = "1.0.5.17"
3113 SOURCE = "Static"
3114 result = verify_pim_rp_info(
3115 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE
3116 )
3117 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
3118
3119 input_dict_starg = [
3120 {
3121 "dut": "f1",
3122 "src_address": "*",
3123 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
3124 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3125 }
3126 ]
3127
3128 input_dict_sg_i2 = [
3129 {
3130 "dut": "l1",
3131 "src_address": source_i2,
3132 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
3133 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
3134 },
3135 {
3136 "dut": "f1",
3137 "src_address": source_i2,
3138 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
3139 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3140 },
3141 ]
3142
3143 input_dict_sg_i1 = [
3144 {
3145 "dut": "f1",
3146 "src_address": source_i1,
3147 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
3148 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3149 }
3150 ]
3151
3152 input_dict_sg_i2_l1 = [
3153 {
3154 "dut": "l1",
3155 "src_address": source_i2,
3156 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
3157 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
3158 }
3159 ]
3160
3161 step("Verify mroute after Shut the link from LHR to RP from RP node")
3162
3163 for data in input_dict_starg:
3164 result = verify_mroutes(
3165 tgen,
3166 data["dut"],
3167 data["src_address"],
3168 IGMP_JOIN_RANGE_1,
3169 data["iif"],
3170 data["oil"],
3171 expected=False,
3172 )
3173 assert result is not True, (
3174 "Testcase {} : Failed \n "
3175 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
3176 "Found: {}".format(tc_name, data["dut"], result)
3177 )
3178
3179 for data in input_dict_sg_i1:
3180 result = verify_mroutes(
3181 tgen,
3182 data["dut"],
3183 data["src_address"],
3184 IGMP_JOIN_RANGE_1,
3185 data["iif"],
3186 data["oil"],
3187 )
3188 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3189
3190 step("Verify upstream after Shut the link from LHR to RP from RP node")
3191
3192 for data in input_dict_starg:
3193 result = verify_upstream_iif(
3194 tgen,
3195 data["dut"],
3196 data["iif"],
3197 data["src_address"],
3198 IGMP_JOIN_RANGE_1,
3199 expected=False,
3200 )
3201 assert result is not True, (
3202 "Testcase {} : Failed \n "
3203 "Expected: [{}]: Upstream IIF interface {} should not be present\n"
3204 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
3205 )
3206
3207 for data in input_dict_sg_i1:
3208 result = verify_upstream_iif(
3209 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3210 )
3211 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3212
3213 step("No shut the link from LHR to RP from RP node")
3214
3215 intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["interface"]
3216 shutdown_bringup_interface(tgen, "r2", intf_r2_f1, True)
3217
3218 step("Verify RP info after No shut the link from LHR to RP from RP node")
3219 dut = "f1"
3220 rp_address = "1.0.5.17"
3221 SOURCE = "Static"
3222 result = verify_pim_rp_info(
3223 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False
3224 )
3225 assert result is not True, (
3226 "Testcase {} : Failed \n "
3227 "Expected: [{}]: RP IIF should be updated as Unknown \n "
3228 "Found: {}".format(tc_name, dut, result)
3229 )
3230
3231 step("Verify mroute after No shut the link from LHR to RP from RP node")
3232
3233 for data in input_dict_starg:
3234 result = verify_mroutes(
3235 tgen,
3236 data["dut"],
3237 data["src_address"],
3238 IGMP_JOIN_RANGE_1,
3239 data["iif"],
3240 data["oil"],
3241 )
3242 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3243
3244 for data in input_dict_sg_i2:
3245 result = verify_mroutes(
3246 tgen,
3247 data["dut"],
3248 data["src_address"],
3249 IGMP_JOIN_RANGE_1,
3250 data["iif"],
3251 data["oil"],
3252 )
3253 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3254
3255 for data in input_dict_sg_i1:
3256 result = verify_mroutes(
3257 tgen,
3258 data["dut"],
3259 data["src_address"],
3260 IGMP_JOIN_RANGE_1,
3261 data["iif"],
3262 data["oil"],
3263 )
3264 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3265
3266 step("Verify upstrem after No shut the link from LHR to RP from RP node")
3267
3268 for data in input_dict_starg:
3269 result = verify_upstream_iif(
3270 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3271 )
3272 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3273
3274 for data in input_dict_sg_i1:
3275 result = verify_upstream_iif(
3276 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3277 )
3278 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3279
3280 for data in input_dict_sg_i2:
3281 result = verify_upstream_iif(
3282 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3283 )
3284 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3285
3286 step("Verify mcast traffic received after noshut LHR to RP from RP node")
3287
3288 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
3289 input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
3290 result = verify_multicast_traffic(tgen, input_traffic)
3291 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3292
3293 step("Shut the link from FHR to RP from RP node")
3294
3295 intf_r2_l1 = topo["routers"]["r2"]["links"]["l1"]["interface"]
3296 shutdown_bringup_interface(tgen, "r2", intf_r2_l1, False)
3297
3298 step("Verify RP info after Shut the link from FHR to RP from RP node")
3299 dut = "l1"
3300 rp_address = "1.0.5.17"
3301 SOURCE = "Static"
3302 result = verify_pim_rp_info(
3303 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE
3304 )
3305 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
3306
3307 step("Verify mroute after Shut the link from FHR to RP from RP node")
3308
3309 for data in input_dict_starg:
3310 result = verify_mroutes(
3311 tgen,
3312 data["dut"],
3313 data["src_address"],
3314 IGMP_JOIN_RANGE_1,
3315 data["iif"],
3316 data["oil"],
3317 )
3318 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3319
3320 for data in input_dict_sg_i1:
3321 result = verify_mroutes(
3322 tgen,
3323 data["dut"],
3324 data["src_address"],
3325 IGMP_JOIN_RANGE_1,
3326 data["iif"],
3327 data["oil"],
3328 )
3329 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3330
3331 step("Verify upstream after Shut the link from FHR to RP from RP node")
3332
3333 for data in input_dict_starg:
3334 result = verify_upstream_iif(
3335 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3336 )
3337 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3338
3339 for data in input_dict_sg_i1:
3340 result = verify_upstream_iif(
3341 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3342 )
3343 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3344
3345 for data in input_dict_sg_i2_l1:
3346 result = verify_upstream_iif(
3347 tgen,
3348 data["dut"],
3349 data["iif"],
3350 data["src_address"],
3351 IGMP_JOIN_RANGE_1,
3352 expected=False,
3353 )
3354 assert result is not True, (
3355 "Testcase {} : Failed \n "
3356 "Expected: [{}]: Upstream IIF interface {} should not be present"
3357 " after shutting link from RP to FHR \n"
3358 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
3359 )
3360
3361 step(" No shut the link from FHR to RP from RP node")
3362
3363 intf_r2_l1 = topo["routers"]["r2"]["links"]["l1"]["interface"]
3364 shutdown_bringup_interface(tgen, "r2", intf_r2_l1, True)
3365
3366 step("Verify RP info after Noshut the link from FHR to RP from RP node")
3367
3368 dut = "l1"
3369 rp_address = "1.0.5.17"
3370 SOURCE = "Static"
3371 result = verify_pim_rp_info(
3372 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False
3373 )
3374 assert result is not True, (
3375 "Testcase {} : Failed \n "
3376 "Expected: [{}]: RP IIF should be updated as Unknown \n"
3377 "Found: {}".format(tc_name, dut, result)
3378 )
3379
3380 step("Verify mroute after Noshut the link from FHR to RP from RP node")
3381
3382 for data in input_dict_starg:
3383 result = verify_mroutes(
3384 tgen,
3385 data["dut"],
3386 data["src_address"],
3387 IGMP_JOIN_RANGE_1,
3388 data["iif"],
3389 data["oil"],
3390 )
3391 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3392
3393 for data in input_dict_sg_i2:
3394 result = verify_mroutes(
3395 tgen,
3396 data["dut"],
3397 data["src_address"],
3398 IGMP_JOIN_RANGE_1,
3399 data["iif"],
3400 data["oil"],
3401 )
3402 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3403
3404 for data in input_dict_sg_i1:
3405 result = verify_mroutes(
3406 tgen,
3407 data["dut"],
3408 data["src_address"],
3409 IGMP_JOIN_RANGE_1,
3410 data["iif"],
3411 data["oil"],
3412 )
3413 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3414
3415 step("Verify mroute after Noshut the link from FHR to RP from RP node")
3416
3417 for data in input_dict_starg:
3418 result = verify_upstream_iif(
3419 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3420 )
3421 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3422
3423 for data in input_dict_sg_i1:
3424 result = verify_upstream_iif(
3425 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3426 )
3427 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3428
3429 for data in input_dict_sg_i2:
3430 result = verify_upstream_iif(
3431 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3432 )
3433 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3434
3435 step("Verify mcast traffic received after noshut FHR to RP from RP node")
3436 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
3437 input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
3438 result = verify_multicast_traffic(tgen, input_traffic)
3439 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3440
3441 step("Shut the link from FHR to RP from FHR node")
3442
3443 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
3444 shutdown_bringup_interface(tgen, "l1", intf_l1_r2, False)
3445
3446 step("Verify PIM Nbrs after Shut the link from FHR to RP from FHR node")
3447
3448 step("Verify RP info after Shut the link from FHR to RP from FHR node")
3449 dut = "l1"
3450 rp_address = "1.0.5.17"
3451 SOURCE = "Static"
3452 result = verify_pim_rp_info(
3453 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE
3454 )
3455 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
3456
3457 step("Verify mroute after Shut the link from FHR to RP from FHR node")
3458
3459 for data in input_dict_starg:
3460 result = verify_mroutes(
3461 tgen,
3462 data["dut"],
3463 data["src_address"],
3464 IGMP_JOIN_RANGE_1,
3465 data["iif"],
3466 data["oil"],
3467 )
3468 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3469
3470 for data in input_dict_sg_i1:
3471 result = verify_mroutes(
3472 tgen,
3473 data["dut"],
3474 data["src_address"],
3475 IGMP_JOIN_RANGE_1,
3476 data["iif"],
3477 data["oil"],
3478 )
3479 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3480
3481 step("Verify upstream after Shut the link from FHR to RP from FHR node")
3482 for data in input_dict_starg:
3483 result = verify_upstream_iif(
3484 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3485 )
3486 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3487
3488 for data in input_dict_sg_i1:
3489 result = verify_upstream_iif(
3490 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3491 )
3492 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3493
3494 for data in input_dict_sg_i2_l1:
3495 result = verify_upstream_iif(
3496 tgen,
3497 data["dut"],
3498 data["iif"],
3499 data["src_address"],
3500 IGMP_JOIN_RANGE_1,
3501 expected=False,
3502 )
3503 assert result is not True, (
3504 "Testcase {} : Failed \n "
3505 "Expected: [{}]: Upstream IIF interface {} should not be present"
3506 " after shutting link from FHR to RP \n"
3507 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
3508 )
3509
3510 step(" No shut the link from FHR to RP from FHR node")
3511
3512 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
3513 shutdown_bringup_interface(tgen, "l1", intf_l1_r2, True)
3514
3515 step("Verify RP info after No Shut the link from FHR to RP from FHR node")
3516 dut = "l1"
3517 rp_address = "1.0.5.17"
3518 SOURCE = "Static"
3519 result = verify_pim_rp_info(
3520 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False
3521 )
3522 assert result is not True, (
3523 "Testcase {} : Failed \n "
3524 "Expected: [{}]: RP IIF should be updated as Unknown \n"
3525 "Found: {}".format(tc_name, dut, result)
3526 )
3527
3528 step("Verify mroute after No Shut the link from FHR to RP from FHR node")
3529
3530 for data in input_dict_starg:
3531 result = verify_mroutes(
3532 tgen,
3533 data["dut"],
3534 data["src_address"],
3535 IGMP_JOIN_RANGE_1,
3536 data["iif"],
3537 data["oil"],
3538 )
3539 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3540
3541 for data in input_dict_sg_i2:
3542 result = verify_mroutes(
3543 tgen,
3544 data["dut"],
3545 data["src_address"],
3546 IGMP_JOIN_RANGE_1,
3547 data["iif"],
3548 data["oil"],
3549 )
3550 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3551
3552 for data in input_dict_sg_i1:
3553 result = verify_mroutes(
3554 tgen,
3555 data["dut"],
3556 data["src_address"],
3557 IGMP_JOIN_RANGE_1,
3558 data["iif"],
3559 data["oil"],
3560 )
3561 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3562
3563 step("Verify upstream after No Shut the link from FHR to RP from FHR node")
3564
3565 for data in input_dict_starg:
3566 result = verify_upstream_iif(
3567 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3568 )
3569 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3570
3571 for data in input_dict_sg_i1:
3572 result = verify_upstream_iif(
3573 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3574 )
3575 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3576
3577 for data in input_dict_sg_i2:
3578 result = verify_upstream_iif(
3579 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3580 )
3581 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3582
3583 step("Verify mcast traffic received after noshut FHR to RP from FHR node")
3584 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
3585 input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
3586 result = verify_multicast_traffic(tgen, input_traffic)
3587 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3588
3589 write_test_footer(tc_name)
3590
3591
3592 def test_mroute_flags_p1(request):
3593 """
3594 TC_47 Verify mroute flag in LHR and FHR node
3595 """
3596
3597 tgen = get_topogen()
3598 tc_name = request.node.name
3599 write_test_header(tc_name)
3600
3601 # Don"t run this test if we have any failure.
3602 if tgen.routers_have_failure():
3603 pytest.skip(tgen.errors)
3604
3605 # Creating configuration from JSON
3606 app_helper.stop_all_hosts()
3607 clear_mroute(tgen)
3608 reset_config_on_routers(tgen)
3609 clear_pim_interface_traffic(tgen, topo)
3610 check_router_status(tgen)
3611
3612 step(
3613 "Remove cisco connected link to simulate topo "
3614 "LHR(FRR1(f1))----RP(cisco(f1)---FHR(FRR3(l1))"
3615 )
3616
3617 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
3618 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["interface"]
3619 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, False)
3620 shutdown_bringup_interface(tgen, "f1", intf_f1_c2, False)
3621
3622 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
3623 step(
3624 "Enable IGMP of FRR1 interface and send IGMP joins "
3625 " from FRR1 node for group range (225.1.1.1-5)"
3626 )
3627
3628 intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
3629 input_dict = {
3630 "f1": {
3631 "igmp": {
3632 "interfaces": {
3633 intf_f1_i8: {
3634 "igmp": {"version": "2", "query": {"query-interval": 15}}
3635 }
3636 }
3637 }
3638 }
3639 }
3640 result = create_igmp_config(tgen, topo, input_dict)
3641 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3642
3643 input_join = {"i8": topo["routers"]["i8"]["links"]["f1"]["interface"]}
3644
3645 for recvr, recvr_intf in input_join.items():
3646 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
3647 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3648
3649 step("Configure static RP for (225.1.1.1-5) as R2")
3650
3651 input_dict = {
3652 "r2": {
3653 "pim": {
3654 "rp": [
3655 {
3656 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
3657 "/"
3658 )[0],
3659 "group_addr_range": GROUP_RANGE,
3660 }
3661 ]
3662 }
3663 }
3664 }
3665
3666 result = create_pim_config(tgen, topo, input_dict)
3667 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3668
3669 step(
3670 "Send traffic from FHR to all the groups ( 225.1.1.1 to 225.1.1.5) and send"
3671 " multicast traffic"
3672 )
3673
3674 input_src = {
3675 "i6": topo["routers"]["i6"]["links"]["l1"]["interface"],
3676 "i2": topo["routers"]["i2"]["links"]["f1"]["interface"],
3677 }
3678
3679 for src, src_intf in input_src.items():
3680 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
3681 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3682
3683 source_i2 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0]
3684 source_i1 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
3685
3686 input_dict_all = [
3687 {
3688 "dut": "l1",
3689 "src_address": source_i2,
3690 "iif": topo["routers"]["l1"]["links"]["i6"]["interface"],
3691 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
3692 },
3693 {
3694 "dut": "f1",
3695 "src_address": "*",
3696 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
3697 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3698 },
3699 {
3700 "dut": "f1",
3701 "src_address": source_i1,
3702 "iif": topo["routers"]["f1"]["links"]["i2"]["interface"],
3703 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3704 },
3705 {
3706 "dut": "f1",
3707 "src_address": source_i2,
3708 "iif": topo["routers"]["f1"]["links"]["r2"]["interface"],
3709 "oil": topo["routers"]["f1"]["links"]["i8"]["interface"],
3710 },
3711 ]
3712
3713 step("Verify mroutes and iff upstream")
3714
3715 for data in input_dict_all:
3716 result = verify_mroutes(
3717 tgen,
3718 data["dut"],
3719 data["src_address"],
3720 IGMP_JOIN_RANGE_1,
3721 data["iif"],
3722 data["oil"],
3723 )
3724 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3725
3726 result = verify_upstream_iif(
3727 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
3728 )
3729 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3730
3731 dut = "f1"
3732 step("verify flag for (*,G) on f1")
3733 src_address = "*"
3734 flag = "SC"
3735 result = verify_multicast_flag_state(
3736 tgen, dut, src_address, IGMP_JOIN_RANGE_1, flag
3737 )
3738 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3739
3740 step("verify flag for (S,G) on f1 for Remote spurce ")
3741 src_address = source_i2
3742 flag = "ST"
3743 result = verify_multicast_flag_state(
3744 tgen, dut, src_address, IGMP_JOIN_RANGE_1, flag
3745 )
3746 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3747
3748 write_test_footer(tc_name)
3749
3750
3751 def test_verify_multicast_traffic_when_LHR_connected_to_RP_p1(request):
3752 """
3753 TC_11: Verify multicast traffic flowing fine, when LHR connected to RP
3754 Topology used:
3755 FHR(FRR3(l1))---LHR(FRR1(r2)----RP(FRR2(f1))
3756 """
3757
3758 tgen = get_topogen()
3759 tc_name = request.node.name
3760 write_test_header(tc_name)
3761
3762 # Don"t run this test if we have any failure.
3763 if tgen.routers_have_failure():
3764 pytest.skip(tgen.errors)
3765
3766 # Creating configuration from JSON
3767 app_helper.stop_all_hosts()
3768 clear_mroute(tgen)
3769 reset_config_on_routers(tgen)
3770 clear_pim_interface_traffic(tgen, topo)
3771 check_router_status(tgen)
3772
3773 step(
3774 "Remove FRR3 to cisco connected link to simulate topo "
3775 "FHR(FRR3(l1))---LHR(FRR1(r2)----RP(FRR2(f1))"
3776 )
3777
3778 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
3779 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["interface"]
3780 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, False)
3781 shutdown_bringup_interface(tgen, "f1", intf_f1_c2, False)
3782
3783 step("Disable IGMP config from l1")
3784 input_dict_2 = {
3785 "l1": {
3786 "igmp": {
3787 "interfaces": {
3788 "l1-i1-eth1": {
3789 "igmp": {
3790 "version": "2",
3791 "delete": True,
3792 }
3793 }
3794 }
3795 }
3796 }
3797 }
3798 result = create_igmp_config(tgen, topo, input_dict_2)
3799 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3800
3801 step("Enable the PIM on all the interfaces of FRR1, R2 and FRR3" " routers")
3802 step(
3803 "Enable IGMP on FRR1(r2) interface and send IGMP join (226.1.1.1-5)"
3804 " and (232.1.1.1-5)"
3805 )
3806
3807 intf_r2_i3 = topo["routers"]["r2"]["links"]["i3"]["interface"]
3808 input_dict = {
3809 "r2": {
3810 "igmp": {
3811 "interfaces": {
3812 intf_r2_i3: {
3813 "igmp": {"version": "2", "query": {"query-interval": 15}}
3814 }
3815 }
3816 }
3817 }
3818 }
3819 result = create_igmp_config(tgen, topo, input_dict)
3820 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3821
3822 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
3823 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
3824
3825 input_join = {"i3": topo["routers"]["i3"]["links"]["r2"]["interface"]}
3826
3827 for recvr, recvr_intf in input_join.items():
3828 result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
3829 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
3830
3831 step("Configure RP for (226.1.1.1-5) and (232.1.1.1-5) in (f1)")
3832
3833 input_dict = {
3834 "f1": {
3835 "pim": {
3836 "rp": [
3837 {
3838 "rp_addr": topo["routers"]["f1"]["links"]["lo"]["ipv4"].split(
3839 "/"
3840 )[0],
3841 "group_addr_range": _GROUP_RANGE,
3842 }
3843 ]
3844 }
3845 }
3846 }
3847
3848 result = create_pim_config(tgen, topo, input_dict)
3849 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3850
3851 step("Send multicast traffic from FRR3 to 225.1.1.1-225.1.1.10" " receiver")
3852
3853 input_src = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
3854
3855 for src, src_intf in input_src.items():
3856 result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
3857 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3858
3859 step(
3860 "'show ip mroute' showing correct RPF and OIF interface for (*,G)"
3861 " and (S,G) entries on all the nodes"
3862 )
3863
3864 source_i1 = topo["routers"]["i1"]["links"]["l1"]["ipv4"].split("/")[0]
3865 input_dict_all = [
3866 {
3867 "dut": "l1",
3868 "src_address": source_i1,
3869 "iif": topo["routers"]["l1"]["links"]["i1"]["interface"],
3870 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
3871 },
3872 {
3873 "dut": "r2",
3874 "src_address": "*",
3875 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
3876 "oil": topo["routers"]["r2"]["links"]["i3"]["interface"],
3877 },
3878 {
3879 "dut": "r2",
3880 "src_address": source_i1,
3881 "iif": topo["routers"]["r2"]["links"]["l1"]["interface"],
3882 "oil": topo["routers"]["r2"]["links"]["i3"]["interface"],
3883 },
3884 ]
3885
3886 for data in input_dict_all:
3887 result = verify_mroutes(
3888 tgen,
3889 data["dut"],
3890 data["src_address"],
3891 _IGMP_JOIN_RANGE,
3892 data["iif"],
3893 data["oil"],
3894 )
3895 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3896
3897 for data in input_dict_all:
3898 result = verify_upstream_iif(
3899 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
3900 )
3901 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3902
3903 step(
3904 "Multicast traffic is flowing for all the groups verify"
3905 "using 'show ip multicast'"
3906 )
3907
3908 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
3909 intf_r2_l1 = topo["routers"]["r2"]["links"]["l1"]["interface"]
3910 intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["interface"]
3911 intf_r2_i3 = topo["routers"]["r2"]["links"]["i3"]["interface"]
3912 intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"]
3913 input_traffic = {
3914 "l1": {"traffic_received": [intf_l1_i1]},
3915 "r2": {"traffic_received": [intf_r2_l1], "traffic_sent": [intf_r2_i3]},
3916 }
3917 result = verify_multicast_traffic(tgen, input_traffic)
3918 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3919
3920 step("Shut and No shut the receiver port")
3921
3922 intf_r2_i3 = topo["routers"]["r2"]["links"]["i3"]["interface"]
3923 shutdown_bringup_interface(tgen, "r2", intf_r2_i3, False)
3924
3925 step(
3926 "Verification: After Shut of receiver port, Verify (*,G) and "
3927 "(S,G) got removed from LHR node (FRR1) using 'show ip mroute'"
3928 )
3929
3930 input_dict_r2 = [
3931 {
3932 "dut": "r2",
3933 "src_address": "*",
3934 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
3935 "oil": topo["routers"]["r2"]["links"]["i3"]["interface"],
3936 },
3937 {
3938 "dut": "r2",
3939 "src_address": source_i1,
3940 "iif": topo["routers"]["r2"]["links"]["l1"]["interface"],
3941 "oil": topo["routers"]["r2"]["links"]["i3"]["interface"],
3942 },
3943 ]
3944
3945 for data in input_dict_r2:
3946 result = verify_mroutes(
3947 tgen,
3948 data["dut"],
3949 data["src_address"],
3950 _IGMP_JOIN_RANGE,
3951 data["iif"],
3952 data["oil"],
3953 expected=False,
3954 )
3955 assert result is not True, (
3956 "Testcase {} : Failed \n "
3957 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
3958 "Found: {}".format(tc_name, data["dut"], result)
3959 )
3960
3961 shutdown_bringup_interface(tgen, "r2", intf_r2_i3, True)
3962
3963 step(
3964 "Verification: After No shut of receiver port , Verify (*,G)"
3965 " and (S,G) got populated on LHR node (FRR1) using "
3966 "'show ip mroute' 'show ip pim upstream'"
3967 )
3968
3969 for data in input_dict_r2:
3970 result = verify_mroutes(
3971 tgen,
3972 data["dut"],
3973 data["src_address"],
3974 _IGMP_JOIN_RANGE,
3975 data["iif"],
3976 data["oil"],
3977 )
3978 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3979
3980 for data in input_dict_r2:
3981 result = verify_upstream_iif(
3982 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
3983 )
3984 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3985
3986 step(
3987 "Multicast traffic is resumed for all the groups verify "
3988 "using 'show ip multicast'"
3989 )
3990
3991 result = verify_multicast_traffic(tgen, input_traffic)
3992 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
3993
3994 step("Shut and No shut the source port")
3995
3996 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
3997 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, False)
3998
3999 step(
4000 "Verification: After Shut of source port, Verify (*,G) and "
4001 "(S,G) got removed from LHR node (FRR1) using 'show ip mroute'"
4002 )
4003
4004 input_dict_l1 = [
4005 {
4006 "dut": "l1",
4007 "src_address": source_i1,
4008 "iif": topo["routers"]["l1"]["links"]["i1"]["interface"],
4009 "oil": topo["routers"]["l1"]["links"]["r2"]["interface"],
4010 }
4011 ]
4012
4013 for data in input_dict_l1:
4014 result = verify_mroutes(
4015 tgen,
4016 data["dut"],
4017 data["src_address"],
4018 _IGMP_JOIN_RANGE,
4019 data["iif"],
4020 data["oil"],
4021 expected=False,
4022 )
4023 assert result is not True, (
4024 "Testcase {} : Failed \n "
4025 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
4026 "Found: {}".format(tc_name, data["dut"], result)
4027 )
4028
4029 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, True)
4030
4031 step(
4032 "Verification: After No shut of source port , Verify (*,G)"
4033 " and (S,G) got populated on LHR node (FRR1) using "
4034 "'show ip mroute' 'show ip pim upstream'"
4035 )
4036
4037 for data in input_dict_l1:
4038 result = verify_mroutes(
4039 tgen,
4040 data["dut"],
4041 data["src_address"],
4042 _IGMP_JOIN_RANGE,
4043 data["iif"],
4044 data["oil"],
4045 )
4046 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4047
4048 for data in input_dict_l1:
4049 result = verify_upstream_iif(
4050 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
4051 )
4052 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4053
4054 step(
4055 "Multicast traffic is resumed for all the groups verify "
4056 "using 'show ip multicast'"
4057 )
4058
4059 result = verify_multicast_traffic(tgen, input_traffic)
4060 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4061
4062 step("Shut and No shut of LHR to cisco port from LHR side")
4063
4064 intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["interface"]
4065 shutdown_bringup_interface(tgen, "r2", intf_r2_f1, False)
4066
4067 step(
4068 "Verification: After Shut of source port, Verify (S,G) got "
4069 "removed from LHR and FHR using 'show ip mroute'"
4070 )
4071
4072 input_dict_r2_f1 = [
4073 {
4074 "dut": "r2",
4075 "src_address": "*",
4076 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
4077 "oil": topo["routers"]["r2"]["links"]["i3"]["interface"],
4078 },
4079 {
4080 "dut": "f1",
4081 "src_address": "*",
4082 "iif": "lo",
4083 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
4084 },
4085 ]
4086
4087 for data in input_dict_r2_f1:
4088 result = verify_mroutes(
4089 tgen,
4090 data["dut"],
4091 data["src_address"],
4092 _IGMP_JOIN_RANGE,
4093 data["iif"],
4094 data["oil"],
4095 expected=False,
4096 )
4097 assert result is not True, (
4098 "Testcase {} : Failed \n "
4099 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
4100 "Found: {}".format(tc_name, data["dut"], result)
4101 )
4102
4103 shutdown_bringup_interface(tgen, "r2", intf_r2_f1, True)
4104
4105 step(
4106 "Verification: After No shut of source port , Verify (*,G)"
4107 " and (S,G) got populated on LHR node (FRR1) using "
4108 "'show ip mroute' 'show ip pim upstream'"
4109 )
4110
4111 for data in input_dict_all:
4112 result = verify_mroutes(
4113 tgen,
4114 data["dut"],
4115 data["src_address"],
4116 _IGMP_JOIN_RANGE,
4117 data["iif"],
4118 data["oil"],
4119 )
4120 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4121
4122 for data in input_dict_all:
4123 result = verify_upstream_iif(
4124 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
4125 )
4126 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4127
4128 step(
4129 "Multicast traffic is resumed for all the groups verify "
4130 "using 'show ip multicast'"
4131 )
4132
4133 input_traffic_r2 = {
4134 "r2": {"traffic_received": [intf_r2_l1], "traffic_sent": [intf_r2_i3]}
4135 }
4136 result = verify_multicast_traffic(tgen, input_traffic_r2)
4137 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4138
4139 step("Shut and no shut of FHR to LHR port from FHR side")
4140
4141 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
4142 shutdown_bringup_interface(tgen, "l1", intf_l1_r2, False)
4143
4144 step(
4145 "Verification: After Shut of LHR to FHR port, Verify (S,G)"
4146 "got removed from LHR 'show ip mroute'"
4147 )
4148
4149 dut = "r2"
4150 src_address = "*"
4151 iif = topo["routers"]["r2"]["links"]["f1"]["interface"]
4152 oil = topo["routers"]["r2"]["links"]["i3"]["interface"]
4153
4154 result = verify_mroutes(tgen, dut, src_address, _IGMP_JOIN_RANGE, iif, oil)
4155 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4156
4157 src_address = source_i1
4158 iif = topo["routers"]["r2"]["links"]["l1"]["interface"]
4159 oil = topo["routers"]["r2"]["links"]["i3"]["interface"]
4160
4161 result = verify_mroutes(
4162 tgen, dut, src_address, _IGMP_JOIN_RANGE, iif, oil, expected=False
4163 )
4164 assert result is not True, (
4165 "Testcase {} : Failed \n "
4166 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
4167 "Found: {}".format(tc_name, dut, result)
4168 )
4169
4170 shutdown_bringup_interface(tgen, "l1", intf_l1_r2, True)
4171
4172 step(
4173 "Verification: After No shut of source port , Verify (*,G)"
4174 " and (S,G) got populated on LHR node (FRR1) using "
4175 "'show ip mroute' 'show ip pim upstream'"
4176 )
4177
4178 for data in input_dict_all:
4179 result = verify_mroutes(
4180 tgen,
4181 data["dut"],
4182 data["src_address"],
4183 _IGMP_JOIN_RANGE,
4184 data["iif"],
4185 data["oil"],
4186 )
4187 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4188
4189 for data in input_dict_all:
4190 result = verify_upstream_iif(
4191 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
4192 )
4193 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4194
4195 step(
4196 "Multicast traffic is resumed for all the groups verify "
4197 "using 'show ip multicast'"
4198 )
4199
4200 result = verify_multicast_traffic(tgen, input_traffic_r2)
4201 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4202
4203 write_test_footer(tc_name)
4204
4205
4206 def test_verify_multicast_traffic_when_FHR_connected_to_RP_p1(request):
4207 """
4208 TC_12: Verify multicast traffic is flowing fine when FHR is connected to RP
4209 Topology used:
4210 LHR(FRR1)---FHR(FRR3)----RP(FRR2)
4211 """
4212
4213 tgen = get_topogen()
4214 tc_name = request.node.name
4215 write_test_header(tc_name)
4216
4217 # Don"t run this test if we have any failure.
4218 if tgen.routers_have_failure():
4219 pytest.skip(tgen.errors)
4220
4221 # Creating configuration from JSON
4222 app_helper.stop_all_hosts()
4223 clear_mroute(tgen)
4224 reset_config_on_routers(tgen)
4225 clear_pim_interface_traffic(tgen, topo)
4226 check_router_status(tgen)
4227
4228 step(
4229 "Remove FRR3 to FRR2 connected link to simulate topo "
4230 "FHR(FRR3)---LHR(FRR1)----RP(FFR2)"
4231 )
4232
4233 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
4234 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["interface"]
4235 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, False)
4236 shutdown_bringup_interface(tgen, "f1", intf_f1_c2, False)
4237
4238 step("Enable the PIM on all the interfaces of FRR1, R2 and FRR3" " routers")
4239 step("Enable IGMP on FRR1(l1) interface and send IGMP join " " and (225.1.1.1-5)")
4240
4241 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
4242 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
4243
4244 input_join = {"i1": topo["routers"]["i1"]["links"]["l1"]["interface"]}
4245
4246 for recvr, recvr_intf in input_join.items():
4247 result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
4248 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
4249
4250 step("Configure RP for (225.1.1.1-5) in (f1)")
4251
4252 input_dict = {
4253 "f1": {
4254 "pim": {
4255 "rp": [
4256 {
4257 "rp_addr": topo["routers"]["f1"]["links"]["lo"]["ipv4"].split(
4258 "/"
4259 )[0],
4260 "group_addr_range": _GROUP_RANGE,
4261 }
4262 ]
4263 }
4264 }
4265 }
4266
4267 result = create_pim_config(tgen, topo, input_dict)
4268 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4269
4270 step("Send multicast traffic from FRR3(r2) to 225.1.1.1-225.1.1.10" " receiver")
4271
4272 input_src = {"i3": topo["routers"]["i3"]["links"]["r2"]["interface"]}
4273
4274 for src, src_intf in input_src.items():
4275 result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
4276 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4277
4278 step(
4279 "'show ip mroute' showing correct RPF and OIF interface for (*,G)"
4280 " and (S,G) entries on all the nodes"
4281 )
4282
4283 source_i3 = topo["routers"]["i3"]["links"]["r2"]["ipv4"].split("/")[0]
4284 input_dict_all = [
4285 {
4286 "dut": "l1",
4287 "src_address": "*",
4288 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
4289 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
4290 },
4291 {
4292 "dut": "l1",
4293 "src_address": source_i3,
4294 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
4295 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
4296 },
4297 {
4298 "dut": "r2",
4299 "src_address": "*",
4300 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
4301 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
4302 },
4303 {
4304 "dut": "r2",
4305 "src_address": source_i3,
4306 "iif": topo["routers"]["r2"]["links"]["i3"]["interface"],
4307 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
4308 },
4309 ]
4310
4311 for data in input_dict_all:
4312 result = verify_mroutes(
4313 tgen,
4314 data["dut"],
4315 data["src_address"],
4316 _IGMP_JOIN_RANGE,
4317 data["iif"],
4318 data["oil"],
4319 )
4320 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4321
4322 for data in input_dict_all:
4323 result = verify_upstream_iif(
4324 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
4325 )
4326 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4327
4328 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["interface"]
4329 intf_f1_r2 = topo["routers"]["f1"]["links"]["r2"]["interface"]
4330 intf_l1_i1 = topo["routers"]["l1"]["links"]["i1"]["interface"]
4331 input_traffic = {
4332 "l1": {"traffic_received": [intf_l1_r2], "traffic_sent": [intf_l1_i1]}
4333 }
4334 result = verify_multicast_traffic(tgen, input_traffic)
4335 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4336
4337 step("Shut the receiver(l1) port in 1 min interval")
4338
4339 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, False)
4340
4341 step(
4342 "Verification: After Shut of receiver port, Verify (*,G) and "
4343 "(S,G) got removed from LHR node (FRR1) using 'show ip mroute'"
4344 )
4345
4346 input_dict_l1 = [
4347 {
4348 "dut": "l1",
4349 "src_address": source_i3,
4350 "iif": topo["routers"]["l1"]["links"]["r2"]["interface"],
4351 "oil": topo["routers"]["l1"]["links"]["i1"]["interface"],
4352 }
4353 ]
4354
4355 for data in input_dict_l1:
4356 result = verify_mroutes(
4357 tgen,
4358 data["dut"],
4359 data["src_address"],
4360 _IGMP_JOIN_RANGE,
4361 data["iif"],
4362 data["oil"],
4363 expected=False,
4364 )
4365 assert result is not True, (
4366 "Testcase {} : Failed \n "
4367 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
4368 "Found: {}".format(tc_name, data["dut"], result)
4369 )
4370
4371 step("No shut the receiver(l1) port in 1 min interval")
4372
4373 shutdown_bringup_interface(tgen, "l1", intf_l1_i1, True)
4374
4375 step(
4376 "Verification: After No shut of receiver port , Verify (*,G)"
4377 " and (S,G) got populated on LHR node (FRR1) using "
4378 "'show ip mroute' 'show ip pim upstream'"
4379 )
4380
4381 for data in input_dict_l1:
4382 result = verify_mroutes(
4383 tgen,
4384 data["dut"],
4385 data["src_address"],
4386 _IGMP_JOIN_RANGE,
4387 data["iif"],
4388 data["oil"],
4389 )
4390 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4391
4392 for data in input_dict_l1:
4393 result = verify_upstream_iif(
4394 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
4395 )
4396 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4397
4398 result = verify_multicast_traffic(tgen, input_traffic)
4399 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4400
4401 step("Shut the source(r2) port in 1 min interval")
4402
4403 intf_r2_i3 = topo["routers"]["r2"]["links"]["i3"]["interface"]
4404 shutdown_bringup_interface(tgen, "r2", intf_r2_i3, False)
4405
4406 step(
4407 "Verification: After Shut of source port, Verify (S,G) got "
4408 "removed from FHR using 'show ip mroute'"
4409 )
4410
4411 input_dict_r2 = [
4412 {
4413 "dut": "r2",
4414 "src_address": source_i3,
4415 "iif": topo["routers"]["r2"]["links"]["i3"]["interface"],
4416 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
4417 }
4418 ]
4419
4420 for data in input_dict_r2:
4421 result = verify_mroutes(
4422 tgen,
4423 data["dut"],
4424 data["src_address"],
4425 _IGMP_JOIN_RANGE,
4426 data["iif"],
4427 data["oil"],
4428 expected=False,
4429 )
4430 assert result is not True, (
4431 "Testcase {} : Failed \n "
4432 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
4433 "Found: {}".format(tc_name, data["dut"], result)
4434 )
4435
4436 step("No shut the source(r2) port in 1 min interval")
4437
4438 shutdown_bringup_interface(tgen, "r2", intf_r2_i3, True)
4439
4440 step(
4441 "Verification: After No shut of source port , Verify (*,G)"
4442 " and (S,G) got populated on LHR and FHR using "
4443 "'show ip mroute' 'show ip pim upstream'"
4444 )
4445
4446 for data in input_dict_r2:
4447 result = verify_mroutes(
4448 tgen,
4449 data["dut"],
4450 data["src_address"],
4451 _IGMP_JOIN_RANGE,
4452 data["iif"],
4453 data["oil"],
4454 )
4455 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4456
4457 for data in input_dict_r2:
4458 result = verify_upstream_iif(
4459 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
4460 )
4461 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4462
4463 result = verify_multicast_traffic(tgen, input_traffic)
4464 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4465
4466 step("Shut FHR to RP port from FHR side")
4467
4468 intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["interface"]
4469 shutdown_bringup_interface(tgen, "r2", intf_r2_f1, False)
4470
4471 step(
4472 "Verification: After Shut of FHR to cisco port, Verify (*,G) "
4473 "got removed from FHR and cisco node using 'show ip mroute'"
4474 )
4475
4476 input_dict_all_star = [
4477 {
4478 "dut": "r2",
4479 "src_address": "*",
4480 "iif": topo["routers"]["r2"]["links"]["f1"]["interface"],
4481 "oil": topo["routers"]["r2"]["links"]["l1"]["interface"],
4482 },
4483 {
4484 "dut": "f1",
4485 "src_address": "*",
4486 "iif": "lo",
4487 "oil": topo["routers"]["f1"]["links"]["r2"]["interface"],
4488 },
4489 ]
4490
4491 for data in input_dict_all_star:
4492 result = verify_mroutes(
4493 tgen,
4494 data["dut"],
4495 data["src_address"],
4496 _IGMP_JOIN_RANGE,
4497 data["iif"],
4498 data["oil"],
4499 expected=False,
4500 )
4501 assert result is not True, (
4502 "Testcase {} : Failed \n "
4503 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
4504 "Found: {}".format(tc_name, data["dut"], result)
4505 )
4506
4507 write_test_footer(tc_name)
4508
4509
4510 def test_PIM_passive_p1(request):
4511 """
4512 TC Verify PIM passive functionality"
4513 """
4514
4515 tgen = get_topogen()
4516 tc_name = request.node.name
4517 write_test_header(tc_name)
4518 app_helper.stop_all_hosts()
4519 # Creating configuration from JSON
4520 clear_mroute(tgen)
4521 if tgen.routers_have_failure():
4522 check_router_status(tgen)
4523 reset_config_on_routers(tgen)
4524 clear_pim_interface_traffic(tgen, topo)
4525
4526 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
4527 step(
4528 "Enable IGMP of FRR1 interface and send IGMP joins "
4529 " from FRR1 node for group range (225.1.1.1-5)"
4530 )
4531
4532 intf_c1_i4 = topo["routers"]["c1"]["links"]["i4"]["interface"]
4533
4534 step(
4535 "configure PIM passive on receiver interface to verify no impact on IGMP join"
4536 "and multicast traffic on pim passive interface"
4537 )
4538
4539 raw_config = {
4540 "c1": {"raw_config": ["interface {}".format(intf_c1_i4), "ip pim passive"]}
4541 }
4542 result = apply_raw_config(tgen, raw_config)
4543 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4544
4545 step("configure IGMPv2 and send IGMP joinon on PIM passive interface")
4546 input_dict = {
4547 "c1": {"igmp": {"interfaces": {intf_c1_i4: {"igmp": {"version": "2"}}}}}
4548 }
4549 result = create_igmp_config(tgen, topo, input_dict)
4550 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
4551
4552 input_join = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
4553 for recvr, recvr_intf in input_join.items():
4554 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
4555 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
4556
4557 step("Configure static RP for (225.1.1.1-5) as R2")
4558
4559 input_dict = {
4560 "r2": {
4561 "pim": {
4562 "rp": [
4563 {
4564 "rp_addr": topo["routers"]["r2"]["links"]["lo"]["ipv4"].split(
4565 "/"
4566 )[0],
4567 "group_addr_range": GROUP_RANGE_1,
4568 }
4569 ]
4570 }
4571 }
4572 }
4573
4574 result = create_pim_config(tgen, topo, input_dict)
4575 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4576
4577 step("Send Mcast traffic from C2 to all the groups ( 225.1.1.1 to 225.1.1.5)")
4578
4579 input_src = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
4580 for src, src_intf in input_src.items():
4581 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
4582 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4583
4584 source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0]
4585
4586 input_dict_starg = [
4587 {
4588 "dut": "c1",
4589 "src_address": "*",
4590 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
4591 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
4592 }
4593 ]
4594
4595 input_dict_sg = [
4596 {
4597 "dut": "c1",
4598 "src_address": source_i5,
4599 "iif": topo["routers"]["c1"]["links"]["c2"]["interface"],
4600 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
4601 }
4602 ]
4603
4604 step("(*,G) and (S,G) created on f1 and node verify using 'show ip mroute'")
4605
4606 for data in input_dict_sg:
4607 result = verify_mroutes(
4608 tgen,
4609 data["dut"],
4610 data["src_address"],
4611 IGMP_JOIN_RANGE_1,
4612 data["iif"],
4613 data["oil"],
4614 )
4615 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4616
4617 for data in input_dict_sg:
4618 result = verify_mroutes(
4619 tgen,
4620 data["dut"],
4621 data["src_address"],
4622 IGMP_JOIN_RANGE_1,
4623 data["iif"],
4624 data["oil"],
4625 )
4626 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4627
4628 for data in input_dict_starg:
4629 result = verify_mroutes(
4630 tgen,
4631 data["dut"],
4632 data["src_address"],
4633 IGMP_JOIN_RANGE_1,
4634 data["iif"],
4635 data["oil"],
4636 )
4637 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4638
4639 intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
4640 intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
4641
4642 step(
4643 "configure PIM passive on upstream interface to verify"
4644 "hello tx/rx counts are not incremented"
4645 )
4646
4647 # Changing hello timer to 3sec for checking more number of packets
4648
4649 raw_config = {
4650 "c1": {
4651 "raw_config": [
4652 "interface {}".format(intf_c1_c2),
4653 "ip pim passive",
4654 "ip pim hello 3",
4655 ]
4656 },
4657 "c2": {"raw_config": ["interface {}".format(intf_c2_c1), "ip pim hello 3"]},
4658 }
4659 result = apply_raw_config(tgen, raw_config)
4660 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4661
4662 step("verify PIM hello tx/rx stats on C1")
4663 state_dict = {
4664 "c1": {
4665 intf_c1_c2: ["helloTx", "helloRx"],
4666 }
4667 }
4668
4669 logger.info("waiting for 5 sec config to get apply and hello count update")
4670 sleep(5)
4671
4672 c1_state_before = verify_pim_interface_traffic(tgen, state_dict)
4673 assert isinstance(
4674 c1_state_before, dict
4675 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
4676 tc_name, result
4677 )
4678
4679 logger.info(
4680 "sleeping for 30 sec hello interval timer to verify count are not increamented"
4681 )
4682 sleep(35)
4683
4684 c1_state_after = verify_pim_interface_traffic(tgen, state_dict)
4685 assert isinstance(
4686 c1_state_after, dict
4687 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
4688 tc_name, result
4689 )
4690
4691 step("verify stats not increamented on c1")
4692 result = verify_pim_stats_increament(c1_state_before, c1_state_after)
4693 assert (
4694 result is not True
4695 ), "Testcase{} : Failed Error: {}" "stats incremented".format(tc_name, result)
4696
4697 step("No impact observed on mroutes")
4698 for data in input_dict_sg:
4699 result = verify_mroutes(
4700 tgen,
4701 data["dut"],
4702 data["src_address"],
4703 IGMP_JOIN_RANGE_1,
4704 data["iif"],
4705 data["oil"],
4706 )
4707 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4708
4709 for data in input_dict_sg:
4710 result = verify_mroutes(
4711 tgen,
4712 data["dut"],
4713 data["src_address"],
4714 IGMP_JOIN_RANGE_1,
4715 data["iif"],
4716 data["oil"],
4717 )
4718 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4719
4720 for data in input_dict_starg:
4721 result = verify_mroutes(
4722 tgen,
4723 data["dut"],
4724 data["src_address"],
4725 IGMP_JOIN_RANGE_1,
4726 data["iif"],
4727 data["oil"],
4728 )
4729 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4730
4731 step("remove PIM passive and verify hello tx/rx is increamented")
4732 raw_config = {
4733 "c1": {
4734 "raw_config": [
4735 "interface {}".format(intf_c1_c2),
4736 "no ip pim passive",
4737 "ip pim hello 3",
4738 ]
4739 }
4740 }
4741 result = apply_raw_config(tgen, raw_config)
4742 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
4743
4744 logger.info("waiting for 30 sec for pim hello to receive")
4745 sleep(30)
4746
4747 c1_state_after = verify_pim_interface_traffic(tgen, state_dict)
4748 assert isinstance(
4749 c1_state_after, dict
4750 ), "Testcase{} : Failed \n state_before is not dictionary \n " "Error: {}".format(
4751 tc_name, result
4752 )
4753
4754 step("verify stats increamented on c1 after removing pim passive")
4755 result = verify_pim_stats_increament(c1_state_before, c1_state_after)
4756 assert result is True, "Testcase{} : Failed Error: {}" "stats incremented".format(
4757 tc_name, result
4758 )
4759
4760 write_test_footer(tc_name)
4761
4762
4763 if __name__ == "__main__":
4764 args = ["-s"] + sys.argv[1:]
4765 sys.exit(pytest.main(args))