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