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