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