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