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