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