]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / static_routing_with_ebgp / test_static_routes_topo3_ebgp.py
1 #!/usr/bin/python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Copyright (c) 2020 by VMware, Inc. ("VMware")
6 # Used Copyright (c) 2018 by Network Device Education Foundation,
7 # Inc. ("NetDEF") in this file.
8 #
9 """
10 -Verify static route ECMP functionality with 8 next hop
11
12 -Verify static route functionality with 8 next hop different AD value
13
14 -Verify static route with tag option
15
16 -Verify BGP did not install the static route when it receive route
17 with local next hop
18
19 """
20 import sys
21 import time
22 import os
23 import pytest
24 import random
25 import platform
26 from lib.topotest import version_cmp
27
28 # Save the Current Working Directory to find configuration files.
29 CWD = os.path.dirname(os.path.realpath(__file__))
30 sys.path.append(os.path.join(CWD, "../"))
31 sys.path.append(os.path.join(CWD, "../lib/"))
32 # pylint: disable=C0413
33 # Import topogen and topotest helpers
34 from lib.topogen import Topogen, get_topogen
35
36 from lib.common_config import (
37 start_topology,
38 write_test_header,
39 write_test_footer,
40 reset_config_on_routers,
41 verify_rib,
42 create_static_routes,
43 check_address_types,
44 step,
45 shutdown_bringup_interface,
46 stop_router,
47 start_router,
48 create_route_maps,
49 verify_ip_nht,
50 )
51 from lib.topolog import logger
52 from lib.bgp import verify_bgp_convergence, create_router_bgp, verify_bgp_rib
53 from lib.topojson import build_config_from_json
54
55 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
56
57 # Global variables
58 BGP_CONVERGENCE = False
59 ADDR_TYPES = check_address_types()
60 NETWORK = {
61 "ipv4": [
62 "11.0.20.1/32",
63 "11.0.20.2/32",
64 "11.0.20.3/32",
65 "11.0.20.4/32",
66 "11.0.20.5/32",
67 "11.0.20.6/32",
68 "11.0.20.7/32",
69 "11.0.20.8/32",
70 ],
71 "ipv6": [
72 "2::1/128",
73 "2::2/128",
74 "2::3/128",
75 "2::4/128",
76 "2::5/128",
77 "2::6/128",
78 "2::7/128",
79 "2::8/128",
80 ],
81 }
82 PREFIX1 = {"ipv4": "110.0.20.1/32", "ipv6": "20::1/128"}
83 NETWORK2 = {"ipv4": ["11.0.20.1/32"], "ipv6": ["2::1/128"]}
84 NEXT_HOP_IP = []
85
86
87 def setup_module(mod):
88 """
89
90 Set up the pytest environment.
91
92 * `mod`: module name
93 """
94 testsuite_run_time = time.asctime(time.localtime(time.time()))
95 logger.info("Testsuite start time: {}".format(testsuite_run_time))
96 logger.info("=" * 40)
97
98 logger.info("Running setup_module to create topology")
99
100 # This function initiates the topology build with Topogen...
101 json_file = "{}/static_routes_topo3_ebgp.json".format(CWD)
102 tgen = Topogen(json_file, mod.__name__)
103 global topo
104 topo = tgen.json_topo
105 # ... and here it calls Mininet initialization functions.
106
107 # Starting topology, create tmp files which are loaded to routers
108 # to start daemons and then start routers
109 start_topology(tgen)
110
111 # Creating configuration from JSON
112 build_config_from_json(tgen, topo)
113
114 if version_cmp(platform.release(), "4.19") < 0:
115 error_msg = (
116 'These tests will not run. (have kernel "{}", '
117 "requires kernel >= 4.19)".format(platform.release())
118 )
119 pytest.skip(error_msg)
120
121 # Checking BGP convergence
122 global BGP_CONVERGENCE
123 global ADDR_TYPES
124
125 # Don't run this test if we have any failure.
126 if tgen.routers_have_failure():
127 pytest.skip(tgen.errors)
128 # Api call verify whether BGP is converged
129 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
130 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
131 BGP_CONVERGENCE
132 )
133
134 logger.info("Running setup_module() done")
135
136
137 def teardown_module(mod):
138 """
139 Teardown the pytest environment
140
141 * `mod`: module name
142 """
143
144 logger.info("Running teardown_module to delete topology")
145
146 tgen = get_topogen()
147
148 # Stop toplogy and Remove tmp files
149 tgen.stop_topology()
150
151 logger.info(
152 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
153 )
154 logger.info("=" * 40)
155
156
157 def populate_nh():
158 NEXT_HOP_IP = {
159 "nh1": {
160 "ipv4": topo["routers"]["r1"]["links"]["r2-link0"]["ipv4"].split("/")[0],
161 "ipv6": topo["routers"]["r1"]["links"]["r2-link0"]["ipv6"].split("/")[0],
162 },
163 "nh2": {
164 "ipv4": topo["routers"]["r1"]["links"]["r2-link1"]["ipv4"].split("/")[0],
165 "ipv6": topo["routers"]["r1"]["links"]["r2-link1"]["ipv6"].split("/")[0],
166 },
167 "nh3": {
168 "ipv4": topo["routers"]["r1"]["links"]["r2-link2"]["ipv4"].split("/")[0],
169 "ipv6": topo["routers"]["r1"]["links"]["r2-link2"]["ipv6"].split("/")[0],
170 },
171 "nh4": {
172 "ipv4": topo["routers"]["r1"]["links"]["r2-link3"]["ipv4"].split("/")[0],
173 "ipv6": topo["routers"]["r1"]["links"]["r2-link3"]["ipv6"].split("/")[0],
174 },
175 "nh5": {
176 "ipv4": topo["routers"]["r1"]["links"]["r2-link4"]["ipv4"].split("/")[0],
177 "ipv6": topo["routers"]["r1"]["links"]["r2-link4"]["ipv6"].split("/")[0],
178 },
179 "nh6": {
180 "ipv4": topo["routers"]["r1"]["links"]["r2-link5"]["ipv4"].split("/")[0],
181 "ipv6": topo["routers"]["r1"]["links"]["r2-link5"]["ipv6"].split("/")[0],
182 },
183 "nh7": {
184 "ipv4": topo["routers"]["r1"]["links"]["r2-link6"]["ipv4"].split("/")[0],
185 "ipv6": topo["routers"]["r1"]["links"]["r2-link6"]["ipv6"].split("/")[0],
186 },
187 "nh8": {
188 "ipv4": topo["routers"]["r1"]["links"]["r2-link7"]["ipv4"].split("/")[0],
189 "ipv6": topo["routers"]["r1"]["links"]["r2-link7"]["ipv6"].split("/")[0],
190 },
191 }
192 return NEXT_HOP_IP
193
194
195 #####################################################
196 #
197 # Tests starting
198 #
199 #####################################################
200
201
202 def test_staticroute_with_ecmp_p0_tc3_ebgp(request):
203 """
204 Verify static route ECMP functionality with 8 next hop'
205
206 """
207 tc_name = request.node.name
208 write_test_header(tc_name)
209 tgen = get_topogen()
210
211 # Don't run this test if we have any failure.
212 if tgen.routers_have_failure():
213 pytest.skip(tgen.errors)
214
215 reset_config_on_routers(tgen)
216 NEXT_HOP_IP = populate_nh()
217
218 step("Configure 8 interfaces / links between R1 and R2,")
219 step(
220 "Configure IPv4 static route in R2 with 8 next hop"
221 "N1(21.1.1.2), N2(22.1.1.2), N3(23.1.1.2), N4(24.1.1.2),"
222 "N5(25.1.1.2), N6(26.1.1.2), N7(27.1.1.2),N8(28.1.1.2), Static"
223 "route next-hop present on R1"
224 )
225
226 step("Configure IBGP IPv4 peering between R2 and R3 router.")
227
228 for addr_type in ADDR_TYPES:
229 # Enable static routes
230 for nhp in range(1, 9):
231 input_dict_4 = {
232 "r2": {
233 "static_routes": [
234 {
235 "network": PREFIX1[addr_type],
236 "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type],
237 }
238 ]
239 }
240 }
241 logger.info("Configure static routes")
242 result = create_static_routes(tgen, input_dict_4)
243 assert result is True, "Testcase {} : Failed \n Error: {}".format(
244 tc_name, result
245 )
246 logger.info("Verifying %s routes on r2", addr_type)
247 nh = [
248 NEXT_HOP_IP["nh1"][addr_type],
249 NEXT_HOP_IP["nh2"][addr_type],
250 NEXT_HOP_IP["nh3"][addr_type],
251 NEXT_HOP_IP["nh4"][addr_type],
252 NEXT_HOP_IP["nh5"][addr_type],
253 NEXT_HOP_IP["nh6"][addr_type],
254 NEXT_HOP_IP["nh7"][addr_type],
255 NEXT_HOP_IP["nh8"][addr_type],
256 ]
257
258 dut = "r2"
259 protocol = "static"
260 result = verify_rib(
261 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol
262 )
263 assert (
264 result is True
265 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name)
266 step("Configure redistribute static in BGP on R2 router")
267 for addr_type in ADDR_TYPES:
268 input_dict_2 = {
269 "r2": {
270 "bgp": {
271 "address_family": {
272 addr_type: {
273 "unicast": {"redistribute": [{"redist_type": "static"}]}
274 }
275 }
276 }
277 }
278 }
279 result = create_router_bgp(tgen, topo, input_dict_2)
280 assert result is True, "Testcase {} : Failed \n Error: {}".format(
281 tc_name, result
282 )
283
284 step(
285 "Remove the static route configured with nexthop N1 to N8, one"
286 "by one from running config"
287 )
288 for addr_type in ADDR_TYPES:
289 # delete static routes
290 for nhp in range(1, 9):
291 input_dict_4 = {
292 "r2": {
293 "static_routes": [
294 {
295 "network": PREFIX1[addr_type],
296 "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type],
297 "delete": True,
298 }
299 ]
300 }
301 }
302
303 logger.info("Configure static routes")
304 result = create_static_routes(tgen, input_dict_4)
305 assert result is True, "Testcase {} : Failed \n Error: {}".format(
306 tc_name, result
307 )
308
309 result = verify_rib(
310 tgen,
311 addr_type,
312 dut,
313 input_dict_4,
314 next_hop=nh,
315 protocol=protocol,
316 expected=False,
317 )
318 assert (
319 result is not True
320 ), "Testcase {} : Failed \nError: Routes are" " still present in RIB".format(
321 tc_name
322 )
323
324 step("Configure the static route with nexthop N1 to N8, one by" "one")
325
326 for addr_type in ADDR_TYPES:
327 # add static routes
328 for nhp in range(1, 9):
329 input_dict_4 = {
330 "r2": {
331 "static_routes": [
332 {
333 "network": PREFIX1[addr_type],
334 "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type],
335 }
336 ]
337 }
338 }
339
340 logger.info("Configure static routes")
341 result = create_static_routes(tgen, input_dict_4)
342 assert result is True, "Testcase {} : Failed \n Error: {}".format(
343 tc_name, result
344 )
345
346 result = verify_rib(
347 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol
348 )
349 assert (
350 result is True
351 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name)
352
353 step("Random shut of the nexthop interfaces")
354 randnum = random.randint(0, 7)
355 for addr_type in ADDR_TYPES:
356 intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"]
357 shutdown_bringup_interface(tgen, dut, intf, False)
358 nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
359 input_dict_5 = {
360 "r2": {
361 "static_routes": [
362 {
363 "network": PREFIX1[addr_type],
364 "next_hop": NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type],
365 }
366 ]
367 }
368 }
369 result = verify_rib(
370 tgen,
371 addr_type,
372 dut,
373 input_dict_5,
374 next_hop=nhip,
375 protocol=protocol,
376 expected=False,
377 )
378 assert (
379 result is not True
380 ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format(
381 tc_name
382 )
383
384 step("Random no shut of the nexthop interfaces")
385 for addr_type in ADDR_TYPES:
386 intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"]
387 shutdown_bringup_interface(tgen, dut, intf, True)
388 nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
389 result = verify_rib(
390 tgen, addr_type, dut, input_dict_5, next_hop=nhip, protocol=protocol
391 )
392 assert (
393 result is True
394 ), "Testcase {} : Failed \n" "Error: Routes are missing in RIB".format(tc_name)
395
396 step("Reload the FRR router")
397 # stop/start -> restart FRR router and verify
398 stop_router(tgen, "r2")
399 start_router(tgen, "r2")
400
401 result = verify_rib(
402 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol
403 )
404 assert (
405 result is True
406 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name)
407
408 write_test_footer(tc_name)
409
410
411 def test_staticroute_with_ecmp_with_diff_AD_p0_tc4_ebgp(request):
412 """
413 Verify static route ECMP functionality with 8 next hop
414
415 """
416 tc_name = request.node.name
417 write_test_header(tc_name)
418 tgen = get_topogen()
419
420 # Don't run this test if we have any failure.
421 if tgen.routers_have_failure():
422 pytest.skip(tgen.errors)
423
424 reset_config_on_routers(tgen)
425
426 step("Configure 8 interfaces / links between R1 and R2,")
427 step("Configure IBGP IPv4 peering between R2 and R3 router.")
428 NEXT_HOP_IP = populate_nh()
429 nh_all = {}
430 for addr_type in ADDR_TYPES:
431 nh_all[addr_type] = []
432 for nhp in range(1, 9):
433 nh_all[addr_type].append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
434 step(
435 "Configure IPv4 static route in R2 with 8 next hop"
436 "N1(21.1.1.2) AD 10, N2(22.1.1.2) AD 20, N3(23.1.1.2) AD 30,"
437 "N4(24.1.1.2) AD 40, N5(25.1.1.2) AD 50, N6(26.1.1.2) AD 60,"
438 "N7(27.1.1.2) AD 70, N8(28.1.1.2) AD 80, Static route next-hop"
439 "present on R1"
440 )
441 for addr_type in ADDR_TYPES:
442 for nhp in range(1, 9):
443 input_dict_4 = {
444 "r2": {
445 "static_routes": [
446 {
447 "network": PREFIX1[addr_type],
448 "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type],
449 "admin_distance": 10 * nhp,
450 }
451 ]
452 }
453 }
454 logger.info("Configure static routes")
455 result = create_static_routes(tgen, input_dict_4)
456 assert result is True, "Testcase {} : Failed \n Error: {}".format(
457 tc_name, result
458 )
459 logger.info("Verifying %s routes on r2", addr_type)
460
461 step(
462 "On R2, static route installed in RIB using "
463 "show ip route with 8 next hop, lowest AD nexthop is active"
464 )
465 step("On R2, static route with lowest AD nexthop installed in FIB")
466 input_dict_4 = {
467 "r2": {
468 "static_routes": [
469 {
470 "network": PREFIX1[addr_type],
471 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
472 "admin_distance": 10,
473 }
474 ]
475 }
476 }
477 dut = "r2"
478 protocol = "static"
479 nh = NEXT_HOP_IP["nh1"][addr_type]
480 result = verify_rib(
481 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True
482 )
483 assert result is True, (
484 "Testcase {} : Failed \nError: Route with "
485 " lowest AD is missing in RIB".format(tc_name)
486 )
487
488 nh = []
489 for nhp in range(2, 9):
490 nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
491 result = verify_rib(
492 tgen,
493 addr_type,
494 dut,
495 input_dict_4,
496 next_hop=nh,
497 protocol=protocol,
498 fib=True,
499 expected=False,
500 )
501 assert result is not True, (
502 "Testcase {} : Failed \nError: Routes "
503 " with high AD are active in RIB".format(tc_name)
504 )
505
506 step("Configure redistribute static in BGP on R2 router")
507 for addr_type in ADDR_TYPES:
508 input_dict_2 = {
509 "r2": {
510 "bgp": {
511 "address_family": {
512 addr_type: {
513 "unicast": {"redistribute": [{"redist_type": "static"}]}
514 }
515 }
516 }
517 }
518 }
519
520 logger.info("Configuring redistribute static")
521 result = create_router_bgp(tgen, topo, input_dict_2)
522 assert result is True, "Testcase {} : Failed \n Error: {}".format(
523 tc_name, result
524 )
525
526 step(
527 "After configuring them, route is always active with lowest AD"
528 "value and all the nexthop populated in RIB and FIB again "
529 )
530 input_dict_4 = {
531 "r2": {
532 "static_routes": [
533 {
534 "network": PREFIX1[addr_type],
535 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
536 "admin_distance": 10,
537 }
538 ]
539 }
540 }
541 dut = "r2"
542 protocol = "static"
543 nh = NEXT_HOP_IP["nh1"][addr_type]
544 result = verify_rib(
545 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True
546 )
547 assert result is True, (
548 "Testcase {} : Failed \nError: Route with "
549 " lowest AD is missing in RIB".format(tc_name)
550 )
551
552 step(
553 "Remove the static route configured with nexthop N1 to N8, one"
554 "by one from running config"
555 )
556
557 for addr_type in ADDR_TYPES:
558 # delete static routes
559 for nhp in range(1, 9):
560 input_dict_4 = {
561 "r2": {
562 "static_routes": [
563 {
564 "network": PREFIX1[addr_type],
565 "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type],
566 "admin_distance": 10 * nhp,
567 "delete": True,
568 }
569 ]
570 }
571 }
572
573 logger.info("Configure static routes")
574 result = create_static_routes(tgen, input_dict_4)
575 assert result is True, "Testcase {} : Failed \n Error: {}".format(
576 tc_name, result
577 )
578
579 step(
580 "After removing the static route with N1 to N8 one by one, "
581 "route become active with next preferred nexthop and nexthop which "
582 "got removed is not shown in RIB and FIB"
583 )
584 result = verify_rib(
585 tgen,
586 addr_type,
587 dut,
588 input_dict_4,
589 next_hop=nh_all[addr_type],
590 protocol=protocol,
591 expected=False,
592 )
593 assert (
594 result is not True
595 ), "Testcase {} : Failed \nError: Routes are" " still present in RIB".format(
596 tc_name
597 )
598
599 step("Configure the static route with nexthop N1 to N8, one by" "one")
600 for addr_type in ADDR_TYPES:
601 # add static routes
602 for nhp in range(1, 9):
603 input_dict_4 = {
604 "r2": {
605 "static_routes": [
606 {
607 "network": PREFIX1[addr_type],
608 "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type],
609 "admin_distance": 10 * nhp,
610 }
611 ]
612 }
613 }
614 logger.info("Configure static routes")
615 result = create_static_routes(tgen, input_dict_4)
616 assert result is True, "Testcase {} : Failed \n Error: {}".format(
617 tc_name, result
618 )
619
620 step("On R2, static route with lowest AD nexthop installed in FIB")
621 input_dict_4 = {
622 "r2": {
623 "static_routes": [
624 {
625 "network": PREFIX1[addr_type],
626 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
627 "admin_distance": 10,
628 }
629 ]
630 }
631 }
632 dut = "r2"
633 protocol = "static"
634 nh = NEXT_HOP_IP["nh1"][addr_type]
635 result = verify_rib(
636 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True
637 )
638 assert result is True, (
639 "Testcase {} : Failed \nError: Route with "
640 " lowest AD is missing in RIB".format(tc_name)
641 )
642
643 nh = []
644 for nhp in range(2, 9):
645 nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
646 result = verify_rib(
647 tgen,
648 addr_type,
649 dut,
650 input_dict_4,
651 next_hop=nh,
652 protocol=protocol,
653 fib=True,
654 expected=False,
655 )
656 assert result is not True, (
657 "Testcase {} : Failed \nError: Routes "
658 " with high AD are active in RIB".format(tc_name)
659 )
660
661 step("Random shut of the nexthop interfaces")
662 randnum = random.randint(0, 7)
663 for addr_type in ADDR_TYPES:
664 intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"]
665 shutdown_bringup_interface(tgen, dut, intf, False)
666 nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
667 input_dict_5 = {
668 "r2": {
669 "static_routes": [
670 {
671 "network": PREFIX1[addr_type],
672 "next_hop": NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type],
673 }
674 ]
675 }
676 }
677 result = verify_rib(
678 tgen,
679 addr_type,
680 dut,
681 input_dict_5,
682 next_hop=nhip,
683 protocol=protocol,
684 expected=False,
685 )
686 assert (
687 result is not True
688 ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format(
689 tc_name
690 )
691
692 step("Random no shut of the nexthop interfaces")
693 for addr_type in ADDR_TYPES:
694 intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"]
695 shutdown_bringup_interface(tgen, dut, intf, True)
696 nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type]
697 result = verify_rib(
698 tgen, addr_type, dut, input_dict_5, next_hop=nhip, protocol=protocol
699 )
700 assert (
701 result is True
702 ), "Testcase {} : Failed \n" "Error: Routes are missing in RIB".format(tc_name)
703
704 step("Reload the FRR router")
705 # stop/start -> restart FRR router and verify
706 stop_router(tgen, "r2")
707 start_router(tgen, "r2")
708
709 step(
710 "After reload of FRR router, static route installed "
711 "in RIB and FIB properly ."
712 )
713 for addr_type in ADDR_TYPES:
714 input_dict_4 = {
715 "r2": {
716 "static_routes": [
717 {
718 "network": PREFIX1[addr_type],
719 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
720 "admin_distance": 10,
721 }
722 ]
723 }
724 }
725 dut = "r2"
726 protocol = "static"
727 nh = NEXT_HOP_IP["nh1"][addr_type]
728 result = verify_rib(
729 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True
730 )
731 assert result is True, (
732 "Testcase {} : Failed \nError: Route with "
733 " lowest AD is missing in RIB".format(tc_name)
734 )
735
736 nh = []
737 for nhp in range(2, 9):
738 nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type])
739 result = verify_rib(
740 tgen,
741 addr_type,
742 dut,
743 input_dict_4,
744 next_hop=nh,
745 protocol=protocol,
746 fib=True,
747 expected=False,
748 )
749 assert result is not True, (
750 "Testcase {} : Failed \nError: Routes "
751 " with high AD are active in RIB".format(tc_name)
752 )
753
754 write_test_footer(tc_name)
755
756
757 def test_bgp_local_nexthop_p1_tc14_ebgp(request):
758 """
759 Verify BGP did not install the static route when it receive route
760 with local next hop
761
762 """
763 tc_name = request.node.name
764 write_test_header(tc_name)
765 tgen = get_topogen()
766
767 step("Configure BGP IPv4 session between R2 and R3")
768 step("Configure IPv4 static route on R2")
769 reset_config_on_routers(tgen)
770
771 for addr_type in ADDR_TYPES:
772 # Enable static routes
773 input_dict_4 = {
774 "r2": {
775 "static_routes": [
776 {
777 "network": NETWORK[addr_type],
778 "next_hop": topo["routers"]["r3"]["links"]["r2-link0"][
779 addr_type
780 ].split("/")[0],
781 }
782 ]
783 }
784 }
785
786 logger.info("Configure static routes")
787 result = create_static_routes(tgen, input_dict_4)
788 assert result is True, "Testcase {} : Failed \n Error: {}".format(
789 tc_name, result
790 )
791
792 step("Configure redistribute static in the BGP")
793
794 input_dict_2 = {
795 "r2": {
796 "bgp": {
797 "address_family": {
798 addr_type: {
799 "unicast": {"redistribute": [{"redist_type": "static"}]}
800 }
801 }
802 }
803 }
804 }
805 result = create_router_bgp(tgen, topo, input_dict_2)
806 assert result is True, "Testcase {} : Failed \n Error: {}".format(
807 tc_name, result
808 )
809
810 step("Verify R2 BGP table has IPv4 route")
811 dut = "r2"
812 result = verify_rib(tgen, addr_type, dut, input_dict_4)
813 assert (
814 result is True
815 ), "Testcase {} : Failed \nError: Routes is" " missing in RIB of R2".format(
816 tc_name
817 )
818
819 step(" Verify route did not install in the R3 BGP table, RIB/FIB")
820 dut = "r3"
821 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4, expected=False)
822 assert result is not True, (
823 "Testcase {} : Failed \nError: Routes is"
824 " still present in BGP RIB of R2".format(tc_name)
825 )
826
827 result = verify_rib(tgen, addr_type, dut, input_dict_4, expected=False)
828 assert result is not True, (
829 "Testcase {} : Failed \nError: Routes is"
830 " still present in RIB of R2".format(tc_name)
831 )
832
833 write_test_footer(tc_name)
834
835
836 def test_frr_intf_name_as_gw_gap_tc4_ebgp_p0(request):
837 """
838 Verify static route configure with interface name as gateway'
839 'address'
840 """
841 tc_name = request.node.name
842 write_test_header(tc_name)
843 tgen = get_topogen()
844
845 # Don't run this test if we have any failure.
846 if tgen.routers_have_failure():
847 pytest.skip(tgen.errors)
848
849 reset_config_on_routers(tgen)
850
851 dut = "r1"
852 intf = topo["routers"]["r1"]["links"]["r2-link0"]["interface"]
853 nh = topo["routers"]["r1"]["links"]["r2-link0"]
854 ip_list = {
855 "ipv4": [(dut, intf, ["1.1.1.1/32"], nh["ipv4"].split("/")[0])],
856 "ipv6": [(dut, intf, ["4001::32/128"], nh["ipv6"].split("/")[0])],
857 }
858
859 step(
860 "Configure IPv4 and IPv6 static route in FRR with different next"
861 "hop (ens224 as nexthop))"
862 )
863 step("ip route 2.2.2.0/24 20.1.1.1 ens224 ----from FRR cli")
864 step("ipv6 route 2000::1/120 5000::1 ens224 ----from FRR cli")
865
866 for addr_type in ADDR_TYPES:
867 # Enable static routes
868 nh = topo["routers"]["r2"]["links"]["r1-link0"][addr_type].split("/")[0]
869 input_dict_4 = {
870 "r1": {
871 "static_routes": [
872 {"network": ip_list[addr_type][0][2][0], "next_hop": nh}
873 ]
874 }
875 }
876
877 logger.info("Configure static routes")
878 result = create_static_routes(tgen, input_dict_4)
879 assert result is True, "Testcase {} : Failed \n Error: {}".format(
880 tc_name, result
881 )
882
883 step(
884 "IPv4 and IPv6 Static route added in FRR verify using "
885 "show ip route , nexthop is resolved using show nht"
886 )
887 protocol = "static"
888 result = verify_rib(
889 tgen, addr_type, dut, input_dict_4, protocol=protocol, next_hop=nh
890 )
891 assert (
892 result is True
893 ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(tc_name)
894
895 input_dict_nh = {
896 "r1": {
897 nh: {
898 "Address": nh,
899 "resolvedVia": "connected",
900 "nexthops": {"nexthop1": {"Interfcae": intf}},
901 }
902 }
903 }
904 result = verify_ip_nht(tgen, input_dict_nh)
905 assert (
906 result is True
907 ), "Testcase {} : Failed \nError: Nexthop is" " missing in RIB".format(tc_name)
908
909 step(
910 "Shut / no shut IPv4 and IPv6 static next hop interface from"
911 "kernel and FRR CLI"
912 )
913
914 shutdown_bringup_interface(tgen, dut, intf, False)
915
916 step(
917 "After shut of nexthop interface, IPv4 and IPv6 route got removed "
918 "from RIB verify using show ip route show nht"
919 )
920 result = verify_rib(
921 tgen,
922 addr_type,
923 dut,
924 input_dict_4,
925 protocol=protocol,
926 next_hop=nh,
927 expected=False,
928 )
929 assert (
930 result is not True
931 ), "Testcase {} : Failed \nError: Routes is" " missing in RIB".format(tc_name)
932
933 shutdown_bringup_interface(tgen, dut, intf, True)
934
935 step(
936 "After no shut route got added again in RIB /FIB using "
937 "show ip route nexthop is resolved using show nht"
938 )
939 result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol)
940 assert result is True, "Testcase {} : Failed".format(tc_name)
941
942 for addr_type in ADDR_TYPES:
943 nh = topo["routers"]["r2"]["links"]["r1-link0"][addr_type].split("/")[0]
944 input_dict_4 = {
945 "r1": {
946 "static_routes": [
947 {
948 "network": ip_list[addr_type][0][2][0],
949 "next_hop": nh,
950 "delete": True,
951 }
952 ]
953 }
954 }
955
956 logger.info("Configure static routes")
957 result = create_static_routes(tgen, input_dict_4)
958 assert result is True, "Testcase {} : Failed \n Error: {}".format(
959 tc_name, result
960 )
961
962 step(
963 "Removing FRR configured static route verify FRR route also "
964 "removed from FRR"
965 )
966 result = verify_rib(
967 tgen,
968 addr_type,
969 dut,
970 input_dict_4,
971 protocol=protocol,
972 next_hop=nh,
973 expected=False,
974 )
975 assert (
976 result is not True
977 ), "Testcase {} : Failed \nError: Routes" " still present in RIB".format(
978 tc_name
979 )
980
981 write_test_footer(tc_name)
982
983
984 def test_static_route_with_tag_p0_tc_13_ebgp(request):
985 """
986 Verify static route with tag option
987
988 """
989 tc_name = request.node.name
990 write_test_header(tc_name)
991 tgen = get_topogen()
992
993 # Don't run this test if we have any failure.
994 if tgen.routers_have_failure():
995 pytest.skip(tgen.errors)
996
997 step("Configure 8 links between R1 and R2")
998 step("Configure 1 links between R2 and R3")
999 NEXT_HOP_IP = populate_nh()
1000
1001 step(
1002 "Configure 2 IPv4 static route (S1 and S2) in R2 with same"
1003 "next hop N1 28.1.1.2"
1004 )
1005 step("Configure static route S1 with tag 1 and static route S2 with" "tag2")
1006 step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1")
1007 step("S2= ip route 20.1.1.1/24 28.1.1.2 tag 2")
1008 step("Enable redistribute static in BGP with route-map")
1009 reset_config_on_routers(tgen)
1010
1011 for addr_type in ADDR_TYPES:
1012 # Enable static routes
1013 input_dict_4 = {
1014 "r2": {
1015 "static_routes": [
1016 {
1017 "network": NETWORK[addr_type],
1018 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
1019 "tag": 4001,
1020 },
1021 {
1022 "network": NETWORK2[addr_type],
1023 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
1024 "tag": 4002,
1025 },
1026 ]
1027 }
1028 }
1029
1030 logger.info("Configure static routes")
1031 result = create_static_routes(tgen, input_dict_4)
1032 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1033 tc_name, result
1034 )
1035 step("verify routes are present in RIB")
1036 dut = "r2"
1037 protocol = "static"
1038 nh = NEXT_HOP_IP["nh1"][addr_type]
1039 result = verify_rib(
1040 tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol
1041 )
1042 assert (
1043 result is True
1044 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name)
1045
1046 step("Configure route-map on R2 with allow tag1 and deny tag2")
1047
1048 # Create route map
1049 input_dict_3 = {
1050 "r2": {
1051 "route_maps": {
1052 "rmap_match_tag_1_{}".format(addr_type): [
1053 {
1054 "action": "permit",
1055 "seq_id": 10,
1056 "match": {addr_type: {"tag": "4001"}},
1057 },
1058 {
1059 "action": "deny",
1060 "seq_id": 20,
1061 "match": {addr_type: {"tag": "4002"}},
1062 },
1063 ]
1064 }
1065 }
1066 }
1067 result = create_route_maps(tgen, input_dict_3)
1068 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1069 tc_name, result
1070 )
1071
1072 # Configure neighbor for route map
1073 input_dict_4 = {
1074 "r2": {
1075 "bgp": {
1076 "address_family": {
1077 addr_type: {
1078 "unicast": {
1079 "neighbor": {
1080 "r3": {
1081 "dest_link": {
1082 "r2-link0": {
1083 "route_maps": [
1084 {
1085 "name": "rmap_match_tag_1_ipv4",
1086 "direction": "out",
1087 }
1088 ]
1089 }
1090 }
1091 }
1092 },
1093 "redistribute": [{"redist_type": "static"}],
1094 }
1095 }
1096 }
1097 }
1098 }
1099 }
1100 result = create_router_bgp(tgen, topo, input_dict_4)
1101 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1102 tc_name, result
1103 )
1104
1105 step(
1106 "Verify static route S1 advetised in BGP table when tag1 permit"
1107 "in route-map else it is denied"
1108 )
1109 dut = "r3"
1110 input_dict_0 = {
1111 "r2": {
1112 "static_routes": [
1113 {
1114 "network": NETWORK2[addr_type],
1115 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
1116 "tag": 4002,
1117 }
1118 ]
1119 }
1120 }
1121
1122 result = verify_rib(
1123 tgen, addr_type, dut, input_dict_0, protocol=protocol, expected=False
1124 )
1125 assert result is not True, (
1126 "Testcase {} : Failed \nError: Route with "
1127 "tag 4002 is still present in RIB".format(tc_name)
1128 )
1129
1130 dut = "r2"
1131 input_dict_1 = {
1132 "r2": {"static_routes": [{"network": NETWORK[addr_type], "tag": 4001}]}
1133 }
1134
1135 result = verify_rib(tgen, addr_type, dut, input_dict_0, protocol=protocol)
1136 assert result is True, (
1137 "Testcase {} : Failed \nError: Route with "
1138 "tag 4001 is missing in RIB".format(tc_name)
1139 )
1140
1141 step("Modify the route-map to allow tag2 and deny tag1")
1142 # Create route map
1143 input_dict_3 = {
1144 "r2": {
1145 "route_maps": {
1146 "rmap_match_tag_1_{}".format(addr_type): [
1147 {
1148 "action": "deny",
1149 "seq_id": 10,
1150 "match": {addr_type: {"tag": "4001"}},
1151 },
1152 {
1153 "action": "permit",
1154 "seq_id": 20,
1155 "match": {addr_type: {"tag": "4002"}},
1156 },
1157 ]
1158 }
1159 }
1160 }
1161 result = create_route_maps(tgen, input_dict_3)
1162 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1163 tc_name, result
1164 )
1165
1166 dut = "r3"
1167 step(
1168 "Verify static route S2 advertised in BGP table when tag2"
1169 "permit in route-map else it is denied"
1170 )
1171 protocol = "bgp"
1172 input_dict_0 = {
1173 "r2": {"static_routes": [{"network": NETWORK2[addr_type], "tag": 4002}]}
1174 }
1175
1176 result = verify_rib(tgen, addr_type, dut, input_dict_0, protocol=protocol)
1177 assert result is True, (
1178 "Testcase {} : Failed \nError: Route with "
1179 "tag 4002 is missing in RIB".format(tc_name)
1180 )
1181
1182 input_dict_1 = {
1183 "r2": {"static_routes": [{"network": NETWORK[addr_type], "tag": 4001}]}
1184 }
1185 result = verify_rib(
1186 tgen, addr_type, dut, input_dict_1, protocol=protocol, expected=False
1187 )
1188 assert result is not True, (
1189 "Testcase {} : Failed \nError: Route with "
1190 "tag 4001 is still present in RIB".format(tc_name)
1191 )
1192
1193 step("Configure one static route with 2 ECMP nexthop N1 and N2")
1194 step("For N1 configure tag 1 and for N2 configure tag 2")
1195 step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1")
1196 step("S1= ip route 10.1.1.1/24 29.1.1.2 tag 2")
1197 step("configure the route-map to allow tag1 and deny tag 2")
1198 step("Modify the route-map to allow tag2 and deny tag1")
1199
1200 for addr_type in ADDR_TYPES:
1201 # Enable static routes
1202 input_dict_4 = {
1203 "r2": {
1204 "static_routes": [
1205 {
1206 "network": NETWORK2[addr_type],
1207 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
1208 "tag": 4001,
1209 },
1210 {
1211 "network": NETWORK2[addr_type],
1212 "next_hop": NEXT_HOP_IP["nh2"][addr_type],
1213 "tag": 4002,
1214 },
1215 ]
1216 }
1217 }
1218
1219 logger.info("Configure static routes")
1220 result = create_static_routes(tgen, input_dict_4)
1221 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1222 tc_name, result
1223 )
1224
1225 dut = "r2"
1226 protocol = "static"
1227 result = verify_rib(
1228 tgen, addr_type, dut, input_dict_4, protocol=protocol, fib=True
1229 )
1230 assert (
1231 result is True
1232 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name)
1233
1234 step("shut/no shut of tag1 and tag2 nexthop")
1235
1236 intf = topo["routers"]["r2"]["links"]["r1-link0"]["interface"]
1237 shutdown_bringup_interface(tgen, dut, intf, False)
1238
1239 shutdown_bringup_interface(tgen, dut, intf, True)
1240
1241 step("configure one static route with 3 next-hop")
1242 step("N1-tag1, N2-tag2, N3-tag3")
1243 step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1")
1244 step("S1= ip route 10.1.1.1/24 29.1.1.2 tag 2")
1245 step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 3")
1246
1247 for addr_type in ADDR_TYPES:
1248 # Enable static routes
1249 input_dict_4 = {
1250 "r2": {
1251 "static_routes": [
1252 {
1253 "network": NETWORK2[addr_type],
1254 "next_hop": NEXT_HOP_IP["nh1"][addr_type],
1255 "tag": 4001,
1256 },
1257 {
1258 "network": NETWORK2[addr_type],
1259 "next_hop": NEXT_HOP_IP["nh2"][addr_type],
1260 "tag": 4002,
1261 },
1262 {
1263 "network": NETWORK2[addr_type],
1264 "next_hop": NEXT_HOP_IP["nh3"][addr_type],
1265 "tag": 4003,
1266 },
1267 ]
1268 }
1269 }
1270
1271 logger.info("Configure static routes")
1272 result = create_static_routes(tgen, input_dict_4)
1273 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1274 tc_name, result
1275 )
1276
1277 dut = "r2"
1278 protocol = "static"
1279 result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol)
1280
1281 step("configure the route-map to allow tag2 & tag3 and deny tag1")
1282 # Create route map
1283 input_dict_3 = {
1284 "r2": {
1285 "route_maps": {
1286 "rmap_match_tag_1_{}".format(addr_type): [
1287 {
1288 "action": "deny",
1289 "seq_id": 10,
1290 "match": {addr_type: {"tag": "4001"}},
1291 },
1292 {
1293 "action": "permit",
1294 "seq_id": 20,
1295 "match": {addr_type: {"tag": "4002"}},
1296 },
1297 {
1298 "action": "permit",
1299 "seq_id": 30,
1300 "match": {addr_type: {"tag": "4003"}},
1301 },
1302 ]
1303 }
1304 }
1305 }
1306 result = create_route_maps(tgen, input_dict_3)
1307 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1308 tc_name, result
1309 )
1310
1311 step(
1312 "Verify static route advertised in BGP table with tag3"
1313 " nexthop if tag2 is down"
1314 )
1315 dut = "r3"
1316 protocol = "bgp"
1317 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
1318 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1319 tc_name, result
1320 )
1321
1322 step("shut / no shut of tag2 and tag3 next-hop")
1323
1324 intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"]
1325 shutdown_bringup_interface(tgen, dut, intf, False)
1326
1327 intf = topo["routers"]["r2"]["links"]["r1-link2"]["interface"]
1328 shutdown_bringup_interface(tgen, dut, intf, False)
1329
1330 step("shut/no shut of tag2 and tag3 nexthop")
1331 intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"]
1332 shutdown_bringup_interface(tgen, dut, intf, True)
1333
1334 intf = topo["routers"]["r2"]["links"]["r1-link2"]["interface"]
1335 shutdown_bringup_interface(tgen, dut, intf, True)
1336
1337 step("Verify after shut/noshut of nexthop BGP table updated correctly")
1338 dut = "r3"
1339 protocol = "bgp"
1340 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
1341 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1342 tc_name, result
1343 )
1344
1345 write_test_footer(tc_name)
1346
1347
1348 if __name__ == "__main__":
1349 args = ["-s"] + sys.argv[1:]
1350 sys.exit(pytest.main(args))