]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_static_routes_topo1.py
Merge pull request #12481 from kuldeepkash/topotests_startup
[mirror_frr.git] / tests / topotests / multicast_pim_dr_nondr_test / test_pim_dr_nondr_with_static_routes_topo1.py
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 """
24 Following tests are covered to test multicast pim sm:
25
26 Test steps
27 - Create topology (setup module)
28 - Bring up topology
29
30 Following tests are covered:
31 1. Verify mroute while rebooting DR /Non DR nodes( r1, r2 , r3 on all the nodes)
32 """
33
34 import os
35 import sys
36 import json
37 import time
38 import datetime
39 from time import sleep
40 import pytest
41
42 # Save the Current Working Directory to find configuration files.
43 CWD = os.path.dirname(os.path.realpath(__file__))
44 sys.path.append(os.path.join(CWD, "../"))
45 sys.path.append(os.path.join(CWD, "../lib/"))
46
47 # Required to instantiate the topology builder class.
48
49 # pylint: disable=C0413
50 # Import topogen and topotest helpers
51 from lib.topogen import Topogen, get_topogen
52
53 from lib.common_config import (
54 start_topology,
55 write_test_header,
56 write_test_footer,
57 step,
58 reset_config_on_routers,
59 apply_raw_config,
60 add_interfaces_to_vlan,
61 stop_router,
62 start_router,
63 check_router_status,
64 topo_daemons,
65 required_linux_kernel_version,
66 )
67 from lib.pim import (
68 create_pim_config,
69 create_igmp_config,
70 verify_mroutes,
71 clear_mroute,
72 clear_pim_interface_traffic,
73 verify_pim_config,
74 verify_upstream_iif,
75 verify_multicast_flag_state,
76 McastTesterHelper,
77 )
78 from lib.topolog import logger
79 from lib.topojson import build_config_from_json
80
81 HELLO_TIMER = 1
82 HOLD_TIMER = 3
83
84 pytestmark = [pytest.mark.pimd]
85
86 TOPOLOGY = """
87
88 Descripton: Configuring static routes on r1/r2/r3/r4/r5 for RP reachablility.
89 IPs are assigned automatically to routers, start IP and subnet is defined in respective JSON file
90 JSON snippet:
91 "link_ip_start": {"ipv4": "10.0.0.0", "v4mask": 24},
92
93 r5 ------- i2
94 10.0.3.2/24| 10.0.0.2/24
95 |
96 10.0.3.1/24|
97 ------------ r4 ----------
98 | 10.0.1.2/24 10.0.2.2/24 |
99 10.0.1.1/24 | | 10.0.2.1/24
100 r1 ----------- s1 ---------- r2
101 10.0.4.2/24 | 10.0.4.3/24
102 |
103 |10.0.4.4/24
104 i1 -------- r3
105 10.0.4.1/24
106 Description:
107 i1, i2 - FRR running iperf to send IGMP
108 join and traffic
109 r1, r2, r3, r4, r5 - FRR ruter
110 s1 - OVS switch
111 """
112
113 # Global variables
114 VLAN_1 = 2501
115 GROUP_RANGE = "225.0.0.0/8"
116 IGMP_JOIN = "225.1.1.1"
117 VLAN_INTF_ADRESS_1 = "10.0.8.3/24"
118 SAME_VLAN_IP_1 = {"ip": "10.1.1.1", "subnet": "255.255.255.0", "cidr": "24"}
119 SAME_VLAN_IP_2 = {"ip": "10.1.1.2", "subnet": "255.255.255.0", "cidr": "24"}
120 SAME_VLAN_IP_3 = {"ip": "10.1.1.3", "subnet": "255.255.255.0", "cidr": "24"}
121 SAME_VLAN_IP_4 = {"ip": "10.1.1.4", "subnet": "255.255.255.0", "cidr": "24"}
122 GROUP_RANGE_1 = [
123 "225.1.1.1/32",
124 "225.1.1.2/32",
125 "225.1.1.3/32",
126 "225.1.1.4/32",
127 "225.1.1.5/32",
128 ]
129 IGMP_JOIN_RANGE_1 = ["225.1.1.1", "225.1.1.2", "225.1.1.3", "225.1.1.4", "225.1.1.5"]
130 GROUP_RANGE_2 = [
131 "226.1.1.1/32",
132 "226.1.1.2/32",
133 "226.1.1.3/32",
134 "226.1.1.4/32",
135 "226.1.1.5/32",
136 ]
137 IGMP_JOIN_RANGE_2 = ["226.1.1.1", "226.1.1.2", "226.1.1.3", "226.1.1.4", "226.1.1.5"]
138 GROUP_RANGE_3 = [
139 "227.1.1.1/32",
140 "227.1.1.2/32",
141 "227.1.1.3/32",
142 "227.1.1.4/32",
143 "227.1.1.5/32",
144 ]
145 IGMP_JOIN_RANGE_3 = ["227.1.1.1", "227.1.1.2", "227.1.1.3", "227.1.1.4", "227.1.1.5"]
146
147 intf_r1_s1 = None
148 intf_r1_s1_addr = None
149 intf_r2_s1 = None
150 intf_r2_s1_addr = None
151 intf_r3_s1 = None
152 intf_r3_s1_addr = None
153 intf_i1_s1 = None
154 intf_i1_s1_addr = None
155
156
157 def setup_module(mod):
158 """
159 Sets up the pytest environment
160
161 * `mod`: module name
162 """
163
164 # Required linux kernel version for this suite to run.
165 result = required_linux_kernel_version("4.19")
166 if result is not True:
167 pytest.skip("Kernel requirements are not met")
168
169 testsuite_run_time = time.asctime(time.localtime(time.time()))
170 logger.info("Testsuite start time: {}".format(testsuite_run_time))
171 logger.info("=" * 40)
172 logger.info("Master Topology: \n {}".format(TOPOLOGY))
173
174 logger.info("Running setup_module to create topology")
175
176 testdir = os.path.dirname(os.path.realpath(__file__))
177 json_file = "{}/pim_dr_nondr_with_static_routes_topo1.json".format(testdir)
178 tgen = Topogen(json_file, mod.__name__)
179 global topo
180 topo = tgen.json_topo
181 # ... and here it calls Mininet initialization functions.
182
183 # Starting topology, create tmp files which are loaded to routers
184 # to start deamons and then start routers
185 start_topology(tgen)
186
187 # Don"t run this test if we have any failure.
188 if tgen.routers_have_failure():
189 pytest.skip(tgen.errors)
190
191 # Creating configuration from JSON
192 build_config_from_json(tgen, tgen.json_topo)
193
194 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
195 global app_helper
196 app_helper = McastTesterHelper(tgen)
197
198 logger.info("Running setup_module() done")
199
200
201 def teardown_module():
202 """Teardown the pytest environment"""
203
204 logger.info("Running teardown_module to delete topology")
205
206 tgen = get_topogen()
207
208 app_helper.cleanup()
209
210 # Stop toplogy and Remove tmp files
211 tgen.stop_topology()
212
213 logger.info(
214 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
215 )
216 logger.info("=" * 40)
217
218
219 #####################################################
220 #
221 # Local APIs
222 #
223 #####################################################
224
225
226 def pre_config_for_receiver_dr_tests(
227 tgen, topo, tc_name, highest_priority, lowest_priority
228 ):
229 """
230 API to do common pre-configuration for receiver test cases
231
232 parameters:
233 -----------
234 * `tgen`: topogen object
235 * `topo`: input json data
236 * `tc_name`: caller test case name
237 * `highest_priority`: router which will be having highest DR priority
238 * `lowest_priority`: router which will be having lowest DR priority
239 """
240
241 global intf_r1_s1, intf_r1_s1_addr, intf_r2_s1, intf_r2_s1_addr, intf_r3_s1, intf_r3_s1_addr, intf_i1_s1, intf_i1_s1_addr
242
243 step("Configure IGMP and PIM on switch connected receiver nodes")
244 step("Configure PIM on all upstream interfaces")
245
246 step("Configure link between R1, R2 ,R3 and receiver on" " same vlan")
247 step(
248 "Make sure {0} is DR initially configuring highest IP on {0} and R2 "
249 "second highest, {1} is lower".format(highest_priority, lowest_priority)
250 )
251
252 intf_r1_s1 = topo["routers"]["r1"]["links"]["s1"]["interface"]
253 intf_r1_s1_addr = topo["routers"]["r1"]["links"]["s1"]["ipv4"]
254
255 intf_r2_s1 = topo["routers"]["r2"]["links"]["s1"]["interface"]
256 intf_r2_s1_addr = topo["routers"]["r2"]["links"]["s1"]["ipv4"]
257
258 intf_r3_s1 = topo["routers"]["r3"]["links"]["s1"]["interface"]
259 intf_r3_s1_addr = topo["routers"]["r3"]["links"]["s1"]["ipv4"]
260
261 intf_i1_s1 = topo["routers"]["i1"]["links"]["s1"]["interface"]
262 intf_i1_s1_addr = topo["routers"]["i1"]["links"]["s1"]["ipv4"]
263
264 if lowest_priority == "r1":
265 lowest_pr_intf = intf_r1_s1
266 else:
267 lowest_pr_intf = intf_r3_s1
268
269 if highest_priority == "r1":
270 highest_pr_intf = intf_r1_s1
271 else:
272 highest_pr_intf = intf_r3_s1
273
274 vlan_input = {
275 lowest_priority: {
276 "vlan": {
277 VLAN_1: [
278 {
279 lowest_pr_intf: {
280 "ip": SAME_VLAN_IP_1["ip"],
281 "subnet": SAME_VLAN_IP_1["subnet"],
282 }
283 }
284 ]
285 }
286 },
287 "r2": {
288 "vlan": {
289 VLAN_1: [
290 {
291 intf_r2_s1: {
292 "ip": SAME_VLAN_IP_2["ip"],
293 "subnet": SAME_VLAN_IP_2["subnet"],
294 }
295 }
296 ]
297 }
298 },
299 highest_priority: {
300 "vlan": {
301 VLAN_1: [
302 {
303 highest_pr_intf: {
304 "ip": SAME_VLAN_IP_3["ip"],
305 "subnet": SAME_VLAN_IP_3["subnet"],
306 }
307 }
308 ]
309 }
310 },
311 "i1": {
312 "vlan": {
313 VLAN_1: [
314 {
315 intf_i1_s1: {
316 "ip": SAME_VLAN_IP_4["ip"],
317 "subnet": SAME_VLAN_IP_4["subnet"],
318 }
319 }
320 ]
321 }
322 },
323 }
324
325 add_interfaces_to_vlan(tgen, vlan_input)
326
327 raw_config = {
328 "r1": {
329 "raw_config": [
330 "interface {}".format(intf_r1_s1),
331 "no ip address {}".format(intf_r1_s1_addr),
332 "no ip pim",
333 ]
334 },
335 "r2": {
336 "raw_config": [
337 "interface {}".format(intf_r2_s1),
338 "no ip address {}".format(intf_r2_s1_addr),
339 "no ip pim",
340 ]
341 },
342 "r3": {
343 "raw_config": [
344 "interface {}".format(intf_r3_s1),
345 "no ip address {}".format(intf_r3_s1_addr),
346 "no ip pim",
347 ]
348 },
349 "i1": {
350 "raw_config": [
351 "interface {}".format(intf_i1_s1),
352 "no ip address {}".format(intf_i1_s1_addr),
353 ]
354 },
355 }
356
357 result = apply_raw_config(tgen, raw_config)
358 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
359
360 raw_config = {
361 lowest_priority: {
362 "raw_config": [
363 "interface {}.{}".format(lowest_pr_intf, VLAN_1),
364 "ip address {}/{}".format(SAME_VLAN_IP_1["ip"], SAME_VLAN_IP_1["cidr"]),
365 "ip pim",
366 "ip igmp",
367 "ip igmp version 2",
368 ]
369 },
370 "r2": {
371 "raw_config": [
372 "interface {}.{}".format(intf_r2_s1, VLAN_1),
373 "ip address {}/{}".format(SAME_VLAN_IP_2["ip"], SAME_VLAN_IP_2["cidr"]),
374 "ip pim",
375 "ip igmp",
376 "ip igmp version 2",
377 ]
378 },
379 highest_priority: {
380 "raw_config": [
381 "interface {}.{}".format(highest_pr_intf, VLAN_1),
382 "ip address {}/{}".format(SAME_VLAN_IP_3["ip"], SAME_VLAN_IP_3["cidr"]),
383 "ip pim",
384 "ip igmp",
385 "ip igmp version 2",
386 ]
387 },
388 "i1": {
389 "raw_config": [
390 "interface {}.{}".format(intf_i1_s1, VLAN_1),
391 "ip address {}/{}".format(SAME_VLAN_IP_4["ip"], SAME_VLAN_IP_4["cidr"]),
392 ]
393 },
394 }
395
396 result = apply_raw_config(tgen, raw_config)
397 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
398
399 for dut, intf in zip(["r1", "r2", "r3"], [intf_r1_s1, intf_r2_s1, intf_r3_s1]):
400 raw_config = {
401 dut: {
402 "raw_config": [
403 "interface {}.{}".format(intf, VLAN_1),
404 "ip pim hello {} {}".format(HELLO_TIMER, HOLD_TIMER),
405 ]
406 }
407 }
408 result = apply_raw_config(tgen, raw_config)
409 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
410
411 step("Configure R4 as RP on all the nodes for group range 224.0.0.0/24")
412
413 input_dict = {
414 "r4": {
415 "pim": {
416 "rp": [
417 {
418 "rp_addr": topo["routers"]["r4"]["links"]["lo"]["ipv4"].split(
419 "/"
420 )[0],
421 "group_addr_range": GROUP_RANGE_1,
422 }
423 ]
424 }
425 }
426 }
427
428 result = create_pim_config(tgen, topo, input_dict)
429 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
430
431 step("Send IGMP join for groups 226.1.1.1 to 226.1.1.5")
432
433 vlan_intf_i1_s1 = "{}.{}".format(intf_i1_s1, VLAN_1)
434 result = app_helper.run_join("i1", IGMP_JOIN_RANGE_1, join_intf=vlan_intf_i1_s1)
435 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
436
437 step("Using static routes instead OSPF: Enable OSPF between all the nodes")
438
439 step("Start traffic from R4 connected source")
440
441 result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "r5")
442 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
443
444 return True
445
446
447 def pre_config_for_source_dr_tests(
448 tgen, topo, tc_name, highest_priority, lowest_priority
449 ):
450 """
451 API to do common pre-configuration for source test cases
452
453 parameters:
454 -----------
455 * `tgen`: topogen object
456 * `topo`: input json data
457 * `tc_name`: caller test case name
458 * `highest_priority`: router which will be having highest DR priority
459 * `lowest_priority`: router which will be having lowest DR priority
460 """
461
462 global intf_r1_s1, intf_r1_s1_addr, intf_r2_s1, intf_r2_s1_addr, intf_r3_s1, intf_r3_s1_addr, intf_i1_s1, intf_i1_s1_addr
463
464 step("Configure IGMP and PIM on switch connected receiver nodes")
465 step("Configure PIM on all upstream interfaces")
466
467 step("Configure link between R1, R2 ,R3 and receiver on" " same vlan")
468 step(
469 "Make sure {0} is DR initially configuring highest IP on {0} and R2 "
470 "second highest, {1} is lower".format(highest_priority, lowest_priority)
471 )
472
473 intf_r1_s1 = topo["routers"]["r1"]["links"]["s1"]["interface"]
474 intf_r1_s1_addr = topo["routers"]["r1"]["links"]["s1"]["ipv4"]
475
476 intf_r2_s1 = topo["routers"]["r2"]["links"]["s1"]["interface"]
477 intf_r2_s1_addr = topo["routers"]["r2"]["links"]["s1"]["ipv4"]
478
479 intf_r3_s1 = topo["routers"]["r3"]["links"]["s1"]["interface"]
480 intf_r3_s1_addr = topo["routers"]["r3"]["links"]["s1"]["ipv4"]
481
482 intf_i1_s1 = topo["routers"]["i1"]["links"]["s1"]["interface"]
483 intf_i1_s1_addr = topo["routers"]["i1"]["links"]["s1"]["ipv4"]
484
485 if lowest_priority == "r1":
486 lowest_pr_intf = intf_r1_s1
487 else:
488 lowest_pr_intf = intf_r3_s1
489
490 if highest_priority == "r1":
491 highest_pr_intf = intf_r1_s1
492 else:
493 highest_pr_intf = intf_r3_s1
494
495 vlan_input = {
496 lowest_priority: {
497 "vlan": {
498 VLAN_1: [
499 {
500 lowest_pr_intf: {
501 "ip": SAME_VLAN_IP_1["ip"],
502 "subnet": SAME_VLAN_IP_1["subnet"],
503 }
504 }
505 ]
506 }
507 },
508 "r2": {
509 "vlan": {
510 VLAN_1: [
511 {
512 intf_r2_s1: {
513 "ip": SAME_VLAN_IP_2["ip"],
514 "subnet": SAME_VLAN_IP_2["subnet"],
515 }
516 }
517 ]
518 }
519 },
520 highest_priority: {
521 "vlan": {
522 VLAN_1: [
523 {
524 highest_pr_intf: {
525 "ip": SAME_VLAN_IP_3["ip"],
526 "subnet": SAME_VLAN_IP_3["subnet"],
527 }
528 }
529 ]
530 }
531 },
532 "i1": {
533 "vlan": {
534 VLAN_1: [
535 {
536 intf_i1_s1: {
537 "ip": SAME_VLAN_IP_4["ip"],
538 "subnet": SAME_VLAN_IP_4["subnet"],
539 }
540 }
541 ]
542 }
543 },
544 }
545
546 add_interfaces_to_vlan(tgen, vlan_input)
547
548 raw_config = {
549 "r1": {
550 "raw_config": [
551 "interface {}".format(intf_r1_s1),
552 "no ip address {}".format(intf_r1_s1_addr),
553 "no ip pim",
554 ]
555 },
556 "r2": {
557 "raw_config": [
558 "interface {}".format(intf_r2_s1),
559 "no ip address {}".format(intf_r2_s1_addr),
560 "no ip pim",
561 ]
562 },
563 "r3": {
564 "raw_config": [
565 "interface {}".format(intf_r3_s1),
566 "no ip address {}".format(intf_r3_s1_addr),
567 "no ip pim",
568 ]
569 },
570 "i1": {
571 "raw_config": [
572 "interface {}".format(intf_i1_s1),
573 "no ip address {}".format(intf_i1_s1_addr),
574 ]
575 },
576 }
577
578 result = apply_raw_config(tgen, raw_config)
579 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
580
581 step(
582 "Configure IGMP and PIM on switch connected receiver nodes , "
583 "configure PIM nbr with hello timer 1"
584 )
585
586 raw_config = {
587 lowest_priority: {
588 "raw_config": [
589 "interface {}.{}".format(lowest_pr_intf, VLAN_1),
590 "ip address {}/{}".format(SAME_VLAN_IP_1["ip"], SAME_VLAN_IP_1["cidr"]),
591 "ip pim",
592 ]
593 },
594 "r2": {
595 "raw_config": [
596 "interface {}.{}".format(intf_r2_s1, VLAN_1),
597 "ip address {}/{}".format(SAME_VLAN_IP_2["ip"], SAME_VLAN_IP_2["cidr"]),
598 "ip pim",
599 ]
600 },
601 highest_priority: {
602 "raw_config": [
603 "interface {}.{}".format(highest_pr_intf, VLAN_1),
604 "ip address {}/{}".format(SAME_VLAN_IP_3["ip"], SAME_VLAN_IP_3["cidr"]),
605 "ip pim",
606 ]
607 },
608 "i1": {
609 "raw_config": [
610 "interface {}.{}".format(intf_i1_s1, VLAN_1),
611 "ip address {}/{}".format(SAME_VLAN_IP_4["ip"], SAME_VLAN_IP_4["cidr"]),
612 ]
613 },
614 }
615
616 result = apply_raw_config(tgen, raw_config)
617 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
618
619 for dut, intf in zip(["r1", "r2", "r3"], [intf_r1_s1, intf_r2_s1, intf_r3_s1]):
620 raw_config = {
621 dut: {
622 "raw_config": [
623 "interface {}.{}".format(intf, VLAN_1),
624 "ip pim hello {} {}".format(HELLO_TIMER, HOLD_TIMER),
625 ]
626 }
627 }
628 result = apply_raw_config(tgen, raw_config)
629 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
630
631 step("Configure R4 as RP on all the nodes for group range 224.0.0.0/24")
632
633 input_dict = {
634 "r4": {
635 "pim": {
636 "rp": [
637 {
638 "rp_addr": topo["routers"]["r4"]["links"]["lo"]["ipv4"].split(
639 "/"
640 )[0],
641 "group_addr_range": GROUP_RANGE_1,
642 }
643 ]
644 }
645 }
646 }
647
648 result = create_pim_config(tgen, topo, input_dict)
649 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
650
651 step("Configure IGMP on R5 port and send IGMP join for groups " "(226.1.1.1-5)")
652
653 intf_r5_i2 = topo["routers"]["r5"]["links"]["i2"]["interface"]
654 input_dict = {
655 "r5": {"igmp": {"interfaces": {intf_r5_i2: {"igmp": {"version": "2"}}}}}
656 }
657 result = create_igmp_config(tgen, topo, input_dict)
658 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
659
660 input_src = {"i2": topo["routers"]["i2"]["links"]["r5"]["interface"]}
661
662 result = app_helper.run_join("i2", IGMP_JOIN_RANGE_1, "r5")
663 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
664
665 step("Using static routes instead OSPF: Enable OSPF between all the nodes")
666
667 step("Start traffic from Source node")
668
669 vlan_intf_i1_s1 = "{}.{}".format(intf_i1_s1, VLAN_1)
670 result = app_helper.run_traffic("i1", IGMP_JOIN_RANGE_1, bind_intf=vlan_intf_i1_s1)
671 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
672
673 return True
674
675
676 #####################################################
677 #
678 # Testcases
679 #
680 #####################################################
681
682
683 def test_pim_source_dr_functionality_while_rebooting_dr_non_dr_nodes_p1(request):
684 """
685 Verify mroute while rebooting DR /Non DR nodes( r1, r2 , r3 on all the nodes)
686 """
687
688 tgen = get_topogen()
689 tc_name = request.node.name
690 write_test_header(tc_name)
691
692 # Creating configuration from JSON
693 app_helper.stop_all_hosts()
694 clear_mroute(tgen)
695 check_router_status(tgen)
696 reset_config_on_routers(tgen)
697 clear_pim_interface_traffic(tgen, topo)
698
699 # Don"t run this test if we have any failure.
700 if tgen.routers_have_failure():
701 pytest.skip(tgen.errors)
702
703 result = pre_config_for_source_dr_tests(tgen, topo, tc_name, "r1", "r3")
704 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
705
706 step("R1 is the DR , verify using 'show ip pim interface json'")
707
708 vlan_intf_r1_s1 = "{}.{}".format(intf_r1_s1, VLAN_1)
709 input_dict_dr = {
710 "r1": {
711 "pim": {
712 "interfaces": {vlan_intf_r1_s1: {"drAddress": SAME_VLAN_IP_3["ip"]}}
713 }
714 }
715 }
716 result = verify_pim_config(tgen, input_dict_dr)
717 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
718
719 step(
720 "R2 is transit router for I1 to reach R4, mroute should have (s, g) mroute with "
721 "OIL towards R4, using 'show ip mroute json'"
722 )
723 step(
724 "R2 (s, g) upstream should be in join state verify using "
725 "'show ip pim upstream json'"
726 )
727 step(
728 "R1 has (S, G) mroute with NONE OIL and upstream as not joined, verify using "
729 "'show ip mroute json' 'show ip pim upstream json'"
730 )
731
732 source_i1 = SAME_VLAN_IP_4["ip"]
733 input_dict_r1_r2 = [
734 {
735 "dut": "r1",
736 "src_address": source_i1,
737 "oil": "none",
738 "iif": "{}.{}".format(
739 topo["routers"]["r1"]["links"]["s1"]["interface"], VLAN_1
740 ),
741 },
742 {
743 "dut": "r2",
744 "src_address": source_i1,
745 "oil": topo["routers"]["r2"]["links"]["r4"]["interface"],
746 "iif": "{}.{}".format(
747 topo["routers"]["r2"]["links"]["s1"]["interface"], VLAN_1
748 ),
749 },
750 ]
751
752 for data in input_dict_r1_r2:
753 result = verify_mroutes(
754 tgen,
755 data["dut"],
756 data["src_address"],
757 IGMP_JOIN_RANGE_1,
758 data["iif"],
759 data["oil"],
760 )
761 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
762
763 if data["dut"] == "r2":
764 result = verify_upstream_iif(
765 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
766 )
767 assert result is True, "Testcase {} : Failed Error: {}".format(
768 tc_name, result
769 )
770 else:
771 result = verify_upstream_iif(
772 tgen,
773 data["dut"],
774 data["iif"],
775 data["src_address"],
776 IGMP_JOIN_RANGE_1,
777 expected=False,
778 )
779 assert result is not True, (
780 "Testcase {} : Failed \n "
781 "Upstream is still joined state \n Error: {}".format(tc_name, result)
782 )
783
784 step("Reboot R3 node")
785 stop_router(tgen, "r3")
786
787 step(
788 "After reboot of R3 verify R1 continues to be DR, using 'show ip pim interface json'"
789 )
790
791 result = verify_pim_config(tgen, input_dict_dr)
792 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
793
794 step("R3 should not have any mroute and upstream")
795 step("R2 has mroute with OIL towards R4 /R1 , verify using 'show ip mroute'")
796 step(
797 "R2 has upstream with Join RejP state verify using 'show ip pim upstream json'"
798 )
799 step("R1 has mroute with none OIL and upstream with Not Join")
800
801 for data in input_dict_r1_r2:
802 result = verify_mroutes(
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 if data["dut"] == "r2":
813 result = verify_upstream_iif(
814 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
815 )
816 assert result is True, "Testcase {} : Failed Error: {}".format(
817 tc_name, result
818 )
819 else:
820 result = verify_upstream_iif(
821 tgen,
822 data["dut"],
823 data["iif"],
824 data["src_address"],
825 IGMP_JOIN_RANGE_1,
826 expected=False,
827 )
828 assert result is not True, (
829 "Testcase {} : Failed \n "
830 "Upstream is still joined state \n Error: {}".format(tc_name, result)
831 )
832
833 step("Reboot R2 node")
834 stop_router(tgen, "r2")
835
836 step(
837 "After reboot of R2, R1 continues to be DR verify using 'show ip pim interface json'"
838 )
839
840 result = verify_pim_config(tgen, input_dict_dr)
841 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
842
843 step(
844 "R3 and R2 should not have any mroute and upstream , verify using "
845 "'show ip mroute json' 'show ip pim upstream json'"
846 )
847 step("R1 has mroute created with empty OIL, using 'show ip mroute json'")
848 step(
849 "R1 has upstream with Not Join, Rej Prune , verify using 'show ip pim upstream json'"
850 )
851
852 for data in input_dict_r1_r2:
853 if data["dut"] == "r1":
854 result = verify_mroutes(
855 tgen,
856 data["dut"],
857 data["src_address"],
858 IGMP_JOIN_RANGE_1,
859 data["iif"],
860 data["oil"],
861 )
862 assert result is True, "Testcase {} : Failed Error: {}".format(
863 tc_name, result
864 )
865
866 result = verify_upstream_iif(
867 tgen,
868 data["dut"],
869 data["iif"],
870 data["src_address"],
871 IGMP_JOIN_RANGE_1,
872 expected=False,
873 )
874 assert result is not True, (
875 "Testcase {} : Failed \n "
876 "Upstream is still joined state \n Error: {}".format(tc_name, result)
877 )
878
879 step("Reboot R1 node using FRR stop")
880 stop_router(tgen, "r1")
881
882 step(
883 "After stop of all the routers, verify upstream and mroutes should "
884 "not present in any of them"
885 )
886
887 for data in input_dict_r1_r2:
888 result = verify_mroutes(
889 tgen,
890 data["dut"],
891 data["src_address"],
892 IGMP_JOIN_RANGE_1,
893 data["iif"],
894 data["oil"],
895 expected=False,
896 )
897 assert (
898 result is not True
899 ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format(
900 tc_name, result
901 )
902
903 step("start FRR for all the nodes")
904 start_router(tgen, "r1")
905 start_router(tgen, "r2")
906 start_router(tgen, "r3")
907
908 step("After start of all the routers, R1 became DR")
909
910 result = verify_pim_config(tgen, input_dict_dr)
911 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
912
913 for data in input_dict_r1_r2:
914 result = verify_mroutes(
915 tgen,
916 data["dut"],
917 data["src_address"],
918 IGMP_JOIN_RANGE_1,
919 data["iif"],
920 data["oil"],
921 )
922 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
923
924 if data["dut"] == "r2":
925 result = verify_upstream_iif(
926 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
927 )
928 assert result is True, "Testcase {} : Failed Error: {}".format(
929 tc_name, result
930 )
931
932 write_test_footer(tc_name)
933
934
935 if __name__ == "__main__":
936 args = ["-s"] + sys.argv[1:]
937 sys.exit(pytest.main(args))