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