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