]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py
Merge pull request #12521 from patrasar/issue_11347_fix
[mirror_frr.git] / tests / topotests / multicast_pim_sm_topo2 / test_multicast_pim_sm_topo2.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2020 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation,
6 # Inc. ("NetDEF") in this file.
7 #
8 # Permission to use, copy, modify, and/or distribute this software
9 # for any purpose with or without fee is hereby granted, provided
10 # that the above copyright notice and this permission notice appear
11 # in all copies.
12 #
13 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 # OF THIS SOFTWARE.
21 #
22
23 """
24 Following tests are covered to test multicast pim sm:
25
26 Test steps
27 - Create topology (setup module)
28 - Bring up topology
29
30 Following tests are covered:
31 1. TC_17: Verify (*,G) and (S,G) present and multicast traffic resume,
32 after restart of PIMd daemon
33 2. TC_18: Verify (*,G) and (S,G) present and multicast traffic resume after
34 FRR service stop and start
35 3. TC_10: Verify SPT switchover working when RPT and SPT path is
36 different
37 4. TC_15: Verify (S,G) and (*,G) mroute after shut / no shut of upstream
38 interfaces
39 5. TC_7: Verify mroute detail when receiver is present
40 outside of FRR
41 6. TC_8: Verify mroute when FRR is acting as FHR and LHR
42 7. TC_20: Verify mroute detail when 5 different receiver joining
43 same source
44 8. TC_22: Verify OIL and IIF detail updated in (S,G) mroute after shut
45 and no shut of the source interface
46 """
47
48 import os
49 import sys
50 import time
51 import pytest
52
53 pytestmark = pytest.mark.pimd
54
55 # Save the Current Working Directory to find configuration files.
56 CWD = os.path.dirname(os.path.realpath(__file__))
57 sys.path.append(os.path.join(CWD, "../"))
58 sys.path.append(os.path.join(CWD, "../lib/"))
59
60 # Required to instantiate the topology builder class.
61
62 # pylint: disable=C0413
63 # Import topogen and topotest helpers
64 from lib.topogen import Topogen, get_topogen
65
66 from lib.common_config import (
67 start_topology,
68 write_test_header,
69 write_test_footer,
70 step,
71 reset_config_on_routers,
72 shutdown_bringup_interface,
73 kill_router_daemons,
74 start_router,
75 start_router_daemons,
76 stop_router,
77 required_linux_kernel_version,
78 topo_daemons,
79 )
80 from lib.pim import (
81 create_pim_config,
82 create_igmp_config,
83 verify_igmp_groups,
84 verify_mroutes,
85 get_pim_interface_traffic,
86 verify_upstream_iif,
87 verify_pim_neighbors,
88 verify_pim_state,
89 clear_mroute,
90 clear_pim_interface_traffic,
91 McastTesterHelper,
92 )
93 from lib.topolog import logger
94 from lib.topojson import build_config_from_json
95
96
97 pytestmark = [pytest.mark.pimd]
98
99 TOPOLOGY = """
100
101
102 i4-----c1-------------c2---i5
103 | |
104 | |
105 i1-----l1------r2-----f1---i2
106 | | | |
107 | | | |
108 i7 i6 i3 i8
109
110 Description:
111 i1, i2, i3. i4, i5, i6, i7, i8 - FRR running iperf to send IGMP
112 join and traffic
113 l1 - LHR
114 f1 - FHR
115 r2 - FRR router
116 c1 - FRR router
117 c2 - FRR router
118 """
119
120 # Global variables
121 GROUP_RANGE = "225.0.0.0/8"
122 IGMP_JOIN = "225.1.1.1"
123 GROUP_RANGE_1 = [
124 "225.1.1.1/32",
125 "225.1.1.2/32",
126 "225.1.1.3/32",
127 "225.1.1.4/32",
128 "225.1.1.5/32",
129 ]
130 IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
131 GROUP_RANGE_2 = [
132 "226.1.1.1/32",
133 "226.1.1.2/32",
134 "226.1.1.3/32",
135 "226.1.1.4/32",
136 "226.1.1.5/32",
137 ]
138 IGMP_JOIN_RANGE_2 = ["226.1.1.1", "226.1.1.2", "226.1.1.3", "226.1.1.4", "226.1.1.5"]
139
140 GROUP_RANGE_3 = [
141 "227.1.1.1/32",
142 "227.1.1.2/32",
143 "227.1.1.3/32",
144 "227.1.1.4/32",
145 "227.1.1.5/32",
146 ]
147 IGMP_JOIN_RANGE_3 = ["227.1.1.1", "227.1.1.2", "227.1.1.3", "227.1.1.4", "227.1.1.5"]
148
149
150 def setup_module(mod):
151 """
152 Sets up the pytest environment
153
154 * `mod`: module name
155 """
156
157 # Required linux kernel version for this suite to run.
158 result = required_linux_kernel_version("4.19")
159 if result is not True:
160 pytest.skip("Kernel requirements are not met")
161
162 testsuite_run_time = time.asctime(time.localtime(time.time()))
163 logger.info("Testsuite start time: {}".format(testsuite_run_time))
164 logger.info("=" * 40)
165 logger.info("Master Topology: \n {}".format(TOPOLOGY))
166
167 logger.info("Running setup_module to create topology")
168
169 json_file = "{}/multicast_pim_sm_topo2.json".format(CWD)
170 tgen = Topogen(json_file, mod.__name__)
171 global topo
172 topo = tgen.json_topo
173 # ... and here it calls Mininet initialization functions.
174
175 # Starting topology, create tmp files which are loaded to routers
176 # to start daemons and then start routers
177 start_topology(tgen)
178
179 # Don"t run this test if we have any failure.
180 if tgen.routers_have_failure():
181 pytest.skip(tgen.errors)
182
183 # Creating configuration from JSON
184 build_config_from_json(tgen, topo)
185
186 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
187 global app_helper
188 app_helper = McastTesterHelper(tgen)
189
190 logger.info("Running setup_module() done")
191
192
193 def teardown_module():
194 """Teardown the pytest environment"""
195
196 logger.info("Running teardown_module to delete topology")
197
198 tgen = get_topogen()
199
200 app_helper.cleanup()
201
202 # Stop toplogy and Remove tmp files
203 tgen.stop_topology()
204
205 logger.info(
206 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
207 )
208 logger.info("=" * 40)
209
210
211 #####################################################
212 #
213 # Testcases
214 #
215 #####################################################
216
217
218 def verify_state_incremented(state_before, state_after):
219 """
220 API to compare interface traffic state incrementing
221
222 Parameters
223 ----------
224 * `state_before` : State dictionary for any particular instance
225 * `state_after` : State dictionary for any particular instance
226 """
227
228 for router, state_data in state_before.items():
229 for state, value in state_data.items():
230 if state_before[router][state] >= state_after[router][state]:
231 errormsg = (
232 "[DUT: %s]: state %s value has not"
233 " incremented, Initial value: %s, "
234 "Current value: %s [FAILED!!]"
235 % (
236 router,
237 state,
238 state_before[router][state],
239 state_after[router][state],
240 )
241 )
242 return errormsg
243
244 logger.info(
245 "[DUT: %s]: State %s value is "
246 "incremented, Initial value: %s, Current value: %s"
247 " [PASSED!!]",
248 router,
249 state,
250 state_before[router][state],
251 state_after[router][state],
252 )
253
254 return True
255
256
257 def test_verify_mroute_and_traffic_when_pimd_restarted_p2(request):
258 """
259 TC_17: Verify (*,G) and (S,G) present and multicast traffic resume,
260 after restart of PIMd daemon
261 """
262
263 tgen = get_topogen()
264 tc_name = request.node.name
265 write_test_header(tc_name)
266
267 # Don"t run this test if we have any failure.
268 if tgen.routers_have_failure():
269 pytest.skip(tgen.errors)
270
271 # Creating configuration from JSON
272 app_helper.stop_all_hosts()
273 clear_mroute(tgen)
274 reset_config_on_routers(tgen)
275 clear_pim_interface_traffic(tgen, topo)
276
277 step("Configure static RP for (226.1.1.1-5) in c1")
278 step("Configure static RP for (232.1.1.1-5) in c2")
279
280 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
281 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
282
283 input_dict = {
284 "c1": {
285 "pim": {
286 "rp": [
287 {
288 "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split(
289 "/"
290 )[0],
291 "group_addr_range": GROUP_RANGE_2,
292 }
293 ]
294 }
295 },
296 "c2": {
297 "pim": {
298 "rp": [
299 {
300 "rp_addr": topo["routers"]["c2"]["links"]["lo"]["ipv4"].split(
301 "/"
302 )[0],
303 "group_addr_range": GROUP_RANGE_3,
304 }
305 ]
306 }
307 },
308 }
309
310 result = create_pim_config(tgen, topo, input_dict)
311 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
312
313 step(
314 "Enable IGMP on FRR1 interface and send IGMP join "
315 "(226.1.1.1-5) and (232.1.1.1-5)"
316 )
317 step(
318 "Configure IGMP interface on FRR3 and send IGMP join"
319 " for group (226.1.1.1-5, 232.1.1.1-5)"
320 )
321
322 input_dict = {
323 "f1": {
324 "igmp": {
325 "interfaces": {
326 "f1-i8-eth2": {
327 "igmp": {"version": "2", "query": {"query-interval": 15}}
328 }
329 }
330 }
331 }
332 }
333 result = create_igmp_config(tgen, topo, input_dict)
334 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
335
336 input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
337
338 for recvr, recvr_intf in input_join.items():
339 result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
340 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
341
342 step(
343 "Connect one source to c2 and send multicast traffic all"
344 " the receivers (226.1.1.1-5, 232.1.1.1-5)"
345 )
346 step(
347 "Send multicast traffic from FRR3 to all the receivers "
348 "(226.1.1.1-5, 232.1.1.1-5)"
349 )
350
351 input_src = {"i2": "i2-f1-eth0", "i5": "i5-c2-eth0"}
352
353 for src, src_intf in input_src.items():
354 result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
355 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
356
357 # Verifying mroutes before PIMd restart, fetching uptime
358
359 source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
360 input_dict = [
361 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"},
362 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"},
363 ]
364 for data in input_dict:
365 result = verify_mroutes(
366 tgen,
367 data["dut"],
368 data["src_address"],
369 _IGMP_JOIN_RANGE,
370 data["iif"],
371 data["oil"],
372 )
373 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
374
375 for data in input_dict:
376 result = verify_upstream_iif(
377 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
378 )
379 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
380
381 step("Restart Pimd process on FRR3 node")
382 kill_router_daemons(tgen, "f1", ["pimd"])
383 start_router_daemons(tgen, "f1", ["pimd"])
384
385 for data in input_dict:
386 result = verify_mroutes(
387 tgen,
388 data["dut"],
389 data["src_address"],
390 _IGMP_JOIN_RANGE,
391 data["iif"],
392 data["oil"],
393 )
394 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
395
396 step(
397 "After restart of PIMd verify pim nbr is up , IGMP groups"
398 " received , and (*,G) (S,G) entries populated again ,"
399 " Verify using 'show ip pim neighbor' , 'show ip igmp groups'"
400 " 'show ip mroute'"
401 )
402
403 result = verify_pim_neighbors(tgen, topo)
404 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
405
406 dut = "f1"
407 interface = "f1-i8-eth2"
408 result = verify_igmp_groups(tgen, dut, interface, _IGMP_JOIN_RANGE)
409 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
410
411 for data in input_dict:
412 result = verify_upstream_iif(
413 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
414 )
415 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
416
417 step("Stop the traffic and restart PIMd immediately on FRR3 node")
418 dut = "i2"
419 intf = "i2-f1-eth0"
420 shutdown_bringup_interface(tgen, dut, intf, False)
421
422 kill_router_daemons(tgen, "f1", ["pimd"])
423 start_router_daemons(tgen, "f1", ["pimd"])
424
425 step(
426 "After PIM process come , all the none of (S,G) mroute should"
427 " present on FRR3 'show ip mroute' "
428 )
429
430 input_dict = [
431 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"}
432 ]
433 for data in input_dict:
434 result = verify_mroutes(
435 tgen,
436 data["dut"],
437 data["src_address"],
438 _IGMP_JOIN_RANGE,
439 data["iif"],
440 data["oil"],
441 )
442 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
443
444 input_dict = [
445 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "none"}
446 ]
447 for data in input_dict:
448 result = verify_mroutes(
449 tgen,
450 data["dut"],
451 data["src_address"],
452 _IGMP_JOIN_RANGE,
453 data["iif"],
454 data["oil"],
455 expected=False,
456 )
457 assert (
458 result is not True
459 ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
460 tc_name, result
461 )
462 logger.info("Expected Behavior: {}".format(result))
463
464 write_test_footer(tc_name)
465
466
467 def test_verify_mroute_and_traffic_when_frr_restarted_p2(request):
468 """
469 TC_18: Verify (*,G) and (S,G) present and multicast traffic resume after
470 FRR service stop and start
471 """
472
473 tgen = get_topogen()
474 tc_name = request.node.name
475 write_test_header(tc_name)
476
477 # Don"t run this test if we have any failure.
478 if tgen.routers_have_failure():
479 pytest.skip(tgen.errors)
480
481 # Creating configuration from JSON
482 app_helper.stop_all_hosts()
483 clear_mroute(tgen)
484 reset_config_on_routers(tgen)
485 clear_pim_interface_traffic(tgen, topo)
486
487 step("Configure static RP for (226.1.1.1-5) in c1")
488 step("Configure static RP for (232.1.1.1-5) in c2")
489
490 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
491 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
492
493 input_dict = {
494 "c1": {
495 "pim": {
496 "rp": [
497 {
498 "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split(
499 "/"
500 )[0],
501 "group_addr_range": GROUP_RANGE_2,
502 }
503 ]
504 }
505 },
506 "c2": {
507 "pim": {
508 "rp": [
509 {
510 "rp_addr": topo["routers"]["c2"]["links"]["lo"]["ipv4"].split(
511 "/"
512 )[0],
513 "group_addr_range": GROUP_RANGE_3,
514 }
515 ]
516 }
517 },
518 }
519
520 result = create_pim_config(tgen, topo, input_dict)
521 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
522
523 step(
524 "Enable IGMP on FRR1 interface and send IGMP join "
525 "(226.1.1.1-5) and (232.1.1.1-5)"
526 )
527 step(
528 "Configure IGMP interface on FRR3 and send IGMP join"
529 " for group (226.1.1.1-5, 232.1.1.1-5)"
530 )
531
532 input_dict = {
533 "f1": {
534 "igmp": {
535 "interfaces": {
536 "f1-i8-eth2": {
537 "igmp": {"version": "2", "query": {"query-interval": 15}}
538 }
539 }
540 }
541 }
542 }
543 result = create_igmp_config(tgen, topo, input_dict)
544 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
545
546 input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
547
548 for recvr, recvr_intf in input_join.items():
549 result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
550 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
551
552 step(
553 "Connect one source to c2 and send multicast traffic all"
554 " the receivers (226.1.1.1-5, 232.1.1.1-5)"
555 )
556 step(
557 "Send multicast traffic from FRR3 to all the receivers "
558 "(226.1.1.1-5, 232.1.1.1-5)"
559 )
560
561 input_src = {"i2": "i2-f1-eth0", "i5": "i5-c2-eth0"}
562
563 for src, src_intf in input_src.items():
564 result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
565 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
566
567 step("Verifying mroutes before FRR restart, fetching uptime")
568
569 source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
570 input_dict = [
571 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"},
572 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"},
573 ]
574 for data in input_dict:
575 result = verify_mroutes(
576 tgen,
577 data["dut"],
578 data["src_address"],
579 _IGMP_JOIN_RANGE,
580 data["iif"],
581 data["oil"],
582 )
583 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
584
585 for data in input_dict:
586 result = verify_upstream_iif(
587 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
588 )
589 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
590
591 step("Stop and Start the FRR services on FRR3 node")
592 stop_router(tgen, "f1")
593 start_router(tgen, "f1")
594
595 for data in input_dict:
596 result = verify_mroutes(
597 tgen,
598 data["dut"],
599 data["src_address"],
600 _IGMP_JOIN_RANGE,
601 data["iif"],
602 data["oil"],
603 )
604 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
605
606 step(
607 "After stop and start of FRR service verify pim nbr is up "
608 "IGMP groups received , and (*,G) (S,G) entries populated again"
609 " Verify using 'show ip pim neighbor' , 'show ip igmp groups'"
610 " 'show ip mroute'"
611 )
612
613 result = verify_pim_neighbors(tgen, topo)
614 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
615
616 dut = "f1"
617 interface = "f1-i8-eth2"
618 result = verify_igmp_groups(tgen, dut, interface, _IGMP_JOIN_RANGE)
619 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
620
621 for data in input_dict:
622 result = verify_upstream_iif(
623 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
624 )
625 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
626
627 step("Stop the traffic and stop and start the FRR services on" " FRR3 node")
628 shutdown_bringup_interface(tgen, "i2", "i2-f1-eth0", False)
629
630 stop_router(tgen, "f1")
631 start_router(tgen, "f1")
632
633 step(
634 "After stop and start of FRR services , all the none of (S,G)"
635 " mroute should present on FRR3 node verify using "
636 "'show ip mroute'"
637 )
638
639 input_dict = [
640 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"}
641 ]
642 for data in input_dict:
643 result = verify_mroutes(
644 tgen,
645 data["dut"],
646 data["src_address"],
647 _IGMP_JOIN_RANGE,
648 data["iif"],
649 data["oil"],
650 )
651 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
652
653 input_dict = [
654 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "none"}
655 ]
656 for data in input_dict:
657 result = verify_mroutes(
658 tgen,
659 data["dut"],
660 data["src_address"],
661 _IGMP_JOIN_RANGE,
662 data["iif"],
663 data["oil"],
664 expected=False,
665 )
666 assert (
667 result is not True
668 ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
669 tc_name, result
670 )
671 logger.info("Expected Behavior: {}".format(result))
672
673 write_test_footer(tc_name)
674
675
676 def test_verify_SPT_switchover_when_RPT_and_SPT_path_is_different_p0(request):
677 """
678 TC_10: Verify SPT switchover working when RPT and SPT path is
679 different
680 """
681
682 tgen = get_topogen()
683 tc_name = request.node.name
684 write_test_header(tc_name)
685
686 # Don"t run this test if we have any failure.
687 if tgen.routers_have_failure():
688 pytest.skip(tgen.errors)
689
690 # Creating configuration from JSON
691 app_helper.stop_all_hosts()
692 clear_mroute(tgen)
693 reset_config_on_routers(tgen)
694 clear_pim_interface_traffic(tgen, topo)
695
696 step("Configure static RP for (226.1.1.1-5) and " "(232.1.1.1-5) in c2")
697
698 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
699 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
700
701 input_dict = {
702 "c2": {
703 "pim": {
704 "rp": [
705 {
706 "rp_addr": topo["routers"]["c2"]["links"]["lo"]["ipv4"].split(
707 "/"
708 )[0],
709 "group_addr_range": _GROUP_RANGE,
710 }
711 ]
712 }
713 }
714 }
715
716 result = create_pim_config(tgen, topo, input_dict)
717 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
718
719 step(
720 "Enable IGMP on FRR1 interface and send IGMP join "
721 "(226.1.1.1-5) and (232.1.1.1-5)"
722 )
723
724 result = app_helper.run_join("i1", _IGMP_JOIN_RANGE, "l1")
725 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
726
727 step("Send multicast traffic from FRR3 to '226.1.1.1-5'" ", '232.1.1.1-5' receiver")
728
729 step("registerRx and registerStopTx value before traffic sent")
730 state_dict = {"c2": {"c2-f1-eth1": ["registerRx", "registerStopTx"]}}
731 state_before = get_pim_interface_traffic(tgen, state_dict)
732 assert isinstance(
733 state_before, dict
734 ), "Testcase {} : Failed \n state_before is not dictionary \nError: {}".format(
735 tc_name, result
736 )
737
738 result = app_helper.run_traffic("i2", _IGMP_JOIN_RANGE, "f1")
739 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
740
741 step(
742 "Verify in FRR3 sending initial packet to RP using"
743 " 'show ip mroute' and mroute OIL is towards RP."
744 )
745
746 result = verify_mroutes(
747 tgen,
748 "f1",
749 "10.0.5.2",
750 _IGMP_JOIN_RANGE,
751 "f1-i2-eth1",
752 ["f1-c2-eth0", "f1-r2-eth3"],
753 )
754 assert result is True, "Testcase {} : " "Failed Error: {}".format(tc_name, result)
755
756 result = verify_mroutes(
757 tgen, "f1", "10.0.5.2", _IGMP_JOIN_RANGE, "f1-i2-eth1", "f1-r2-eth3"
758 )
759 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
760
761 step(
762 " After spt switchover traffic is flowing between"
763 " (LHR(FRR1)-FHR(FRR3)) and (S,G) OIL is updated toward FRR1"
764 " 'show ip mroute' and 'show ip pim upstream'"
765 )
766
767 source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
768 input_dict = [
769 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"},
770 {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"},
771 ]
772 for data in input_dict:
773 result = verify_mroutes(
774 tgen,
775 data["dut"],
776 data["src_address"],
777 _IGMP_JOIN_RANGE,
778 data["iif"],
779 data["oil"],
780 )
781 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
782
783 for data in input_dict:
784 result = verify_upstream_iif(
785 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
786 )
787 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
788
789 step("Stop the traffic to all the receivers")
790
791 app_helper.stop_host("i2")
792
793 step(
794 "Null register packet being send periodically from FRR3 to RP, "
795 "verify using show ip mroute on RP, have (S, G) entries null OIL"
796 " 'show ip mroute' and verify show ip pim interface traffic"
797 "(In RP Register msg should be received and Register stop should"
798 " be transmitted)"
799 )
800 input_dict = [
801 {"dut": "c2", "src_address": source, "iif": "c2-f1-eth1", "oil": "none"}
802 ]
803 for data in input_dict:
804 result = verify_mroutes(
805 tgen,
806 data["dut"],
807 data["src_address"],
808 _IGMP_JOIN_RANGE,
809 data["iif"],
810 data["oil"],
811 )
812 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
813
814 step("registerRx and registerStopTx value after traffic sent")
815 state_after = get_pim_interface_traffic(tgen, state_dict)
816 assert isinstance(
817 state_after, dict
818 ), "Testcase {} : Failed \n state_before is not dictionary \nError: {}".format(
819 tc_name, result
820 )
821
822 result = verify_state_incremented(state_before, state_after)
823 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
824
825 write_test_footer(tc_name)
826
827
828 def test_verify_mroute_after_shut_noshut_of_upstream_interface_p1(request):
829 """
830 TC_15: Verify (S,G) and (*,G) mroute after shut / no shut of upstream
831 interfaces
832 """
833
834 tgen = get_topogen()
835 tc_name = request.node.name
836 write_test_header(tc_name)
837
838 # Don"t run this test if we have any failure.
839 if tgen.routers_have_failure():
840 pytest.skip(tgen.errors)
841
842 # Creating configuration from JSON
843 app_helper.stop_all_hosts()
844 clear_mroute(tgen)
845 reset_config_on_routers(tgen)
846 clear_pim_interface_traffic(tgen, topo)
847
848 step("Configure static RP for (226.1.1.1-5) in c1")
849 step("Configure static RP for (232.1.1.1-5) in c2")
850
851 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
852 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
853
854 input_dict = {
855 "c1": {
856 "pim": {
857 "rp": [
858 {
859 "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split(
860 "/"
861 )[0],
862 "group_addr_range": GROUP_RANGE_2,
863 }
864 ]
865 }
866 },
867 "c2": {
868 "pim": {
869 "rp": [
870 {
871 "rp_addr": topo["routers"]["c2"]["links"]["lo"]["ipv4"].split(
872 "/"
873 )[0],
874 "group_addr_range": GROUP_RANGE_3,
875 }
876 ]
877 }
878 },
879 }
880
881 result = create_pim_config(tgen, topo, input_dict)
882 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
883
884 step(
885 "Enable IGMP on FRR1 interface and send IGMP join "
886 "(226.1.1.1-5) and (232.1.1.1-5)"
887 )
888 step(
889 "Configure IGMP interface on FRR3 and send IGMP join"
890 " for group (226.1.1.1-5, 232.1.1.1-5)"
891 )
892
893 input_dict = {
894 "f1": {
895 "igmp": {
896 "interfaces": {
897 "f1-i8-eth2": {
898 "igmp": {"version": "2", "query": {"query-interval": 15}}
899 }
900 }
901 }
902 }
903 }
904 result = create_igmp_config(tgen, topo, input_dict)
905 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
906
907 input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
908
909 for recvr, recvr_intf in input_join.items():
910 result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
911 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
912
913 step(
914 "Connect one source to c2 and send multicast traffic all"
915 " the receivers (226.1.1.1-5, 232.1.1.1-5)"
916 )
917 step(
918 "Send multicast traffic from FRR3 to all the receivers "
919 "(226.1.1.1-5, 232.1.1.1-5)"
920 )
921
922 input_src = {"i2": "i2-f1-eth0", "i5": "i5-c2-eth0"}
923
924 for src, src_intf in input_src.items():
925 result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
926 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
927
928 step(
929 "FRR3 (S,G) has one OIL for local receiver one toward c2"
930 " verify 'show ip mroute' and 'show ip pim upstream'"
931 )
932
933 source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
934 input_dict = [
935 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"},
936 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-i8-eth2"},
937 ]
938 for data in input_dict:
939 result = verify_mroutes(
940 tgen,
941 data["dut"],
942 data["src_address"],
943 IGMP_JOIN_RANGE_2,
944 data["iif"],
945 data["oil"],
946 )
947 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
948
949 for data in input_dict:
950 result = verify_upstream_iif(
951 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_2
952 )
953 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
954
955 step("Shut and No shut interface connected from FHR (FRR3)" " to c2")
956 dut = "f1"
957 intf = "f1-c2-eth0"
958 shutdown_bringup_interface(tgen, dut, intf, False)
959 shutdown_bringup_interface(tgen, dut, intf, True)
960
961 step("Shut and No shut interface connected from LHR (FRR1)" " to c1")
962 dut = "l1"
963 intf = "l1-c1-eth0"
964 shutdown_bringup_interface(tgen, dut, intf, False)
965 shutdown_bringup_interface(tgen, dut, intf, True)
966
967 for data in input_dict:
968 result = verify_mroutes(
969 tgen,
970 data["dut"],
971 data["src_address"],
972 IGMP_JOIN_RANGE_2,
973 data["iif"],
974 data["oil"],
975 )
976 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
977
978 step("Shut and No shut FRR1 and FRR3 interface")
979 shutdown_bringup_interface(tgen, "l1", "l1-r2-eth4", False)
980 shutdown_bringup_interface(tgen, dut, intf, True)
981
982 shutdown_bringup_interface(tgen, "f1", "f1-r2-eth3", False)
983 shutdown_bringup_interface(tgen, dut, intf, True)
984
985 step(
986 "After shut/no shut of interface , verify traffic resume to all"
987 "the receivers (S,G) OIL update for all the receivers"
988 )
989
990 for data in input_dict:
991 result = verify_mroutes(
992 tgen,
993 data["dut"],
994 data["src_address"],
995 IGMP_JOIN_RANGE_2,
996 data["iif"],
997 data["oil"],
998 )
999 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1000
1001 step(
1002 "Shut FRR1, FRR3 interface , clear mroute in FRR1"
1003 " and No shut FRR1, FRR3 interface "
1004 )
1005 dut = "l1"
1006 intf = "l1-r2-eth4"
1007 shutdown_bringup_interface(tgen, dut, intf, False)
1008
1009 dut = "f1"
1010 intf = "f1-r2-eth3"
1011 shutdown_bringup_interface(tgen, dut, intf, False)
1012
1013 dut = "l1"
1014 intf = "l1-r2-eth4"
1015 shutdown_bringup_interface(tgen, dut, intf, True)
1016
1017 dut = "f1"
1018 intf = "f1-r2-eth3"
1019 shutdown_bringup_interface(tgen, dut, intf, True)
1020
1021 clear_mroute(tgen, "l1")
1022 clear_mroute(tgen, "l1")
1023
1024 step(
1025 "After no shut, verify traffic resume to all the receivers"
1026 " (S,G) OIL update for all the receivers"
1027 )
1028
1029 for data in input_dict:
1030 result = verify_mroutes(
1031 tgen,
1032 data["dut"],
1033 data["src_address"],
1034 IGMP_JOIN_RANGE_2,
1035 data["iif"],
1036 data["oil"],
1037 )
1038 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1039
1040 step(
1041 "Shut and no shut upstream interface from FRR1 to FRR2 and "
1042 "cisco immediate after mroute/upstream got cleared"
1043 )
1044
1045 dut = "l1"
1046 intf_l1_r2 = "l1-r2-eth4"
1047 shutdown_bringup_interface(tgen, dut, intf_l1_r2, False)
1048
1049 intf_l1_c1 = "l1-c1-eth0"
1050 shutdown_bringup_interface(tgen, dut, intf_l1_c1, False)
1051
1052 result = verify_upstream_iif(
1053 tgen, "l1", "Unknown", source, IGMP_JOIN_RANGE_2, expected=False
1054 )
1055 assert result is not True, (
1056 "Testcase {} : Failed Error: \n "
1057 "mroutes are still present, after waiting for 10 mins".format(tc_name)
1058 )
1059
1060 step("No shut the Source interface just after the upstream is expired" " from FRR1")
1061 shutdown_bringup_interface(tgen, dut, intf_l1_r2, True)
1062 shutdown_bringup_interface(tgen, dut, intf_l1_c1, True)
1063
1064 for data in input_dict:
1065 result = verify_mroutes(
1066 tgen,
1067 data["dut"],
1068 data["src_address"],
1069 IGMP_JOIN_RANGE_2,
1070 data["iif"],
1071 data["oil"],
1072 )
1073 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1074
1075 step("Stop the traffic to all the receivers")
1076 app_helper.stop_all_hosts()
1077
1078 for data in input_dict:
1079 result = verify_mroutes(
1080 tgen,
1081 data["dut"],
1082 data["src_address"],
1083 IGMP_JOIN_RANGE_2,
1084 data["iif"],
1085 data["oil"],
1086 expected=False,
1087 )
1088 assert (
1089 result is not True
1090 ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
1091 tc_name, result
1092 )
1093 logger.info("Expected Behavior: {}".format(result))
1094
1095 write_test_footer(tc_name)
1096
1097
1098 def test_verify_mroute_when_receiver_is_outside_frr_p0(request):
1099 """
1100 TC_7: Verify mroute detail when receiver is present
1101 outside of FRR
1102 """
1103
1104 tgen = get_topogen()
1105 tc_name = request.node.name
1106 write_test_header(tc_name)
1107
1108 # Don"t run this test if we have any failure.
1109 if tgen.routers_have_failure():
1110 pytest.skip(tgen.errors)
1111
1112 # Creating configuration from JSON
1113 app_helper.stop_all_hosts()
1114 clear_mroute(tgen)
1115 reset_config_on_routers(tgen)
1116 clear_pim_interface_traffic(tgen, topo)
1117
1118 step("Configure static RP on c1 for group range " "(226.1.1.1-5) and (232.1.1.1-5)")
1119
1120 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
1121 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
1122
1123 input_dict = {
1124 "c1": {
1125 "pim": {
1126 "rp": [
1127 {
1128 "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split(
1129 "/"
1130 )[0],
1131 "group_addr_range": _GROUP_RANGE,
1132 }
1133 ]
1134 }
1135 }
1136 }
1137
1138 result = create_pim_config(tgen, topo, input_dict)
1139 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1140
1141 step(
1142 "Enable IGMP on FRR1 interface and send IGMP join"
1143 " (226.1.1.1-5) and (232.1.1.1-5)"
1144 )
1145 result = app_helper.run_join("i1", _IGMP_JOIN_RANGE, "l1")
1146 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1147
1148 step(
1149 "Send multicast traffic from FRR3 to all the receivers "
1150 "(226.1.1.1-5) and (232.1.1.1-5)"
1151 )
1152 result = app_helper.run_traffic("i2", _IGMP_JOIN_RANGE, "f1")
1153 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1154
1155 step(
1156 "Configure one more receiver in c2 enable IGMP and send"
1157 " join (226.1.1.1-5) and (232.1.1.1-5)"
1158 )
1159 input_dict = {
1160 "c2": {
1161 "igmp": {
1162 "interfaces": {
1163 "c2-i5-eth2": {
1164 "igmp": {"version": "2", "query": {"query-interval": 15}}
1165 }
1166 }
1167 }
1168 }
1169 }
1170 result = create_igmp_config(tgen, topo, input_dict)
1171 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1172
1173 result = app_helper.run_join("i5", _IGMP_JOIN_RANGE, "c2")
1174 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1175
1176 step("FRR1 has 10 (*.G) and 10 (S,G) verify using 'show ip mroute count'")
1177 step(
1178 "All the receiver are receiving traffic on FRR1 and (S,G) OIL is toward"
1179 "receivers, verify using 'show ip mroute' 'show ip pim upstream'"
1180 )
1181 step(
1182 "All the receiver are receiving traffic on c2 and (S,G) OIL is "
1183 "toward receivers, verify using 'show ip mroute' 'show ip pim upstream'"
1184 )
1185
1186 source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
1187 input_dict = [
1188 {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"},
1189 {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"},
1190 {"dut": "c2", "src_address": "*", "iif": "c2-c1-eth0", "oil": "c2-i5-eth2"},
1191 {"dut": "c2", "src_address": source, "iif": "c2-f1-eth1", "oil": "c2-i5-eth2"},
1192 ]
1193 for data in input_dict:
1194 result = verify_mroutes(
1195 tgen,
1196 data["dut"],
1197 data["src_address"],
1198 _IGMP_JOIN_RANGE,
1199 data["iif"],
1200 data["oil"],
1201 )
1202 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1203
1204 step(
1205 "FRR3 has (S,G) OIL created toward c1/c2 receiver and FRR1 receiver"
1206 "'show ip pim state'"
1207 )
1208 input_dict = [
1209 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-c2-eth0"},
1210 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"},
1211 ]
1212 for data in input_dict:
1213 result = verify_pim_state(
1214 tgen,
1215 data["dut"],
1216 data["iif"],
1217 data["oil"],
1218 _IGMP_JOIN_RANGE,
1219 data["src_address"],
1220 )
1221 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1222
1223 for data in input_dict:
1224 result = verify_upstream_iif(
1225 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
1226 )
1227 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1228
1229 write_test_footer(tc_name)
1230
1231
1232 def test_verify_mroute_when_FRR_is_FHR_and_LHR_p0(request):
1233 """
1234 TC_8: Verify mroute when FRR is acting as FHR and LHR
1235 """
1236
1237 tgen = get_topogen()
1238 tc_name = request.node.name
1239 write_test_header(tc_name)
1240
1241 # Don"t run this test if we have any failure.
1242 if tgen.routers_have_failure():
1243 pytest.skip(tgen.errors)
1244
1245 # Creating configuration from JSON
1246 app_helper.stop_all_hosts()
1247 clear_mroute(tgen)
1248 reset_config_on_routers(tgen)
1249 clear_pim_interface_traffic(tgen, topo)
1250
1251 step("Configure static RP for group range (226.1.1.1-5) and " "(232.1.1.1-5) on c1")
1252 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
1253 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
1254
1255 input_dict = {
1256 "c1": {
1257 "pim": {
1258 "rp": [
1259 {
1260 "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split(
1261 "/"
1262 )[0],
1263 "group_addr_range": _GROUP_RANGE,
1264 }
1265 ]
1266 }
1267 }
1268 }
1269
1270 result = create_pim_config(tgen, topo, input_dict)
1271 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1272
1273 step(
1274 "Enable IGMP on FRR1 interface and send IGMP join (226.1.1.1-5)"
1275 " and (232.1.1.1-5)"
1276 )
1277 step(
1278 "Configure receiver on FRR3 with igmp and pim enabled and "
1279 "send IGMP join (226.1.1.1-5) and (232.1.1.1-5)"
1280 )
1281 step(
1282 "Send multicast traffic from FRR3 to all the receivers "
1283 "(226.1.1.1-5) and (232.1.1.1-5)"
1284 )
1285
1286 step("Send IGMP join (226.1.1.1-5, 232.1.1.1-5) to LHR(l1)")
1287 result = app_helper.run_join("i1", _IGMP_JOIN_RANGE, "l1")
1288 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1289
1290 step("Send multicast traffic from FRR3 to '226.1.1.1-5'" ", '232.1.1.1-5' receiver")
1291 result = app_helper.run_traffic("i2", _IGMP_JOIN_RANGE, "f1")
1292 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1293
1294 step(
1295 "Configure receiver in f1 enable IGMP and send"
1296 " join (226.1.1.1-5) and (232.1.1.1-5)"
1297 )
1298
1299 step("Configure one IGMP interface on f1 node and send IGMP" " join (225.1.1.1)")
1300 input_dict = {
1301 "f1": {
1302 "igmp": {
1303 "interfaces": {
1304 "f1-i8-eth2": {
1305 "igmp": {"version": "2", "query": {"query-interval": 15}}
1306 }
1307 }
1308 }
1309 }
1310 }
1311 result = create_igmp_config(tgen, topo, input_dict)
1312 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1313
1314 result = app_helper.run_join("i8", _IGMP_JOIN_RANGE, "f1")
1315 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1316 step(
1317 "l1 and f1 has 10 IGMP groups (226.1.1.1-5, 232.1.1.1-5),"
1318 " verify using 'show ip igmp groups'"
1319 )
1320 dut = "l1"
1321 interface = "l1-i1-eth1"
1322 result = verify_igmp_groups(tgen, dut, interface, _IGMP_JOIN_RANGE)
1323 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1324
1325 dut = "f1"
1326 interface = "f1-i8-eth2"
1327 result = verify_igmp_groups(tgen, dut, interface, _IGMP_JOIN_RANGE)
1328 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1329
1330 step(
1331 "l1 , f1 has 10 (*,G) and 10 (S,G) for groups "
1332 "(226.1.1.1-5, 232.1.1.1-5), verify using "
1333 " 'show ip mroute'"
1334 )
1335
1336 source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
1337 input_dict = [
1338 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"},
1339 {"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"},
1340 {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"},
1341 {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"},
1342 ]
1343 for data in input_dict:
1344 result = verify_mroutes(
1345 tgen,
1346 data["dut"],
1347 data["src_address"],
1348 _IGMP_JOIN_RANGE,
1349 data["iif"],
1350 data["oil"],
1351 )
1352 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1353
1354 step("Join timer is running in FHR and LHR , verify using" " 'show ip pim state'")
1355
1356 for data in input_dict:
1357 result = verify_pim_state(
1358 tgen,
1359 data["dut"],
1360 data["iif"],
1361 data["oil"],
1362 _IGMP_JOIN_RANGE,
1363 data["src_address"],
1364 )
1365 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1366
1367 # Stop the multicast traffic
1368 step("Stop the traffic to all the receivers")
1369 app_helper.stop_all_hosts()
1370
1371 step(
1372 "After traffic stopped , verify (*,G) entries are not flushed"
1373 " out from FRR1 node verify using 'show ip mroute' "
1374 )
1375
1376 input_dict = [
1377 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"},
1378 {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"},
1379 ]
1380 for data in input_dict:
1381 result = verify_mroutes(
1382 tgen,
1383 data["dut"],
1384 data["src_address"],
1385 _IGMP_JOIN_RANGE,
1386 data["iif"],
1387 data["oil"],
1388 )
1389 assert (
1390 result is True
1391 ), "Testcase {} : Failed Error mroutes were flushed.".format(tc_name)
1392
1393 step(
1394 "After traffic stopped , verify (S,G) entries are flushed out"
1395 " from FRR1 node verify using 'show ip mroute' "
1396 )
1397
1398 input_dict = [
1399 {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"},
1400 {"dut": "f1", "src_address": source, "iif": "i2-f1-eth0", "oil": "f1-r2-eth3"},
1401 ]
1402
1403 for data in input_dict:
1404 result = verify_mroutes(
1405 tgen,
1406 data["dut"],
1407 data["src_address"],
1408 _IGMP_JOIN_RANGE,
1409 data["iif"],
1410 data["oil"],
1411 expected=False,
1412 )
1413 assert (
1414 result is not True
1415 ), "Testcase {} : Failed Error: \nmroutes are still present".format(tc_name)
1416
1417 write_test_footer(tc_name)
1418
1419
1420 def test_verify_mroute_when_5_different_receiver_joining_same_sources_p0(request):
1421 """
1422 TC_20: Verify mroute detail when 5 different receiver joining
1423 same source
1424 """
1425
1426 tgen = get_topogen()
1427 tc_name = request.node.name
1428 write_test_header(tc_name)
1429
1430 # Don"t run this test if we have any failure.
1431 if tgen.routers_have_failure():
1432 pytest.skip(tgen.errors)
1433
1434 # Creating configuration from JSON
1435 app_helper.stop_all_hosts()
1436 clear_mroute(tgen)
1437 reset_config_on_routers(tgen)
1438 clear_pim_interface_traffic(tgen, topo)
1439
1440 step("Configure static RP for (226.1.1.1-5) in c1")
1441 step("Configure static RP for (232.1.1.1-5) in c2")
1442
1443 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
1444 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
1445
1446 input_dict = {
1447 "c1": {
1448 "pim": {
1449 "rp": [
1450 {
1451 "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split(
1452 "/"
1453 )[0],
1454 "group_addr_range": GROUP_RANGE_2,
1455 }
1456 ]
1457 }
1458 },
1459 "c2": {
1460 "pim": {
1461 "rp": [
1462 {
1463 "rp_addr": topo["routers"]["c2"]["links"]["lo"]["ipv4"].split(
1464 "/"
1465 )[0],
1466 "group_addr_range": GROUP_RANGE_3,
1467 }
1468 ]
1469 }
1470 },
1471 }
1472
1473 result = create_pim_config(tgen, topo, input_dict)
1474 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1475
1476 step(
1477 "Configure 2 IGMP interface on FRR1 and send IGMP join"
1478 "for group (226.1.1.1-5, 232.1.1.1-5) from both the interface"
1479 )
1480 step(
1481 "Configure 2 IGMP interface on FRR3 and send IGMP join for"
1482 " group (226.1.1.1-5, 232.1.1.1-5) from both the interface"
1483 )
1484 step(
1485 "Configure 1 IGMP interface on c2 and send IGMP join for"
1486 "group (226.1.1.1-5, 232.1.1.1-5)"
1487 )
1488
1489 input_dict = {
1490 "f1": {
1491 "igmp": {
1492 "interfaces": {
1493 "f1-i8-eth2": {
1494 "igmp": {"version": "2", "query": {"query-interval": 15}}
1495 },
1496 "f1-i2-eth1": {
1497 "igmp": {"version": "2", "query": {"query-interval": 15}}
1498 },
1499 }
1500 }
1501 },
1502 "l1": {
1503 "igmp": {
1504 "interfaces": {
1505 "l1-i6-eth2": {
1506 "igmp": {"version": "2", "query": {"query-interval": 15}}
1507 }
1508 }
1509 }
1510 },
1511 }
1512 result = create_igmp_config(tgen, topo, input_dict)
1513 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1514
1515 input_join = {
1516 "i1": "i1-l1-eth0",
1517 "i6": "i6-l1-eth0",
1518 "i8": "i8-f1-eth0",
1519 "i2": "i2-f1-eth0",
1520 }
1521
1522 for recvr, recvr_intf in input_join.items():
1523 result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
1524 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1525
1526 step("Configure one source in FRR2 , one in c1")
1527 step(
1528 "Send multicast traffic from both the sources to all the"
1529 "receivers (226.1.1.1-5, 232.1.1.1-5)"
1530 )
1531
1532 input_src = {"i3": "i3-r2-eth0"}
1533
1534 for src, src_intf in input_src.items():
1535 result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
1536 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1537 step(
1538 "After all the IGMP groups received with correct port using"
1539 " 'show ip igmp groups' in FRR1, FRR3, c2"
1540 )
1541 dut = "l1"
1542 interface = "l1-i6-eth2"
1543 result = verify_igmp_groups(tgen, dut, interface, _IGMP_JOIN_RANGE)
1544 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1545
1546 dut = "f1"
1547 interface = "f1-i8-eth2"
1548 result = verify_igmp_groups(tgen, dut, interface, _IGMP_JOIN_RANGE)
1549 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1550
1551 step(
1552 "(*,G) entries got created with upstream interface RP connected"
1553 " port using 'show ip pim upstream' in FRR1, FRR3, c2"
1554 )
1555 step(
1556 "(S,G) entries created for all the receiver after starting the"
1557 " source , traffic is reaching to all the receiver , verify OIL"
1558 " of (S,G) is receiver port using 'show ip mroute' in FRR1, "
1559 "FRR3 c2"
1560 )
1561
1562 source = topo["routers"]["i3"]["links"]["r2"]["ipv4"].split("/")[0]
1563 input_dict_all = [
1564 {
1565 "dut": "l1",
1566 "src_address": source,
1567 "iif": ["l1-r2-eth4", "l1-c1-eth0"],
1568 "oil": ["l1-i1-eth1", "l1-i6-eth2"],
1569 },
1570 {"dut": "f1", "src_address": source, "iif": "f1-r2-eth3", "oil": "f1-i8-eth2"},
1571 ]
1572 for data in input_dict_all:
1573 result = verify_mroutes(
1574 tgen,
1575 data["dut"],
1576 data["src_address"],
1577 _IGMP_JOIN_RANGE,
1578 data["iif"],
1579 data["oil"],
1580 )
1581 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1582
1583 for data in input_dict_all:
1584 result = verify_upstream_iif(
1585 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
1586 )
1587 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1588
1589 step("Shut the receiver interface one by one on FRR1 node")
1590 shutdown_bringup_interface(tgen, "l1", "l1-i1-eth1", False)
1591 shutdown_bringup_interface(tgen, "l1", "l1-i6-eth2", False)
1592
1593 step(
1594 "After shut the receiver port verify traffic is stopped immediately"
1595 " and (S,G) got timeout immediately in FRR1, FRR3, c2"
1596 )
1597 input_dict = [
1598 {"dut": "l1", "src_address": source, "iif": "l1-r2-eth4", "oil": "l1-i1-eth1"}
1599 ]
1600 for data in input_dict:
1601 result = verify_mroutes(
1602 tgen,
1603 data["dut"],
1604 data["src_address"],
1605 IGMP_JOIN_RANGE_2,
1606 data["iif"],
1607 data["oil"],
1608 expected=False,
1609 )
1610 assert (
1611 result is not True
1612 ), "Testcase {} : Failed \n mroutes are still present \n Error: {}".format(
1613 tc_name, result
1614 )
1615 logger.info("Expected Behavior: {}".format(result))
1616
1617 step(
1618 "No traffic impact observed on other receivers verify using"
1619 " 'show ip mroute' "
1620 )
1621 input_dict = [
1622 {"dut": "f1", "src_address": source, "iif": "f1-r2-eth3", "oil": "f1-i8-eth2"}
1623 ]
1624 for data in input_dict:
1625 result = verify_mroutes(
1626 tgen,
1627 data["dut"],
1628 data["src_address"],
1629 _IGMP_JOIN_RANGE,
1630 data["iif"],
1631 data["oil"],
1632 )
1633 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1634
1635 step("No shut the receiver interface one by one on FRR1 node")
1636 shutdown_bringup_interface(tgen, "l1", "l1-i1-eth1", True)
1637 shutdown_bringup_interface(tgen, "l1", "l1-i6-eth2", True)
1638
1639 step(
1640 "After no shut of receivers all the mroute entries got populated"
1641 ", no duplicate entries present in mroute"
1642 )
1643
1644 for data in input_dict_all:
1645 result = verify_mroutes(
1646 tgen,
1647 data["dut"],
1648 data["src_address"],
1649 _IGMP_JOIN_RANGE,
1650 data["iif"],
1651 data["oil"],
1652 )
1653 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1654
1655 write_test_footer(tc_name)
1656
1657
1658 def test_verify_oil_iif_for_mroute_after_shut_noshut_source_interface_p1(request):
1659 """
1660 TC_22: Verify OIL and IIF detail updated in (S,G) mroute after shut
1661 and no shut of the source interface
1662 """
1663
1664 tgen = get_topogen()
1665 tc_name = request.node.name
1666 write_test_header(tc_name)
1667
1668 # Don"t run this test if we have any failure.
1669 if tgen.routers_have_failure():
1670 pytest.skip(tgen.errors)
1671
1672 # Creating configuration from JSON
1673 app_helper.stop_all_hosts()
1674 clear_mroute(tgen)
1675 reset_config_on_routers(tgen)
1676 clear_pim_interface_traffic(tgen, topo)
1677
1678 step("Configure static RP for (226.1.1.1-5) in c1")
1679 step("Configure static RP for (232.1.1.1-5) in c2")
1680
1681 _GROUP_RANGE = GROUP_RANGE_2 + GROUP_RANGE_3
1682 _IGMP_JOIN_RANGE = IGMP_JOIN_RANGE_2 + IGMP_JOIN_RANGE_3
1683
1684 input_dict = {
1685 "c1": {
1686 "pim": {
1687 "rp": [
1688 {
1689 "rp_addr": topo["routers"]["c1"]["links"]["lo"]["ipv4"].split(
1690 "/"
1691 )[0],
1692 "group_addr_range": GROUP_RANGE_2,
1693 }
1694 ]
1695 }
1696 },
1697 "c2": {
1698 "pim": {
1699 "rp": [
1700 {
1701 "rp_addr": topo["routers"]["c2"]["links"]["lo"]["ipv4"].split(
1702 "/"
1703 )[0],
1704 "group_addr_range": GROUP_RANGE_3,
1705 }
1706 ]
1707 }
1708 },
1709 }
1710
1711 result = create_pim_config(tgen, topo, input_dict)
1712 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1713
1714 step(
1715 "Configure IGMP interface on FRR1 and FRR3 and send IGMP join"
1716 " for group (226.1.1.1-5, 232.1.1.1-5)"
1717 )
1718
1719 input_dict = {
1720 "f1": {
1721 "igmp": {
1722 "interfaces": {
1723 "f1-i8-eth2": {
1724 "igmp": {"version": "2", "query": {"query-interval": 15}}
1725 }
1726 }
1727 }
1728 }
1729 }
1730 result = create_igmp_config(tgen, topo, input_dict)
1731 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1732
1733 input_join = {"i1": "i1-l1-eth0", "i8": "i8-f1-eth0"}
1734
1735 for recvr, recvr_intf in input_join.items():
1736 result = app_helper.run_join(recvr, _IGMP_JOIN_RANGE, join_intf=recvr_intf)
1737 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
1738
1739 step("Configure 1 source in FRR1 , 1 in FRR3")
1740 step(
1741 "Send multicast traffic from both the sources to all the "
1742 "receivers (226.1.1.1-5, 232.1.1.1-5)"
1743 )
1744
1745 input_src = {"i6": "i6-l1-eth0", "i2": "i2-f1-eth0"}
1746
1747 for src, src_intf in input_src.items():
1748 result = app_helper.run_traffic(src, _IGMP_JOIN_RANGE, bind_intf=src_intf)
1749 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1750
1751 step(
1752 "*,G) is created and (S,G) created on FRR1 and FRR3 for both"
1753 " the source verify using 'show ip mroute' and "
1754 " 'show ip pim upstream' to check the upstream interface"
1755 " details"
1756 )
1757
1758 source_i6 = topo["routers"]["i6"]["links"]["l1"]["ipv4"].split("/")[0]
1759 source_i2 = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
1760 input_dict_all = [
1761 {"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"},
1762 {
1763 "dut": "l1",
1764 "src_address": source_i2,
1765 "iif": "l1-r2-eth4",
1766 "oil": "l1-i1-eth1",
1767 },
1768 {
1769 "dut": "l1",
1770 "src_address": source_i6,
1771 "iif": "l1-i6-eth2",
1772 "oil": "l1-i1-eth1",
1773 },
1774 {"dut": "f1", "src_address": "*", "iif": "f1-c2-eth0", "oil": "f1-i8-eth2"},
1775 {
1776 "dut": "f1",
1777 "src_address": source_i2,
1778 "iif": "f1-i2-eth1",
1779 "oil": "f1-i8-eth2",
1780 },
1781 {
1782 "dut": "f1",
1783 "src_address": source_i6,
1784 "iif": "f1-r2-eth3",
1785 "oil": "f1-i8-eth2",
1786 },
1787 ]
1788 for data in input_dict_all:
1789 result = verify_mroutes(
1790 tgen,
1791 data["dut"],
1792 data["src_address"],
1793 _IGMP_JOIN_RANGE,
1794 data["iif"],
1795 data["oil"],
1796 )
1797 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1798
1799 for data in input_dict_all:
1800 result = verify_upstream_iif(
1801 tgen, data["dut"], data["iif"], data["src_address"], _IGMP_JOIN_RANGE
1802 )
1803 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1804
1805 step("Shut the source interface one by one on FRR1")
1806 shutdown_bringup_interface(tgen, "f1", "f1-i2-eth1", False)
1807
1808 step(
1809 "After shut of ource interface from FRR3 verify all the (S,G) "
1810 "entries flushed out from FRR3 node 'show ip pim upstream' "
1811 " 'show ip mroute' "
1812 )
1813
1814 result = verify_mroutes(
1815 tgen,
1816 "f1",
1817 source_i2,
1818 _IGMP_JOIN_RANGE,
1819 "f1-i2-eth1",
1820 "f1-i8-eth2",
1821 expected=False,
1822 )
1823 assert (
1824 result is not True
1825 ), "Testcase {} : Failed \n mroutes are" " still present \n Error: {}".format(
1826 tc_name, result
1827 )
1828 logger.info("Expected Behavior: {}".format(result))
1829
1830 result = verify_upstream_iif(
1831 tgen, "f1", "Unknown", "10.0.5.2", _IGMP_JOIN_RANGE, joinState="NotJoined"
1832 )
1833 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1834
1835 write_test_footer(tc_name)
1836
1837
1838 if __name__ == "__main__":
1839 args = ["-s"] + sys.argv[1:]
1840 sys.exit(pytest.main(args))