]> 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 #11128 from opensourcerouting/feature/rfc8538
[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 # get list of daemons needs to be started for this suite.
184 daemons = topo_daemons(tgen, tgen.json_topo)
185
186 # Starting topology, create tmp files which are loaded to routers
187 # to start deamons and then start routers
188 start_topology(tgen, daemons)
189
190 # Don"t run this test if we have any failure.
191 if tgen.routers_have_failure():
192 pytest.skip(tgen.errors)
193
194 # Creating configuration from JSON
195 build_config_from_json(tgen, tgen.json_topo)
196
197 # XXX Replace this using "with McastTesterHelper()... " in each test if possible.
198 global app_helper
199 app_helper = McastTesterHelper(tgen)
200
201 logger.info("Running setup_module() done")
202
203
204 def teardown_module():
205 """Teardown the pytest environment"""
206
207 logger.info("Running teardown_module to delete topology")
208
209 tgen = get_topogen()
210
211 app_helper.cleanup()
212
213 # Stop toplogy and Remove tmp files
214 tgen.stop_topology()
215
216 logger.info(
217 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
218 )
219 logger.info("=" * 40)
220
221
222 #####################################################
223 #
224 # Local APIs
225 #
226 #####################################################
227
228
229 def pre_config_for_receiver_dr_tests(
230 tgen, topo, tc_name, highest_priority, lowest_priority
231 ):
232 """
233 API to do common pre-configuration for receiver test cases
234
235 parameters:
236 -----------
237 * `tgen`: topogen object
238 * `topo`: input json data
239 * `tc_name`: caller test case name
240 * `highest_priority`: router which will be having highest DR priority
241 * `lowest_priority`: router which will be having lowest DR priority
242 """
243
244 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
245
246 step("Configure IGMP and PIM on switch connected receiver nodes")
247 step("Configure PIM on all upstream interfaces")
248
249 step("Configure link between R1, R2 ,R3 and receiver on" " same vlan")
250 step(
251 "Make sure {0} is DR initially configuring highest IP on {0} and R2 "
252 "second highest, {1} is lower".format(highest_priority, lowest_priority)
253 )
254
255 intf_r1_s1 = topo["routers"]["r1"]["links"]["s1"]["interface"]
256 intf_r1_s1_addr = topo["routers"]["r1"]["links"]["s1"]["ipv4"]
257
258 intf_r2_s1 = topo["routers"]["r2"]["links"]["s1"]["interface"]
259 intf_r2_s1_addr = topo["routers"]["r2"]["links"]["s1"]["ipv4"]
260
261 intf_r3_s1 = topo["routers"]["r3"]["links"]["s1"]["interface"]
262 intf_r3_s1_addr = topo["routers"]["r3"]["links"]["s1"]["ipv4"]
263
264 intf_i1_s1 = topo["routers"]["i1"]["links"]["s1"]["interface"]
265 intf_i1_s1_addr = topo["routers"]["i1"]["links"]["s1"]["ipv4"]
266
267 if lowest_priority == "r1":
268 lowest_pr_intf = intf_r1_s1
269 else:
270 lowest_pr_intf = intf_r3_s1
271
272 if highest_priority == "r1":
273 highest_pr_intf = intf_r1_s1
274 else:
275 highest_pr_intf = intf_r3_s1
276
277 vlan_input = {
278 lowest_priority: {
279 "vlan": {
280 VLAN_1: [
281 {
282 lowest_pr_intf: {
283 "ip": SAME_VLAN_IP_1["ip"],
284 "subnet": SAME_VLAN_IP_1["subnet"],
285 }
286 }
287 ]
288 }
289 },
290 "r2": {
291 "vlan": {
292 VLAN_1: [
293 {
294 intf_r2_s1: {
295 "ip": SAME_VLAN_IP_2["ip"],
296 "subnet": SAME_VLAN_IP_2["subnet"],
297 }
298 }
299 ]
300 }
301 },
302 highest_priority: {
303 "vlan": {
304 VLAN_1: [
305 {
306 highest_pr_intf: {
307 "ip": SAME_VLAN_IP_3["ip"],
308 "subnet": SAME_VLAN_IP_3["subnet"],
309 }
310 }
311 ]
312 }
313 },
314 "i1": {
315 "vlan": {
316 VLAN_1: [
317 {
318 intf_i1_s1: {
319 "ip": SAME_VLAN_IP_4["ip"],
320 "subnet": SAME_VLAN_IP_4["subnet"],
321 }
322 }
323 ]
324 }
325 },
326 }
327
328 add_interfaces_to_vlan(tgen, vlan_input)
329
330 raw_config = {
331 "r1": {
332 "raw_config": [
333 "interface {}".format(intf_r1_s1),
334 "no ip address {}".format(intf_r1_s1_addr),
335 "no ip pim",
336 ]
337 },
338 "r2": {
339 "raw_config": [
340 "interface {}".format(intf_r2_s1),
341 "no ip address {}".format(intf_r2_s1_addr),
342 "no ip pim",
343 ]
344 },
345 "r3": {
346 "raw_config": [
347 "interface {}".format(intf_r3_s1),
348 "no ip address {}".format(intf_r3_s1_addr),
349 "no ip pim",
350 ]
351 },
352 "i1": {
353 "raw_config": [
354 "interface {}".format(intf_i1_s1),
355 "no ip address {}".format(intf_i1_s1_addr),
356 ]
357 },
358 }
359
360 result = apply_raw_config(tgen, raw_config)
361 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
362
363 raw_config = {
364 lowest_priority: {
365 "raw_config": [
366 "interface {}.{}".format(lowest_pr_intf, VLAN_1),
367 "ip address {}/{}".format(SAME_VLAN_IP_1["ip"], SAME_VLAN_IP_1["cidr"]),
368 "ip pim",
369 "ip igmp",
370 "ip igmp version 2",
371 ]
372 },
373 "r2": {
374 "raw_config": [
375 "interface {}.{}".format(intf_r2_s1, VLAN_1),
376 "ip address {}/{}".format(SAME_VLAN_IP_2["ip"], SAME_VLAN_IP_2["cidr"]),
377 "ip pim",
378 "ip igmp",
379 "ip igmp version 2",
380 ]
381 },
382 highest_priority: {
383 "raw_config": [
384 "interface {}.{}".format(highest_pr_intf, VLAN_1),
385 "ip address {}/{}".format(SAME_VLAN_IP_3["ip"], SAME_VLAN_IP_3["cidr"]),
386 "ip pim",
387 "ip igmp",
388 "ip igmp version 2",
389 ]
390 },
391 "i1": {
392 "raw_config": [
393 "interface {}.{}".format(intf_i1_s1, VLAN_1),
394 "ip address {}/{}".format(SAME_VLAN_IP_4["ip"], SAME_VLAN_IP_4["cidr"]),
395 ]
396 },
397 }
398
399 result = apply_raw_config(tgen, raw_config)
400 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
401
402 for dut, intf in zip(["r1", "r2", "r3"], [intf_r1_s1, intf_r2_s1, intf_r3_s1]):
403 raw_config = {
404 dut: {
405 "raw_config": [
406 "interface {}.{}".format(intf, VLAN_1),
407 "ip pim hello {} {}".format(HELLO_TIMER, HOLD_TIMER),
408 ]
409 }
410 }
411 result = apply_raw_config(tgen, raw_config)
412 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
413
414 step("Configure R4 as RP on all the nodes for group range 224.0.0.0/24")
415
416 input_dict = {
417 "r4": {
418 "pim": {
419 "rp": [
420 {
421 "rp_addr": topo["routers"]["r4"]["links"]["lo"]["ipv4"].split(
422 "/"
423 )[0],
424 "group_addr_range": GROUP_RANGE_1,
425 }
426 ]
427 }
428 }
429 }
430
431 result = create_pim_config(tgen, topo, input_dict)
432 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
433
434 step("Send IGMP join for groups 226.1.1.1 to 226.1.1.5")
435
436 vlan_intf_i1_s1 = "{}.{}".format(intf_i1_s1, VLAN_1)
437 result = app_helper.run_join("i1", IGMP_JOIN_RANGE_1, join_intf=vlan_intf_i1_s1)
438 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
439
440 step("Using static routes instead OSPF: Enable OSPF between all the nodes")
441
442 step("Start traffic from R4 connected source")
443
444 result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "r5")
445 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
446
447 return True
448
449
450 def pre_config_for_source_dr_tests(
451 tgen, topo, tc_name, highest_priority, lowest_priority
452 ):
453 """
454 API to do common pre-configuration for source test cases
455
456 parameters:
457 -----------
458 * `tgen`: topogen object
459 * `topo`: input json data
460 * `tc_name`: caller test case name
461 * `highest_priority`: router which will be having highest DR priority
462 * `lowest_priority`: router which will be having lowest DR priority
463 """
464
465 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
466
467 step("Configure IGMP and PIM on switch connected receiver nodes")
468 step("Configure PIM on all upstream interfaces")
469
470 step("Configure link between R1, R2 ,R3 and receiver on" " same vlan")
471 step(
472 "Make sure {0} is DR initially configuring highest IP on {0} and R2 "
473 "second highest, {1} is lower".format(highest_priority, lowest_priority)
474 )
475
476 intf_r1_s1 = topo["routers"]["r1"]["links"]["s1"]["interface"]
477 intf_r1_s1_addr = topo["routers"]["r1"]["links"]["s1"]["ipv4"]
478
479 intf_r2_s1 = topo["routers"]["r2"]["links"]["s1"]["interface"]
480 intf_r2_s1_addr = topo["routers"]["r2"]["links"]["s1"]["ipv4"]
481
482 intf_r3_s1 = topo["routers"]["r3"]["links"]["s1"]["interface"]
483 intf_r3_s1_addr = topo["routers"]["r3"]["links"]["s1"]["ipv4"]
484
485 intf_i1_s1 = topo["routers"]["i1"]["links"]["s1"]["interface"]
486 intf_i1_s1_addr = topo["routers"]["i1"]["links"]["s1"]["ipv4"]
487
488 if lowest_priority == "r1":
489 lowest_pr_intf = intf_r1_s1
490 else:
491 lowest_pr_intf = intf_r3_s1
492
493 if highest_priority == "r1":
494 highest_pr_intf = intf_r1_s1
495 else:
496 highest_pr_intf = intf_r3_s1
497
498 vlan_input = {
499 lowest_priority: {
500 "vlan": {
501 VLAN_1: [
502 {
503 lowest_pr_intf: {
504 "ip": SAME_VLAN_IP_1["ip"],
505 "subnet": SAME_VLAN_IP_1["subnet"],
506 }
507 }
508 ]
509 }
510 },
511 "r2": {
512 "vlan": {
513 VLAN_1: [
514 {
515 intf_r2_s1: {
516 "ip": SAME_VLAN_IP_2["ip"],
517 "subnet": SAME_VLAN_IP_2["subnet"],
518 }
519 }
520 ]
521 }
522 },
523 highest_priority: {
524 "vlan": {
525 VLAN_1: [
526 {
527 highest_pr_intf: {
528 "ip": SAME_VLAN_IP_3["ip"],
529 "subnet": SAME_VLAN_IP_3["subnet"],
530 }
531 }
532 ]
533 }
534 },
535 "i1": {
536 "vlan": {
537 VLAN_1: [
538 {
539 intf_i1_s1: {
540 "ip": SAME_VLAN_IP_4["ip"],
541 "subnet": SAME_VLAN_IP_4["subnet"],
542 }
543 }
544 ]
545 }
546 },
547 }
548
549 add_interfaces_to_vlan(tgen, vlan_input)
550
551 raw_config = {
552 "r1": {
553 "raw_config": [
554 "interface {}".format(intf_r1_s1),
555 "no ip address {}".format(intf_r1_s1_addr),
556 "no ip pim",
557 ]
558 },
559 "r2": {
560 "raw_config": [
561 "interface {}".format(intf_r2_s1),
562 "no ip address {}".format(intf_r2_s1_addr),
563 "no ip pim",
564 ]
565 },
566 "r3": {
567 "raw_config": [
568 "interface {}".format(intf_r3_s1),
569 "no ip address {}".format(intf_r3_s1_addr),
570 "no ip pim",
571 ]
572 },
573 "i1": {
574 "raw_config": [
575 "interface {}".format(intf_i1_s1),
576 "no ip address {}".format(intf_i1_s1_addr),
577 ]
578 },
579 }
580
581 result = apply_raw_config(tgen, raw_config)
582 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
583
584 step(
585 "Configure IGMP and PIM on switch connected receiver nodes , "
586 "configure PIM nbr with hello timer 1"
587 )
588
589 raw_config = {
590 lowest_priority: {
591 "raw_config": [
592 "interface {}.{}".format(lowest_pr_intf, VLAN_1),
593 "ip address {}/{}".format(SAME_VLAN_IP_1["ip"], SAME_VLAN_IP_1["cidr"]),
594 "ip pim",
595 ]
596 },
597 "r2": {
598 "raw_config": [
599 "interface {}.{}".format(intf_r2_s1, VLAN_1),
600 "ip address {}/{}".format(SAME_VLAN_IP_2["ip"], SAME_VLAN_IP_2["cidr"]),
601 "ip pim",
602 ]
603 },
604 highest_priority: {
605 "raw_config": [
606 "interface {}.{}".format(highest_pr_intf, VLAN_1),
607 "ip address {}/{}".format(SAME_VLAN_IP_3["ip"], SAME_VLAN_IP_3["cidr"]),
608 "ip pim",
609 ]
610 },
611 "i1": {
612 "raw_config": [
613 "interface {}.{}".format(intf_i1_s1, VLAN_1),
614 "ip address {}/{}".format(SAME_VLAN_IP_4["ip"], SAME_VLAN_IP_4["cidr"]),
615 ]
616 },
617 }
618
619 result = apply_raw_config(tgen, raw_config)
620 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
621
622 for dut, intf in zip(["r1", "r2", "r3"], [intf_r1_s1, intf_r2_s1, intf_r3_s1]):
623 raw_config = {
624 dut: {
625 "raw_config": [
626 "interface {}.{}".format(intf, VLAN_1),
627 "ip pim hello {} {}".format(HELLO_TIMER, HOLD_TIMER),
628 ]
629 }
630 }
631 result = apply_raw_config(tgen, raw_config)
632 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
633
634 step("Configure R4 as RP on all the nodes for group range 224.0.0.0/24")
635
636 input_dict = {
637 "r4": {
638 "pim": {
639 "rp": [
640 {
641 "rp_addr": topo["routers"]["r4"]["links"]["lo"]["ipv4"].split(
642 "/"
643 )[0],
644 "group_addr_range": GROUP_RANGE_1,
645 }
646 ]
647 }
648 }
649 }
650
651 result = create_pim_config(tgen, topo, input_dict)
652 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
653
654 step("Configure IGMP on R5 port and send IGMP join for groups " "(226.1.1.1-5)")
655
656 intf_r5_i2 = topo["routers"]["r5"]["links"]["i2"]["interface"]
657 input_dict = {
658 "r5": {"igmp": {"interfaces": {intf_r5_i2: {"igmp": {"version": "2"}}}}}
659 }
660 result = create_igmp_config(tgen, topo, input_dict)
661 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
662
663 input_src = {"i2": topo["routers"]["i2"]["links"]["r5"]["interface"]}
664
665 result = app_helper.run_join("i2", IGMP_JOIN_RANGE_1, "r5")
666 assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
667
668 step("Using static routes instead OSPF: Enable OSPF between all the nodes")
669
670 step("Start traffic from Source node")
671
672 vlan_intf_i1_s1 = "{}.{}".format(intf_i1_s1, VLAN_1)
673 result = app_helper.run_traffic("i1", IGMP_JOIN_RANGE_1, bind_intf=vlan_intf_i1_s1)
674 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
675
676 return True
677
678
679 #####################################################
680 #
681 # Testcases
682 #
683 #####################################################
684
685
686 def test_pim_source_dr_functionality_while_rebooting_dr_non_dr_nodes_p1(request):
687 """
688 Verify mroute while rebooting DR /Non DR nodes( r1, r2 , r3 on all the nodes)
689 """
690
691 tgen = get_topogen()
692 tc_name = request.node.name
693 write_test_header(tc_name)
694
695 # Creating configuration from JSON
696 app_helper.stop_all_hosts()
697 clear_mroute(tgen)
698 check_router_status(tgen)
699 reset_config_on_routers(tgen)
700 clear_pim_interface_traffic(tgen, topo)
701
702 # Don"t run this test if we have any failure.
703 if tgen.routers_have_failure():
704 pytest.skip(tgen.errors)
705
706 result = pre_config_for_source_dr_tests(tgen, topo, tc_name, "r1", "r3")
707 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
708
709 step("R1 is the DR , verify using 'show ip pim interface json'")
710
711 vlan_intf_r1_s1 = "{}.{}".format(intf_r1_s1, VLAN_1)
712 input_dict_dr = {
713 "r1": {
714 "pim": {
715 "interfaces": {vlan_intf_r1_s1: {"drAddress": SAME_VLAN_IP_3["ip"]}}
716 }
717 }
718 }
719 result = verify_pim_config(tgen, input_dict_dr)
720 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
721
722 step(
723 "R2 is transit router for R3 to reach R4, mroute should have (s, g) mroute with "
724 "OIL towards R4, using 'show ip mroute json'"
725 )
726 step(
727 "R2 (s, g) upstream should be in join state verify using "
728 "'show ip pim upstream json'"
729 )
730 step(
731 "R1 has (S, G) mroute with NONE OIL and upstream as not joined, verify using "
732 "'show ip mroute json' 'show ip pim upstream json'"
733 )
734
735 source_i1 = SAME_VLAN_IP_4["ip"]
736 input_dict_r1_r2 = [
737 {
738 "dut": "r1",
739 "src_address": source_i1,
740 "oil": "none",
741 "iif": "{}.{}".format(
742 topo["routers"]["r1"]["links"]["s1"]["interface"], VLAN_1
743 ),
744 },
745 {
746 "dut": "r2",
747 "src_address": source_i1,
748 "oil": topo["routers"]["r2"]["links"]["r4"]["interface"],
749 "iif": "{}.{}".format(
750 topo["routers"]["r2"]["links"]["s1"]["interface"], VLAN_1
751 ),
752 },
753 ]
754
755 for data in input_dict_r1_r2:
756 result = verify_mroutes(
757 tgen,
758 data["dut"],
759 data["src_address"],
760 IGMP_JOIN_RANGE_1,
761 data["iif"],
762 data["oil"],
763 )
764 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
765
766 if data["dut"] == "r2":
767 result = verify_upstream_iif(
768 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
769 )
770 assert result is True, "Testcase {} : Failed Error: {}".format(
771 tc_name, result
772 )
773 else:
774 result = verify_upstream_iif(
775 tgen,
776 data["dut"],
777 data["iif"],
778 data["src_address"],
779 IGMP_JOIN_RANGE_1,
780 expected=False,
781 )
782 assert result is not True, (
783 "Testcase {} : Failed \n "
784 "Upstream is still joined state \n Error: {}".format(tc_name, result)
785 )
786
787 step("Reboot R3 node")
788 stop_router(tgen, "r3")
789
790 step("After reboot of R3 verify R1 became DR, using 'show ip pim interface json'")
791
792 result = verify_pim_config(tgen, input_dict_dr)
793 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
794
795 step("R3 should not have any mroute and upstream")
796 step("R2 has mroute with OIL towards R4 /R1 , verify using 'show ip mroute'")
797 step(
798 "R2 has upstream with Join RejP state verify using 'show ip pim upstream json'"
799 )
800 step("R1 has mroute with none OIL and upstream with Not Join")
801
802 for data in input_dict_r1_r2:
803 result = verify_mroutes(
804 tgen,
805 data["dut"],
806 data["src_address"],
807 IGMP_JOIN_RANGE_1,
808 data["iif"],
809 data["oil"],
810 )
811 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
812
813 if data["dut"] == "r2":
814 result = verify_upstream_iif(
815 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
816 )
817 assert result is True, "Testcase {} : Failed Error: {}".format(
818 tc_name, result
819 )
820 else:
821 result = verify_upstream_iif(
822 tgen,
823 data["dut"],
824 data["iif"],
825 data["src_address"],
826 IGMP_JOIN_RANGE_1,
827 expected=False,
828 )
829 assert result is not True, (
830 "Testcase {} : Failed \n "
831 "Upstream is still joined state \n Error: {}".format(tc_name, result)
832 )
833
834 step("Reboot R2 node")
835 stop_router(tgen, "r2")
836
837 step("After reboot of R2, R1 became DR verify using 'show ip pim interface json'")
838
839 result = verify_pim_config(tgen, input_dict_dr)
840 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
841
842 step(
843 "R3 and R2 should not have any mroute and upstream , verify using "
844 "'show ip mroute json' 'show ip pim upstream json'"
845 )
846 step("R1 has mroute created with OIL towards R4 , using 'show ip mroute json'")
847 step(
848 "R1 has upstream with Join Rej Prune , verify using 'show ip pim upstream json'"
849 )
850
851 for data in input_dict_r1_r2:
852 if data["dut"] == "r1":
853 result = verify_mroutes(
854 tgen,
855 data["dut"],
856 data["src_address"],
857 IGMP_JOIN_RANGE_1,
858 data["iif"],
859 data["oil"],
860 )
861 assert result is True, "Testcase {} : Failed Error: {}".format(
862 tc_name, result
863 )
864
865 result = verify_upstream_iif(
866 tgen,
867 data["dut"],
868 data["iif"],
869 data["src_address"],
870 IGMP_JOIN_RANGE_1,
871 expected=False,
872 )
873 assert result is not True, (
874 "Testcase {} : Failed \n "
875 "Upstream is still joined state \n Error: {}".format(tc_name, result)
876 )
877
878 step("Reboot R1 node using FRR stop")
879 stop_router(tgen, "r1")
880
881 step(
882 "After stop of all the routers, verify upstream and mroutes should "
883 "not present in any of them"
884 )
885
886 for data in input_dict_r1_r2:
887 result = verify_mroutes(
888 tgen,
889 data["dut"],
890 data["src_address"],
891 IGMP_JOIN_RANGE_1,
892 data["iif"],
893 data["oil"],
894 expected=False,
895 )
896 assert (
897 result is not True
898 ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format(
899 tc_name, result
900 )
901
902 step("start FRR for all the nodes")
903 start_router(tgen, "r1")
904 start_router(tgen, "r2")
905 start_router(tgen, "r3")
906
907 step("After start of all the routers, R1 became DR")
908
909 result = verify_pim_config(tgen, input_dict_dr)
910 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
911
912 for data in input_dict_r1_r2:
913 result = verify_mroutes(
914 tgen,
915 data["dut"],
916 data["src_address"],
917 IGMP_JOIN_RANGE_1,
918 data["iif"],
919 data["oil"],
920 )
921 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
922
923 if data["dut"] == "r2":
924 result = verify_upstream_iif(
925 tgen, data["dut"], data["iif"], data["src_address"], IGMP_JOIN_RANGE_1
926 )
927 assert result is True, "Testcase {} : Failed Error: {}".format(
928 tc_name, result
929 )
930
931 write_test_footer(tc_name)
932
933
934 if __name__ == "__main__":
935 args = ["-s"] + sys.argv[1:]
936 sys.exit(pytest.main(args))