]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py
Merge pull request #10343 from taspelund/fix_receivedRoutes_string
[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,
693a44e1 76 verify_ip_mroutes,
77 clear_ip_pim_interface_traffic,
693a44e1 78 verify_upstream_iif,
79 clear_ip_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:
139 pytest.skip("Kernel requirements are not met")
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
154 # get list of daemons needs to be started for this suite.
155 daemons = topo_daemons(tgen, topo)
156
157 # Starting topology, create tmp files which are loaded to routers
158 # to start deamons and then start routers
159 start_topology(tgen, daemons)
160
161 # Don"t run this test if we have any failure.
162 if tgen.routers_have_failure():
163 pytest.skip(tgen.errors)
164
165 # Creating configuration from JSON
166 build_config_from_json(tgen, topo)
167
1973df1d
CH
168 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
169 global app_helper
170 app_helper = McastTesterHelper(tgen)
171
693a44e1 172 logger.info("Running setup_module() done")
173
174
175def teardown_module():
176 """Teardown the pytest environment"""
177
178 logger.info("Running teardown_module to delete topology")
179
180 tgen = get_topogen()
181
1973df1d 182 app_helper.cleanup()
8db751b8 183
693a44e1 184 # Stop toplogy and Remove tmp files
185 tgen.stop_topology()
186
187 logger.info(
188 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
189 )
190 logger.info("=" * 40)
191
192
193#####################################################
194#
195# Testcases
196#
197#####################################################
198
199
693a44e1 200def verify_state_incremented(state_before, state_after):
201 """
202 API to compare interface traffic state incrementing
203
204 Parameters
205 ----------
206 * `state_before` : State dictionary for any particular instance
207 * `state_after` : State dictionary for any particular instance
208 """
209
210 for router, state_data in state_before.items():
211 for state, value in state_data.items():
212 if state_before[router][state] >= state_after[router][state]:
213 errormsg = (
214 "[DUT: %s]: state %s value has not"
215 " incremented, Initial value: %s, "
216 "Current value: %s [FAILED!!]"
217 % (
218 router,
219 state,
220 state_before[router][state],
221 state_after[router][state],
222 )
223 )
224 return errormsg
225
226 logger.info(
227 "[DUT: %s]: State %s value is "
228 "incremented, Initial value: %s, Current value: %s"
229 " [PASSED!!]",
230 router,
231 state,
232 state_before[router][state],
233 state_after[router][state],
234 )
235
236 return True
237
238
239def test_mroute_when_RP_reachable_default_route_p2(request):
240 """
241 TC_49 Verify mroute when and source RP is reachable using default route
242 """
243
244 tgen = get_topogen()
245 tc_name = request.node.name
246 write_test_header(tc_name)
247
8db751b8
CH
248 # Don"t run this test if we have any failure.
249 if tgen.routers_have_failure():
250 pytest.skip(tgen.errors)
251
693a44e1 252 # Creating configuration from JSON
1973df1d 253 app_helper.stop_all_hosts()
693a44e1 254 clear_ip_mroute(tgen)
255 reset_config_on_routers(tgen)
256 clear_ip_pim_interface_traffic(tgen, topo)
257
693a44e1 258 step(
259 "Remove c1-c2 connected link to simulate topo "
260 "c1(FHR)---l1(RP)----r2---f1-----c2(LHR)"
261 )
262
263 intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
264 intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
265 shutdown_bringup_interface(tgen, "c1", intf_c1_c2, False)
266 shutdown_bringup_interface(tgen, "c2", intf_c2_c1, False)
267
268 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
269 step(
270 "Enable IGMP of FRR1 interface and send IGMP joins "
271 " from FRR1 node for group range (225.1.1.1-5)"
272 )
273
274 intf_c2_i5 = topo["routers"]["c2"]["links"]["i5"]["interface"]
275 input_dict = {
276 "c2": {"igmp": {"interfaces": {intf_c2_i5: {"igmp": {"version": "2"}}}}}
277 }
278 result = create_igmp_config(tgen, topo, input_dict)
279 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
280
281 input_join = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
282
283 for recvr, recvr_intf in input_join.items():
1973df1d 284 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
693a44e1 285 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
286
287 step("Configure static RP for (225.1.1.1-5) as R2")
288
289 input_dict = {
290 "l1": {
291 "pim": {
292 "rp": [
293 {
294 "rp_addr": topo["routers"]["l1"]["links"]["lo"]["ipv4"].split(
295 "/"
296 )[0],
297 "group_addr_range": GROUP_RANGE,
298 }
299 ]
300 }
301 }
302 }
303
304 result = create_pim_config(tgen, topo, input_dict)
305 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
306
307 step("Send traffic from C1 to all the groups ( 225.1.1.1 to 225.1.1.5)")
308
309 input_src = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
310
311 for src, src_intf in input_src.items():
1973df1d 312 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
693a44e1 313 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
314
315 source_i4 = topo["routers"]["i4"]["links"]["c1"]["ipv4"].split("/")[0]
316
317 input_dict_starg = [
318 {
319 "dut": "c2",
320 "src_address": "*",
321 "iif": topo["routers"]["c2"]["links"]["f1"]["interface"],
322 "oil": topo["routers"]["c2"]["links"]["i5"]["interface"],
323 }
324 ]
325
326 input_dict_sg = [
327 {
328 "dut": "c2",
329 "src_address": source_i4,
330 "iif": topo["routers"]["c2"]["links"]["f1"]["interface"],
331 "oil": topo["routers"]["c2"]["links"]["i5"]["interface"],
332 }
333 ]
334
335 step("Verify mroutes and iff upstream")
336
337 for data in input_dict_sg:
338 result = verify_ip_mroutes(
339 tgen,
340 data["dut"],
341 data["src_address"],
342 IGMP_JOIN_RANGE_1,
343 data["iif"],
344 data["oil"],
345 )
346 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
347
348 result = verify_upstream_iif(
349 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
350 )
351 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
352
353 for data in input_dict_starg:
354 result = verify_ip_mroutes(
355 tgen,
356 data["dut"],
357 data["src_address"],
358 IGMP_JOIN_RANGE_1,
359 data["iif"],
360 data["oil"],
361 )
362 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
363
364 result = verify_upstream_iif(
365 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
366 )
367 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
368
369 step("Delete static routes on c2")
370 input_dict = {
371 "c2": {
372 "static_routes": [
373 {
374 "network": ["1.0.4.11/32", "10.0.2.1/24", "10.0.1.2/24"],
375 "next_hop": "10.0.3.2",
376 "delete": True,
377 }
378 ]
379 }
380 }
381
382 result = create_static_routes(tgen, input_dict)
383 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
384
385 step("Verify RP info unknown after removing static route from c2 ")
386 dut = "c2"
387 rp_address = topo["routers"]["l1"]["links"]["lo"]["ipv4"].split("/")[0]
388 SOURCE = "Static"
389 result = verify_pim_rp_info(
390 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE
391 )
392 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
393
394 step("Verify mroute not present after Delete of static routes on c1")
395
396 for data in input_dict_sg:
397 result = verify_ip_mroutes(
398 tgen,
399 data["dut"],
400 data["src_address"],
401 IGMP_JOIN_RANGE_1,
402 data["iif"],
403 data["oil"],
404 expected=False,
405 )
0b25370e
DS
406 assert result is not True, (
407 "Testcase {} : Failed \n "
5cbb02eb 408 "mroutes(S,G) are present after delete of static routes on c1 \n Error: {}".format(
0b25370e
DS
409 tc_name, result
410 )
411 )
693a44e1 412
413 result = verify_upstream_iif(
414 tgen,
415 data["dut"],
416 data["iif"],
417 data["src_address"],
418 IGMP_JOIN_RANGE_1,
419 expected=False,
420 )
0b25370e
DS
421 assert result is not True, (
422 "Testcase {} : Failed \n "
5cbb02eb 423 "upstream is present after delete of static routes on c1 \n Error: {}".format(
0b25370e
DS
424 tc_name, result
425 )
426 )
693a44e1 427
428 for data in input_dict_starg:
429 result = verify_ip_mroutes(
430 tgen,
431 data["dut"],
432 data["src_address"],
433 IGMP_JOIN_RANGE_1,
434 data["iif"],
435 data["oil"],
436 expected=False,
437 )
0b25370e
DS
438 assert result is not True, (
439 "Testcase {} : Failed \n "
5cbb02eb 440 "mroutes(*,G) are present after delete of static routes on c1 \n Error: {}".format(
0b25370e
DS
441 tc_name, result
442 )
443 )
693a44e1 444
445 result = verify_upstream_iif(
446 tgen,
447 data["dut"],
448 data["iif"],
449 data["src_address"],
450 IGMP_JOIN_RANGE_1,
451 expected=False,
452 )
0b25370e
DS
453 assert result is not True, (
454 "Testcase {} : Failed \n "
5cbb02eb 455 "upstream is present after delete of static routes on c1 \n Error: {}".format(
0b25370e
DS
456 tc_name, result
457 )
458 )
693a44e1 459
460 step("Configure default routes on c2")
461
462 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["ipv4"].split("/")[0]
463
464 input_dict = {
465 "c2": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_f1_c2}]}
466 }
467 result = create_static_routes(tgen, input_dict)
468 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
469
470 step("applying ip nht config on c2")
471
472 raw_config = {"c2": {"raw_config": ["ip nht resolve-via-default"]}}
473
474 result = apply_raw_config(tgen, raw_config)
475 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
476
477 step("Verify RP info is NOT unknown after removing static route from c2 ")
478 result = verify_pim_rp_info(
479 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False
480 )
0b25370e
DS
481 assert result is not True, (
482 "Testcase {} : Failed \n "
5cbb02eb 483 "RP info is unknown after removing static route from c2 \n Error: {}".format(
0b25370e
DS
484 tc_name, result
485 )
486 )
693a44e1 487
488 step("Verify (s,g) populated after adding default route ")
489
490 for data in input_dict_sg:
491 result = verify_ip_mroutes(
492 tgen,
493 data["dut"],
494 data["src_address"],
495 IGMP_JOIN_RANGE_1,
496 data["iif"],
497 data["oil"],
498 )
499 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
500
501 result = verify_upstream_iif(
502 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
503 )
504 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
505
506 step("Verify (*,g) populated after adding default route ")
507
508 for data in input_dict_starg:
509 result = verify_ip_mroutes(
510 tgen,
511 data["dut"],
512 data["src_address"],
513 IGMP_JOIN_RANGE_1,
514 data["iif"],
515 data["oil"],
516 )
517 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
518
519 result = verify_upstream_iif(
520 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
521 )
522 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
523
524 write_test_footer(tc_name)
525
526
527def test_mroute_with_RP_default_route_all_nodes_p2(request):
528 """
529 TC_50 Verify mroute when LHR,FHR,RP and transit routers reachable
530 using default routes
531 """
532
533 tgen = get_topogen()
534 tc_name = request.node.name
535 write_test_header(tc_name)
536
8db751b8
CH
537 # Don"t run this test if we have any failure.
538 if tgen.routers_have_failure():
539 pytest.skip(tgen.errors)
540
693a44e1 541 # Creating configuration from JSON
1973df1d 542 app_helper.stop_all_hosts()
693a44e1 543 clear_ip_mroute(tgen)
544 reset_config_on_routers(tgen)
545 clear_ip_pim_interface_traffic(tgen, topo)
546
693a44e1 547 step(
548 "Remove c1-c2 connected link to simulate topo "
549 "c1(LHR)---l1(RP)----r2---f1-----c2(FHR)"
550 )
551
552 intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
553 intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
554 shutdown_bringup_interface(tgen, "c1", intf_c1_c2, False)
555 shutdown_bringup_interface(tgen, "c2", intf_c2_c1, False)
556
557 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
558 step(
559 "Enable IGMP of FRR1 interface and send IGMP joins "
560 " from FRR1 node for group range (225.1.1.1-5)"
561 )
562
563 intf_c1_i4 = topo["routers"]["c1"]["links"]["i4"]["interface"]
564 input_dict = {
565 "c1": {"igmp": {"interfaces": {intf_c1_i4: {"igmp": {"version": "2"}}}}}
566 }
567 result = create_igmp_config(tgen, topo, input_dict)
568 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
569
570 input_join = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
571
572 for recvr, recvr_intf in input_join.items():
1973df1d 573 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
693a44e1 574 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
575
576 step("Configure static RP for (225.1.1.1-5) as R2")
577
578 input_dict = {
579 "l1": {
580 "pim": {
581 "rp": [
582 {
583 "rp_addr": topo["routers"]["l1"]["links"]["lo"]["ipv4"].split(
584 "/"
585 )[0],
586 "group_addr_range": GROUP_RANGE,
587 }
588 ]
589 }
590 }
591 }
592
593 result = create_pim_config(tgen, topo, input_dict)
594 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
595
596 step("Send traffic from C2 to all the groups ( 225.1.1.1 to 225.1.1.5)")
597
598 input_src = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
599
600 for src, src_intf in input_src.items():
1973df1d 601 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
693a44e1 602 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
603
604 source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0]
605
606 input_dict_starg = [
607 {
608 "dut": "c1",
609 "src_address": "*",
610 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
611 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
612 }
613 ]
614
615 input_dict_sg = [
616 {
617 "dut": "c1",
618 "src_address": source_i5,
619 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
620 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
621 }
622 ]
623
624 step("Verify mroutes and iff upstream")
625
626 for data in input_dict_sg:
627 result = verify_ip_mroutes(
628 tgen,
629 data["dut"],
630 data["src_address"],
631 IGMP_JOIN_RANGE_1,
632 data["iif"],
633 data["oil"],
634 )
635 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
636
637 result = verify_upstream_iif(
638 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
639 )
640 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
641
642 for data in input_dict_starg:
643 result = verify_ip_mroutes(
644 tgen,
645 data["dut"],
646 data["src_address"],
647 IGMP_JOIN_RANGE_1,
648 data["iif"],
649 data["oil"],
650 )
651 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
652
653 result = verify_upstream_iif(
654 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
655 )
656 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
657
658 step("Delete static routes RP on all the nodes")
659 input_dict = {
660 "c2": {
661 "static_routes": [
662 {"network": ["1.0.4.11/32"], "next_hop": "10.0.3.2", "delete": True}
663 ]
664 },
665 "c1": {
666 "static_routes": [
667 {"network": ["1.0.4.11/32"], "next_hop": "10.0.2.2", "delete": True}
668 ]
669 },
670 "r2": {
671 "static_routes": [
672 {"network": ["1.0.4.11/32"], "next_hop": "10.0.12.1", "delete": True}
673 ]
674 },
675 "f1": {
676 "static_routes": [
677 {"network": ["1.0.4.11/32"], "next_hop": "10.0.7.2", "delete": True}
678 ]
679 },
680 }
681
682 result = create_static_routes(tgen, input_dict)
683 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
684
685 step("Verify RP info unknown after removing static route from c2 ")
686 dut = "c2"
687 rp_address = topo["routers"]["l1"]["links"]["lo"]["ipv4"].split("/")[0]
688 SOURCE = "Static"
689 result = verify_pim_rp_info(
690 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE
691 )
692 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
693
694 for data in input_dict_starg:
695 result = verify_ip_mroutes(
696 tgen,
697 data["dut"],
698 data["src_address"],
699 IGMP_JOIN_RANGE_1,
700 data["iif"],
701 data["oil"],
702 expected=False,
703 )
0b25370e
DS
704 assert (
705 result is not True
706 ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format(
693a44e1 707 tc_name, result
0b25370e 708 )
693a44e1 709
710 result = verify_upstream_iif(
711 tgen,
712 data["dut"],
713 data["iif"],
714 data["src_address"],
715 IGMP_JOIN_RANGE_1,
716 expected=False,
717 )
0b25370e
DS
718 assert (
719 result is not True
720 ), "Testcase {} : Failed \n " "upstream is still present \n Error: {}".format(
693a44e1 721 tc_name, result
0b25370e 722 )
693a44e1 723
724 step("Configure default routes on all the nodes")
725
726 intf_f1_c2 = topo["routers"]["f1"]["links"]["c2"]["ipv4"].split("/")[0]
727 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["ipv4"].split("/")[0]
728 intf_l1_r2 = topo["routers"]["l1"]["links"]["r2"]["ipv4"].split("/")[0]
729 intf_r2_f1 = topo["routers"]["r2"]["links"]["f1"]["ipv4"].split("/")[0]
730
731 input_dict = {
732 "c1": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_l1_c1}]},
733 "c2": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_f1_c2}]},
734 "r2": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_l1_r2}]},
735 "f1": {"static_routes": [{"network": "0.0.0.0/0", "next_hop": intf_r2_f1}]},
736 }
737 result = create_static_routes(tgen, input_dict)
738 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
739
740 step("applying ip nht config on c2")
741
742 raw_config = {
743 "c1": {"raw_config": ["ip nht resolve-via-default"]},
744 "c2": {"raw_config": ["ip nht resolve-via-default"]},
745 "r2": {"raw_config": ["ip nht resolve-via-default"]},
746 "f1": {"raw_config": ["ip nht resolve-via-default"]},
747 "l1": {"raw_config": ["ip nht resolve-via-default"]},
748 }
749
750 result = apply_raw_config(tgen, raw_config)
751 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
752
753 step("Verify RP info Not unknown after removing static route from c2 ")
754 dut = "c2"
755 step("Verify RP info is NOT unknown after removing static route from c2 ")
756 result = verify_pim_rp_info(
757 tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False
758 )
0b25370e
DS
759 assert result is not True, (
760 "Testcase {} : Failed \n "
5cbb02eb 761 "RP info is unknown after removing static route from c2 \n Error: {}".format(
0b25370e
DS
762 tc_name, result
763 )
764 )
693a44e1 765
766 step("Verify (s,g) populated after adding default route ")
767
768 for data in input_dict_sg:
769 result = verify_ip_mroutes(
770 tgen,
771 data["dut"],
772 data["src_address"],
773 IGMP_JOIN_RANGE_1,
774 data["iif"],
775 data["oil"],
776 )
777 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
778
779 result = verify_upstream_iif(
780 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
781 )
782 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
783
784 step("Verify (*,g) populated after adding default route ")
785
786 for data in input_dict_starg:
787 result = verify_ip_mroutes(
788 tgen,
789 data["dut"],
790 data["src_address"],
791 IGMP_JOIN_RANGE_1,
792 data["iif"],
793 data["oil"],
794 )
795 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
796
797 result = verify_upstream_iif(
798 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
799 )
800 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
801
802 write_test_footer(tc_name)
803
804
805def test_PIM_hello_tx_rx_p1(request):
806 """
807 TC_54 Verify received and transmit hello stats
808 are getting cleared after PIM nbr reset
809 """
810
811 tgen = get_topogen()
812 tc_name = request.node.name
813 write_test_header(tc_name)
814
8db751b8
CH
815 # Don"t run this test if we have any failure.
816 if tgen.routers_have_failure():
817 pytest.skip(tgen.errors)
818
693a44e1 819 # Creating configuration from JSON
1973df1d 820 app_helper.stop_all_hosts()
693a44e1 821 clear_ip_mroute(tgen)
822 reset_config_on_routers(tgen)
823 clear_ip_pim_interface_traffic(tgen, topo)
824
693a44e1 825 step(
826 "Remove c1-c2 connected link to simulate topo "
827 "c1(LHR)---l1(RP)----r2---f1-----c2(FHR)"
828 )
829
830 intf_c1_c2 = topo["routers"]["c1"]["links"]["c2"]["interface"]
831 intf_c2_c1 = topo["routers"]["c2"]["links"]["c1"]["interface"]
832 shutdown_bringup_interface(tgen, "c1", intf_c1_c2, False)
833 shutdown_bringup_interface(tgen, "c2", intf_c2_c1, False)
834
835 step("Enable the PIM on all the interfaces of FRR1, FRR2, FRR3")
836 step(
837 "Enable IGMP of FRR1 interface and send IGMP joins "
838 " from FRR1 node for group range (225.1.1.1-5)"
839 )
840
841 intf_c1_i4 = topo["routers"]["c1"]["links"]["i4"]["interface"]
842 input_dict = {
843 "c1": {"igmp": {"interfaces": {intf_c1_i4: {"igmp": {"version": "2"}}}}}
844 }
845 result = create_igmp_config(tgen, topo, input_dict)
846 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
847
848 input_join = {"i4": topo["routers"]["i4"]["links"]["c1"]["interface"]}
849
850 for recvr, recvr_intf in input_join.items():
1973df1d 851 result = app_helper.run_join(recvr, IGMP_JOIN_RANGE_1, join_intf=recvr_intf)
693a44e1 852 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
853
854 step("Configure static RP for (225.1.1.1-5) as R2")
855
856 input_dict = {
857 "l1": {
858 "pim": {
859 "rp": [
860 {
861 "rp_addr": topo["routers"]["l1"]["links"]["lo"]["ipv4"].split(
862 "/"
863 )[0],
864 "group_addr_range": GROUP_RANGE,
865 }
866 ]
867 }
868 }
869 }
870
871 result = create_pim_config(tgen, topo, input_dict)
872 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
873
874 step("Send Mcast traffic from C2 to all the groups ( 225.1.1.1 to 225.1.1.5)")
875
876 input_src = {"i5": topo["routers"]["i5"]["links"]["c2"]["interface"]}
877
878 for src, src_intf in input_src.items():
1973df1d 879 result = app_helper.run_traffic(src, IGMP_JOIN_RANGE_1, bind_intf=src_intf)
693a44e1 880 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
881
882 source_i5 = topo["routers"]["i5"]["links"]["c2"]["ipv4"].split("/")[0]
883
884 input_dict_starg = [
885 {
886 "dut": "c1",
887 "src_address": "*",
888 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
889 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
890 }
891 ]
892
893 input_dict_sg = [
894 {
895 "dut": "c1",
896 "src_address": source_i5,
897 "iif": topo["routers"]["c1"]["links"]["l1"]["interface"],
898 "oil": topo["routers"]["c1"]["links"]["i4"]["interface"],
899 }
900 ]
901
902 step("(*,G) and (S,G) created on f1 and node verify using 'show ip mroute'")
903 for data in input_dict_sg:
904 result = verify_ip_mroutes(
905 tgen,
906 data["dut"],
907 data["src_address"],
908 IGMP_JOIN_RANGE_1,
909 data["iif"],
910 data["oil"],
911 )
912 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
913
914 for data in input_dict_starg:
915 result = verify_ip_mroutes(
916 tgen,
917 data["dut"],
918 data["src_address"],
919 IGMP_JOIN_RANGE_1,
920 data["iif"],
921 data["oil"],
922 )
923 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
924
925 intf_l1_c1 = topo["routers"]["l1"]["links"]["c1"]["interface"]
926 intf_c1_l1 = topo["routers"]["c1"]["links"]["l1"]["interface"]
927
928 step("verify before stats on C1")
5980ad0a
DS
929 state_dict = {
930 "c1": {
931 intf_c1_l1: ["helloTx", "helloRx"],
932 }
933 }
693a44e1 934
0b01a0bb 935 c1_state_before = get_pim_interface_traffic(tgen, state_dict)
693a44e1 936 assert isinstance(
937 c1_state_before, dict
d7d21c3a
CH
938 ), "Testcase{} : Failed \n state_before is not dictionary \n Error: {}".format(
939 tc_name, result
940 )
693a44e1 941
942 step("Flap PIM nbr while doing interface c1-l1 interface shut from f1 side")
943 shutdown_bringup_interface(tgen, "c1", intf_c1_l1, False)
944
945 step(
946 "After shut of local interface from c1 , verify rx/tx hello counters are cleared on c1 side"
947 "verify using 'show ip pim interface traffic'"
948 )
949 shutdown_bringup_interface(tgen, "c1", intf_c1_l1, True)
950
758999b3
DS
951 step("verify stats after on c1 and that they are incremented")
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))