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