]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / multicast_pim_sm_topo3 / test_multicast_pim_sm_topo4.py
CommitLineData
693a44e1 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
693a44e1 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#
693a44e1 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:
18
191. TC:48 Verify mroute after configuring black-hole route for RP and source
202. TC:49 Verify mroute when RP is reachable using default route
213. TC:50 Verify mroute when LHR,FHR,RP and transit routers reachable
22 using default routes
234. TC:52 Verify PIM nbr after changing interface ip
245. TC:53 Verify IGMP interface updated with correct detail after changing interface config
256. TC:54 Verify received and transmit hello stats are getting cleared after PIM nbr reset
26
27
28"""
29
30import os
693a44e1 31import sys
693a44e1 32import time
693a44e1 33import pytest
34
7ed8fcff
DS
35pytestmark = pytest.mark.pimd
36
693a44e1 37# Save the Current Working Directory to find configuration files.
38CWD = os.path.dirname(os.path.realpath(__file__))
39sys.path.append(os.path.join(CWD, "../"))
40sys.path.append(os.path.join(CWD, "../lib/"))
41
42# Required to instantiate the topology builder class.
43
44# pylint: disable=C0413
45# Import topogen and topotest helpers
46from lib.topogen import Topogen, get_topogen
693a44e1 47
48from lib.common_config import (
49 start_topology,
50 write_test_header,
51 write_test_footer,
52 step,
693a44e1 53 reset_config_on_routers,
693a44e1 54 shutdown_bringup_interface,
693a44e1 55 apply_raw_config,
56 create_static_routes,
57 required_linux_kernel_version,
58 topo_daemons,
59)
60from lib.pim import (
61 create_pim_config,
62 create_igmp_config,
4fafd29f
KK
63 verify_mroutes,
64 clear_pim_interface_traffic,
693a44e1 65 verify_upstream_iif,
4fafd29f 66 clear_mroute,
693a44e1 67 verify_pim_rp_info,
0b01a0bb 68 get_pim_interface_traffic,
1973df1d 69 McastTesterHelper,
693a44e1 70)
71from lib.topolog import logger
4953ca97 72from lib.topojson import build_config_from_json
758999b3
DS
73from time import sleep
74
693a44e1 75
693a44e1 76TOPOLOGY = """
77
78
79 i4-----c1-------------c2---i5
80 | |
81 | |
82 i1-----l1------r2-----f1---i2
83 | | | |
84 | | | |
85 i7 i6 i3 i8
86
87 Description:
88 i1, i2, i3. i4, i5, i6, i7, i8 - FRR running iperf to send IGMP
89 join and traffic
90 l1 - LHR
91 f1 - FHR
92 r2 - FRR router
93 c1 - FRR router
94 c2 - FRR router
95"""
96
97# Global variables
98
99GROUP_RANGE = "224.0.0.0/4"
100IGMP_GROUP = "225.1.1.1/32"
101IGMP_JOIN = "225.1.1.1"
102GROUP_RANGE_1 = [
103 "225.1.1.1/32",
104 "225.1.1.2/32",
105 "225.1.1.3/32",
106 "225.1.1.4/32",
107 "225.1.1.5/32",
108]
109IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
110NEW_ADDRESS_1 = "192.168.20.1"
111NEW_ADDRESS_2 = "192.168.20.2"
112NEW_ADDRESS_1_SUBNET = "192.168.20.1/24"
113NEW_ADDRESS_2_SUBNET = "192.168.20.2/24"
114
115
693a44e1 116def setup_module(mod):
117 """
118 Sets up the pytest environment
119
120 * `mod`: module name
121 """
122
123 # Required linux kernel version for this suite to run.
124 result = required_linux_kernel_version("4.19")
125 if result is not True:
db726bb8 126 pytest.skip("Kernel version should be >= 4.19")
693a44e1 127
128 testsuite_run_time = time.asctime(time.localtime(time.time()))
129 logger.info("Testsuite start time: {}".format(testsuite_run_time))
130 logger.info("=" * 40)
131 logger.info("Master Topology: \n {}".format(TOPOLOGY))
132
133 logger.info("Running setup_module to create topology")
134
e82b531d
CH
135 json_file = "{}/multicast_pim_sm_topo4.json".format(CWD)
136 tgen = Topogen(json_file, mod.__name__)
137 global topo
138 topo = tgen.json_topo
693a44e1 139 # ... and here it calls Mininet initialization functions.
140
693a44e1 141 # Starting topology, create tmp files which are loaded to routers
d60a3f0e 142 # to start daemons and then start routers
991a971f 143 start_topology(tgen)
693a44e1 144
145 # Don"t run this test if we have any failure.
146 if tgen.routers_have_failure():
147 pytest.skip(tgen.errors)
148
149 # Creating configuration from JSON
150 build_config_from_json(tgen, topo)
151
1973df1d
CH
152 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
153 global app_helper
154 app_helper = McastTesterHelper(tgen)
155
693a44e1 156 logger.info("Running setup_module() done")
157
158
159def teardown_module():
160 """Teardown the pytest environment"""
161
162 logger.info("Running teardown_module to delete topology")
163
164 tgen = get_topogen()
165
1973df1d 166 app_helper.cleanup()
8db751b8 167
693a44e1 168 # Stop toplogy and Remove tmp files
169 tgen.stop_topology()
170
171 logger.info(
172 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
173 )
174 logger.info("=" * 40)
175
176
177#####################################################
178#
179# Testcases
180#
181#####################################################
182
183
3996d25e
MR
184def reset_stats(stats):
185 """
186 API to reset the stats
187
188 Parameters
189 ----------
190 * `stats` : State dictionary holding helloRx and helloTx values
191 """
192
193 for router, state_data in stats.items():
194 for state, value in state_data.items():
195 stats[router][state] = 0
196 logger.info(
197 "[DUT: %s]: stats %s value has reset" " reset, Current value: %s",
198 router,
199 state,
200 stats[router][state],
201 )
202
203 return True
204
205
693a44e1 206def verify_state_incremented(state_before, state_after):
207 """
208 API to compare interface traffic state incrementing
209
210 Parameters
211 ----------
212 * `state_before` : State dictionary for any particular instance
213 * `state_after` : State dictionary for any particular instance
214 """
215
216 for router, state_data in state_before.items():
217 for state, value in state_data.items():
218 if state_before[router][state] >= state_after[router][state]:
219 errormsg = (
220 "[DUT: %s]: state %s value has not"
221 " incremented, Initial value: %s, "
222 "Current value: %s [FAILED!!]"
223 % (
224 router,
225 state,
226 state_before[router][state],
227 state_after[router][state],
228 )
229 )
230 return errormsg
231
232 logger.info(
233 "[DUT: %s]: State %s value is "
234 "incremented, Initial value: %s, Current value: %s"
235 " [PASSED!!]",
236 router,
237 state,
238 state_before[router][state],
239 state_after[router][state],
240 )
241
242 return True
243
244
245def test_mroute_when_RP_reachable_default_route_p2(request):
246 """
247 TC_49 Verify mroute when and source RP is reachable using default route
248 """
249
250 tgen = get_topogen()
251 tc_name = request.node.name
252 write_test_header(tc_name)
253
8db751b8
CH
254 # Don"t run this test if we have any failure.
255 if tgen.routers_have_failure():
256 pytest.skip(tgen.errors)
257
693a44e1 258 # Creating configuration from JSON
1973df1d 259 app_helper.stop_all_hosts()
4fafd29f 260 clear_mroute(tgen)
693a44e1 261 reset_config_on_routers(tgen)
4fafd29f 262 clear_pim_interface_traffic(tgen, topo)
693a44e1 263
693a44e1 264 step(
265 "Remove c1-c2 connected link to simulate topo "
266 "c1(FHR)---l1(RP)----r2---f1-----c2(LHR)"
267 )
268
269 intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
270 intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
271 shutdown_bringup_interface(tgen, "c1", intf_c1_c2, False)
272 shutdown_bringup_interface(tgen, "c2", intf_c2_c1, False)
273
274 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
275 step(
276 "Enable IGMP of FRR1 interface and send IGMP joins "
277 " from FRR1 node for group range (225.1.1.1-5)"
278 )
279
280 intf_c2_i5 = topo["routers"]["c2"]["links"]["i5"]["interface"]
281 input_dict = {
282 "c2": {"igmp": {"interfaces": {intf_c2_i5: {"igmp": {"version": "2"}}}}}
283 }
284 result = create_igmp_config(tgen, topo, input_dict)
285 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
286
287 input_join = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
288
289 for recvr, recvr_intf in input_join.items():
1973df1d 290 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
693a44e1 291 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
292
293 step("Configure static RP for (225.1.1.1-5) as R2")
294
295 input_dict = {
296 "l1": {
297 "pim": {
298 "rp": [
299 {
300 "rp_addr": topo["routers"]["l1"]["links"]["lo"]["ipv4"].split(
301 "/"
302 )[0],
303 "group_addr_range": GROUP_RANGE,
304 }
305 ]
306 }
307 }
308 }
309
310 result = create_pim_config(tgen, topo, input_dict)
311 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
312
313 step("Send traffic from C1 to all the groups ( 225.1.1.1 to 225.1.1.5)")
314
315 input_src = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
316
317 for src, src_intf in input_src.items():
1973df1d 318 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
693a44e1 319 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
320
321 source_i4 = topo["routers"]["i4"]["links"]["c1"]["ipv4"].split("/")[0]
322
323 input_dict_starg = [
324 {
325 "dut": "c2",
326 "src_address": "*",
327 "iif": topo["routers"]["c2"]["links"]["f1"]["interface"],
328 "oil": topo["routers"]["c2"]["links"]["i5"]["interface"],
329 }
330 ]
331
332 input_dict_sg = [
333 {
334 "dut": "c2",
335 "src_address": source_i4,
336 "iif": topo["routers"]["c2"]["links"]["f1"]["interface"],
337 "oil": topo["routers"]["c2"]["links"]["i5"]["interface"],
338 }
339 ]
340
341 step("Verify mroutes and iff upstream")
342
343 for data in input_dict_sg:
4fafd29f 344 result = verify_mroutes(
693a44e1 345 tgen,
346 data["dut"],
347 data["src_address"],
348 IGMP_JOIN_RANGE_1,
349 data["iif"],
350 data["oil"],
351 )
352 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
353
354 result = verify_upstream_iif(
355 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
356 )
357 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
358
359 for data in input_dict_starg:
4fafd29f 360 result = verify_mroutes(
693a44e1 361 tgen,
362 data["dut"],
363 data["src_address"],
364 IGMP_JOIN_RANGE_1,
365 data["iif"],
366 data["oil"],
367 )
368 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
369
370 result = verify_upstream_iif(
371 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
372 )
373 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
374
375 step("Delete static routes on c2")
376 input_dict = {
377 "c2": {
378 "static_routes": [
379 {
380 "network": ["1.0.4.11/32", "10.0.2.1/24", "10.0.1.2/24"],
381 "next_hop": "10.0.3.2",
382 "delete": True,
383 }
384 ]
385 }
386 }
387
388 result = create_static_routes(tgen, input_dict)
389 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
390
391 step("Verify RP info unknown after removing static route from c2 ")
392 dut = "c2"
393 rp_address = topo["routers"]["l1"]["links"]["lo"]["ipv4"].split("/")[0]
394 SOURCE = "Static"
395 result = verify_pim_rp_info(
396 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE
397 )
398 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
399
400 step("Verify mroute not present after Delete of static routes on c1")
401
402 for data in input_dict_sg:
4fafd29f 403 result = verify_mroutes(
693a44e1 404 tgen,
405 data["dut"],
406 data["src_address"],
407 IGMP_JOIN_RANGE_1,
408 data["iif"],
409 data["oil"],
410 expected=False,
411 )
0b25370e
DS
412 assert result is not True, (
413 "Testcase {} : Failed \n "
db726bb8
KK
414 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
415 "Found: {}".format(tc_name, data["dut"], result)
0b25370e 416 )
693a44e1 417
418 result = verify_upstream_iif(
419 tgen,
420 data["dut"],
421 data["iif"],
422 data["src_address"],
423 IGMP_JOIN_RANGE_1,
424 expected=False,
425 )
0b25370e
DS
426 assert result is not True, (
427 "Testcase {} : Failed \n "
db726bb8
KK
428 "Expected: [{}]: Upstream IIF interface {} should not be present\n "
429 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
0b25370e 430 )
693a44e1 431
432 for data in input_dict_starg:
4fafd29f 433 result = verify_mroutes(
693a44e1 434 tgen,
435 data["dut"],
436 data["src_address"],
437 IGMP_JOIN_RANGE_1,
438 data["iif"],
439 data["oil"],
440 expected=False,
441 )
0b25370e
DS
442 assert result is not True, (
443 "Testcase {} : Failed \n "
db726bb8
KK
444 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
445 "Found: {}".format(tc_name, data["dut"], result)
0b25370e 446 )
693a44e1 447
448 result = verify_upstream_iif(
449 tgen,
450 data["dut"],
451 data["iif"],
452 data["src_address"],
453 IGMP_JOIN_RANGE_1,
454 expected=False,
455 )
0b25370e
DS
456 assert result is not True, (
457 "Testcase {} : Failed \n "
db726bb8
KK
458 "Expected: [{}]: Upstream IIF interface {} should not be present\n "
459 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
0b25370e 460 )
693a44e1 461
462 step("Configure default routes on c2")
463
464 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["ipv4"].split("/")[0]
465
466 input_dict = {
467 "c2": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_f1_c2}]}
468 }
469 result = create_static_routes(tgen, input_dict)
470 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
471
472 step("applying ip nht config on c2")
473
474 raw_config = {"c2": {"raw_config": ["ip nht resolve-via-default"]}}
475
476 result = apply_raw_config(tgen, raw_config)
477 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
478
479 step("Verify RP info is NOT unknown after removing static route from c2 ")
480 result = verify_pim_rp_info(
481 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False
482 )
0b25370e
DS
483 assert result is not True, (
484 "Testcase {} : Failed \n "
db726bb8
KK
485 "Expected: [{}]: RP Info should not be Unknown after removing static"
486 " route from c2 \n"
244f2df0 487 "Found: {}".format(tc_name, data["dut"], result)
0b25370e 488 )
693a44e1 489
490 step("Verify (s,g) populated after adding default route ")
491
492 for data in input_dict_sg:
4fafd29f 493 result = verify_mroutes(
693a44e1 494 tgen,
495 data["dut"],
496 data["src_address"],
497 IGMP_JOIN_RANGE_1,
498 data["iif"],
499 data["oil"],
500 )
501 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
502
503 result = verify_upstream_iif(
504 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
505 )
506 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
507
508 step("Verify (*,g) populated after adding default route ")
509
510 for data in input_dict_starg:
4fafd29f 511 result = verify_mroutes(
693a44e1 512 tgen,
513 data["dut"],
514 data["src_address"],
515 IGMP_JOIN_RANGE_1,
516 data["iif"],
517 data["oil"],
518 )
519 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
520
521 result = verify_upstream_iif(
522 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
523 )
524 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
525
526 write_test_footer(tc_name)
527
528
529def test_mroute_with_RP_default_route_all_nodes_p2(request):
530 """
531 TC_50 Verify mroute when LHR,FHR,RP and transit routers reachable
532 using default routes
533 """
534
535 tgen = get_topogen()
536 tc_name = request.node.name
537 write_test_header(tc_name)
538
8db751b8
CH
539 # Don"t run this test if we have any failure.
540 if tgen.routers_have_failure():
541 pytest.skip(tgen.errors)
542
693a44e1 543 # Creating configuration from JSON
1973df1d 544 app_helper.stop_all_hosts()
4fafd29f 545 clear_mroute(tgen)
693a44e1 546 reset_config_on_routers(tgen)
4fafd29f 547 clear_pim_interface_traffic(tgen, topo)
693a44e1 548
693a44e1 549 step(
550 "Remove c1-c2 connected link to simulate topo "
551 "c1(LHR)---l1(RP)----r2---f1-----c2(FHR)"
552 )
553
554 intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
555 intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
556 shutdown_bringup_interface(tgen, "c1", intf_c1_c2, False)
557 shutdown_bringup_interface(tgen, "c2", intf_c2_c1, False)
558
559 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
560 step(
561 "Enable IGMP of FRR1 interface and send IGMP joins "
562 " from FRR1 node for group range (225.1.1.1-5)"
563 )
564
565 intf_c1_i4 = topo["routers"]["c1"]["links"]["i4"]["interface"]
566 input_dict = {
567 "c1": {"igmp": {"interfaces": {intf_c1_i4: {"igmp": {"version": "2"}}}}}
568 }
569 result = create_igmp_config(tgen, topo, input_dict)
570 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
571
572 input_join = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
573
574 for recvr, recvr_intf in input_join.items():
1973df1d 575 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
693a44e1 576 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
577
578 step("Configure static RP for (225.1.1.1-5) as R2")
579
580 input_dict = {
581 "l1": {
582 "pim": {
583 "rp": [
584 {
585 "rp_addr": topo["routers"]["l1"]["links"]["lo"]["ipv4"].split(
586 "/"
587 )[0],
588 "group_addr_range": GROUP_RANGE,
589 }
590 ]
591 }
592 }
593 }
594
595 result = create_pim_config(tgen, topo, input_dict)
596 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
597
598 step("Send traffic from C2 to all the groups ( 225.1.1.1 to 225.1.1.5)")
599
600 input_src = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
601
602 for src, src_intf in input_src.items():
1973df1d 603 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
693a44e1 604 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
605
606 source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0]
607
608 input_dict_starg = [
609 {
610 "dut": "c1",
611 "src_address": "*",
612 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
613 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
614 }
615 ]
616
617 input_dict_sg = [
618 {
619 "dut": "c1",
620 "src_address": source_i5,
621 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
622 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
623 }
624 ]
625
626 step("Verify mroutes and iff upstream")
627
628 for data in input_dict_sg:
4fafd29f 629 result = verify_mroutes(
693a44e1 630 tgen,
631 data["dut"],
632 data["src_address"],
633 IGMP_JOIN_RANGE_1,
634 data["iif"],
635 data["oil"],
636 )
637 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
638
639 result = verify_upstream_iif(
640 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
641 )
642 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
643
644 for data in input_dict_starg:
4fafd29f 645 result = verify_mroutes(
693a44e1 646 tgen,
647 data["dut"],
648 data["src_address"],
649 IGMP_JOIN_RANGE_1,
650 data["iif"],
651 data["oil"],
652 )
653 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
654
655 result = verify_upstream_iif(
656 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
657 )
658 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
659
660 step("Delete static routes RP on all the nodes")
661 input_dict = {
662 "c2": {
663 "static_routes": [
664 {"network": ["1.0.4.11/32"], "next_hop": "10.0.3.2", "delete": True}
665 ]
666 },
667 "c1": {
668 "static_routes": [
669 {"network": ["1.0.4.11/32"], "next_hop": "10.0.2.2", "delete": True}
670 ]
671 },
672 "r2": {
673 "static_routes": [
674 {"network": ["1.0.4.11/32"], "next_hop": "10.0.12.1", "delete": True}
675 ]
676 },
677 "f1": {
678 "static_routes": [
679 {"network": ["1.0.4.11/32"], "next_hop": "10.0.7.2", "delete": True}
680 ]
681 },
682 }
683
684 result = create_static_routes(tgen, input_dict)
685 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
686
687 step("Verify RP info unknown after removing static route from c2 ")
688 dut = "c2"
689 rp_address = topo["routers"]["l1"]["links"]["lo"]["ipv4"].split("/")[0]
690 SOURCE = "Static"
691 result = verify_pim_rp_info(
692 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE
693 )
694 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
695
696 for data in input_dict_starg:
4fafd29f 697 result = verify_mroutes(
693a44e1 698 tgen,
699 data["dut"],
700 data["src_address"],
701 IGMP_JOIN_RANGE_1,
702 data["iif"],
703 data["oil"],
704 expected=False,
705 )
db726bb8
KK
706 assert result is not True, (
707 "Testcase {} : Failed \n "
708 "Expected: [{}]: mroute (S, G) should not be present in mroute table \n "
709 "Found: {}".format(tc_name, data["dut"], result)
0b25370e 710 )
693a44e1 711
712 result = verify_upstream_iif(
713 tgen,
714 data["dut"],
715 data["iif"],
716 data["src_address"],
717 IGMP_JOIN_RANGE_1,
718 expected=False,
719 )
db726bb8
KK
720 assert result is not True, (
721 "Testcase {} : Failed \n "
722 "Expected: [{}]: Upstream IIF interface {} should not be present\n "
723 "Found: {}".format(tc_name, data["dut"], data["iif"], result)
0b25370e 724 )
693a44e1 725
726 step("Configure default routes on all the nodes")
727
728 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["ipv4"].split("/")[0]
729 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["ipv4"].split("/")[0]
730 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["ipv4"].split("/")[0]
731 intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["ipv4"].split("/")[0]
732
733 input_dict = {
734 "c1": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_l1_c1}]},
735 "c2": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_f1_c2}]},
736 "r2": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_l1_r2}]},
737 "f1": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_r2_f1}]},
738 }
739 result = create_static_routes(tgen, input_dict)
740 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
741
742 step("applying ip nht config on c2")
743
744 raw_config = {
745 "c1": {"raw_config": ["ip nht resolve-via-default"]},
746 "c2": {"raw_config": ["ip nht resolve-via-default"]},
747 "r2": {"raw_config": ["ip nht resolve-via-default"]},
748 "f1": {"raw_config": ["ip nht resolve-via-default"]},
749 "l1": {"raw_config": ["ip nht resolve-via-default"]},
750 }
751
752 result = apply_raw_config(tgen, raw_config)
753 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
754
755 step("Verify RP info Not unknown after removing static route from c2 ")
756 dut = "c2"
757 step("Verify RP info is NOT unknown after removing static route from c2 ")
758 result = verify_pim_rp_info(
759 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False
760 )
0b25370e
DS
761 assert result is not True, (
762 "Testcase {} : Failed \n "
db726bb8
KK
763 "Expected: [{}]: RP Info should not be Unknown after removing static"
764 " route from c2 \n"
244f2df0 765 "Found: {}".format(tc_name, data["dut"], result)
0b25370e 766 )
693a44e1 767
768 step("Verify (s,g) populated after adding default route ")
769
770 for data in input_dict_sg:
4fafd29f 771 result = verify_mroutes(
693a44e1 772 tgen,
773 data["dut"],
774 data["src_address"],
775 IGMP_JOIN_RANGE_1,
776 data["iif"],
777 data["oil"],
778 )
779 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
780
781 result = verify_upstream_iif(
782 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
783 )
784 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
785
786 step("Verify (*,g) populated after adding default route ")
787
788 for data in input_dict_starg:
4fafd29f 789 result = verify_mroutes(
693a44e1 790 tgen,
791 data["dut"],
792 data["src_address"],
793 IGMP_JOIN_RANGE_1,
794 data["iif"],
795 data["oil"],
796 )
797 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
798
799 result = verify_upstream_iif(
800 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
801 )
802 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
803
804 write_test_footer(tc_name)
805
806
807def test_PIM_hello_tx_rx_p1(request):
808 """
809 TC_54 Verify received and transmit hello stats
810 are getting cleared after PIM nbr reset
811 """
812
813 tgen = get_topogen()
814 tc_name = request.node.name
815 write_test_header(tc_name)
816
8db751b8
CH
817 # Don"t run this test if we have any failure.
818 if tgen.routers_have_failure():
819 pytest.skip(tgen.errors)
820
693a44e1 821 # Creating configuration from JSON
1973df1d 822 app_helper.stop_all_hosts()
4fafd29f 823 clear_mroute(tgen)
693a44e1 824 reset_config_on_routers(tgen)
4fafd29f 825 clear_pim_interface_traffic(tgen, topo)
693a44e1 826
693a44e1 827 step(
828 "Remove c1-c2 connected link to simulate topo "
829 "c1(LHR)---l1(RP)----r2---f1-----c2(FHR)"
830 )
831
832 intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
833 intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
834 shutdown_bringup_interface(tgen, "c1", intf_c1_c2, False)
835 shutdown_bringup_interface(tgen, "c2", intf_c2_c1, False)
836
837 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
838 step(
839 "Enable IGMP of FRR1 interface and send IGMP joins "
840 " from FRR1 node for group range (225.1.1.1-5)"
841 )
842
843 intf_c1_i4 = topo["routers"]["c1"]["links"]["i4"]["interface"]
844 input_dict = {
845 "c1": {"igmp": {"interfaces": {intf_c1_i4: {"igmp": {"version": "2"}}}}}
846 }
847 result = create_igmp_config(tgen, topo, input_dict)
848 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
849
850 input_join = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
851
852 for recvr, recvr_intf in input_join.items():
1973df1d 853 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
693a44e1 854 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
855
856 step("Configure static RP for (225.1.1.1-5) as R2")
857
858 input_dict = {
859 "l1": {
860 "pim": {
861 "rp": [
862 {
863 "rp_addr": topo["routers"]["l1"]["links"]["lo"]["ipv4"].split(
864 "/"
865 )[0],
866 "group_addr_range": GROUP_RANGE,
867 }
868 ]
869 }
870 }
871 }
872
873 result = create_pim_config(tgen, topo, input_dict)
874 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
875
876 step("Send Mcast traffic from C2 to all the groups ( 225.1.1.1 to 225.1.1.5)")
877
878 input_src = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
879
880 for src, src_intf in input_src.items():
1973df1d 881 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
693a44e1 882 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
883
884 source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0]
885
886 input_dict_starg = [
887 {
888 "dut": "c1",
889 "src_address": "*",
890 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
891 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
892 }
893 ]
894
895 input_dict_sg = [
896 {
897 "dut": "c1",
898 "src_address": source_i5,
899 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
900 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
901 }
902 ]
903
904 step("(*,G) and (S,G) created on f1 and node verify using 'show ip mroute'")
905 for data in input_dict_sg:
4fafd29f 906 result = verify_mroutes(
693a44e1 907 tgen,
908 data["dut"],
909 data["src_address"],
910 IGMP_JOIN_RANGE_1,
911 data["iif"],
912 data["oil"],
913 )
914 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
915
916 for data in input_dict_starg:
4fafd29f 917 result = verify_mroutes(
693a44e1 918 tgen,
919 data["dut"],
920 data["src_address"],
921 IGMP_JOIN_RANGE_1,
922 data["iif"],
923 data["oil"],
924 )
925 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
926
927 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
928 intf_c1_l1 = topo["routers"]["c1"]["links"]["l1"]["interface"]
929
5980ad0a
DS
930 state_dict = {
931 "c1": {
932 intf_c1_l1: ["helloTx", "helloRx"],
933 }
934 }
693a44e1 935
0b01a0bb 936 c1_state_before = get_pim_interface_traffic(tgen, state_dict)
693a44e1 937 assert isinstance(
938 c1_state_before, dict
d7d21c3a
CH
939 ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format(
940 tc_name, result
941 )
693a44e1 942
943 step("Flap PIM nbr while doing interface c1-l1 interface shut from f1 side")
944 shutdown_bringup_interface(tgen, "c1", intf_c1_l1, False)
945
3996d25e
MR
946 """ Resetting the stats here since shutdown resets the stats.
947 """
948 reset_stats(c1_state_before)
693a44e1 949 shutdown_bringup_interface(tgen, "c1", intf_c1_l1, True)
950
3996d25e 951 step("verify stats after no shutdown on c1 and that they are incremented")
758999b3
DS
952
953 count = 0
954 done = False
955 while not done and count <= 7:
956 c1_state_after = get_pim_interface_traffic(tgen, state_dict)
957 assert isinstance(
958 c1_state_after, dict
959 ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format(
960 tc_name, result
961 )
962
963 result = verify_state_incremented(c1_state_before, c1_state_after)
964 if result is not True:
965 sleep(5)
966 count += 1
967 else:
968 done = True
693a44e1 969
693a44e1 970 assert (
0d16f9d8
MR
971 result is True
972 ), "Testcase{} : Failed Error: {}" "stats is not incremented".format(
973 tc_name, result
974 )
693a44e1 975
976 step("verify before stats on l1")
5980ad0a
DS
977 l1_state_dict = {
978 "l1": {
979 intf_l1_c1: ["helloTx", "helloRx"],
980 }
981 }
693a44e1 982
0b01a0bb 983 l1_state_before = get_pim_interface_traffic(tgen, l1_state_dict)
693a44e1 984 assert isinstance(
985 l1_state_before, dict
d7d21c3a
CH
986 ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format(
987 tc_name, result
988 )
693a44e1 989
990 step("Flap PIM nbr while doing interface r2-c1 shut from r2 side")
991 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, False)
992
993 step(
994 "After shut the interface from r2 side , verify r2 side rx and tx of hello"
995 "counters are resetted show ip pim interface traffic"
996 )
997 shutdown_bringup_interface(tgen, "l1", intf_l1_c1, True)
998
758999b3
DS
999 step("verify stats after on l1 are incremented")
1000 count = 0
1001 done = False
1002 while not done and count <= 7:
1003 l1_state_after = get_pim_interface_traffic(tgen, l1_state_dict)
1004 assert isinstance(
1005 l1_state_after, dict
1006 ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format(
1007 tc_name, result
1008 )
1009
1010 result = verify_state_incremented(l1_state_before, l1_state_after)
1011 if result is True:
1012 sleep(5)
1013 count += 1
1014 else:
1015 done = True
693a44e1 1016
693a44e1 1017 assert (
1018 result is not True
1019 ), "Testcase{} : Failed Error: {}" "stats incremented".format(tc_name, result)
1020
1021 step("Reinit the dict")
1022 c1_state_before = {}
1023 l1_state_before = {}
1024 c1_state_after = {}
1025 l1_state_after = {}
1026
1027 step("verify before stats on C1")
5980ad0a
DS
1028 state_dict = {
1029 "c1": {
1030 intf_c1_l1: ["helloTx", "helloRx"],
1031 }
1032 }
693a44e1 1033
0b01a0bb 1034 c1_state_before = get_pim_interface_traffic(tgen, state_dict)
693a44e1 1035 assert isinstance(
1036 c1_state_before, dict
d7d21c3a
CH
1037 ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format(
1038 tc_name, result
1039 )
693a44e1 1040
1041 step("Flap c1-r2 pim nbr while changing ip address from c1 side")
1042 c1_l1_ip_subnet = topo["routers"]["c1"]["links"]["l1"]["ipv4"]
1043
1044 raw_config = {
1045 "c1": {
1046 "raw_config": [
1047 "interface {}".format(intf_c1_l1),
1048 "no ip address {}".format(c1_l1_ip_subnet),
1049 "ip address {}".format(NEW_ADDRESS_2_SUBNET),
1050 ]
1051 }
1052 }
1053
1054 result = apply_raw_config(tgen, raw_config)
1055 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1056
758999b3
DS
1057 step("verify stats after on c1 are incremented")
1058 count = 0
1059 done = False
1060 while not done and count <= 7:
1061 c1_state_after = get_pim_interface_traffic(tgen, state_dict)
1062 assert isinstance(
1063 c1_state_after, dict
1064 ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format(
1065 tc_name, result
1066 )
1067
1068 result = verify_state_incremented(c1_state_before, c1_state_after)
1069 if result is not True:
1070 sleep(5)
1071 count += 1
1072 else:
1073 done = True
693a44e1 1074
715d3774
DS
1075 assert result is True, "Testcase{} : Failed Error: {}" "stats incremented".format(
1076 tc_name, result
1077 )
693a44e1 1078
1079 write_test_footer(tc_name)
1080
1081
1082if __name__ == "__main__":
1083 args = ["-s"] + sys.argv[1:]
1084 sys.exit(pytest.main(args))