]>
Commit | Line | Data |
---|---|---|
26bbe9af | 1 | #!/usr/bin/python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
26bbe9af | 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 | # | |
26bbe9af | 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 | |
26bbe9af | 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 | |
26bbe9af | 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, | |
26bbe9af | 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 | |
4953ca97 | 53 | from lib.topojson import build_config_from_json |
26bbe9af | 54 | |
efb62eed DS |
55 | pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] |
56 | ||
26bbe9af | 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 | ||
26bbe9af | 87 | def setup_module(mod): |
88 | """ | |
89 | ||
90 | Set up the pytest environment. | |
91 | ||
92 | * `mod`: module name | |
93 | """ | |
26bbe9af | 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... | |
e82b531d CH |
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 | |
26bbe9af | 105 | # ... and here it calls Mininet initialization functions. |
106 | ||
107 | # Starting topology, create tmp files which are loaded to routers | |
d60a3f0e | 108 | # to start daemons and then start routers |
26bbe9af | 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 | ) | |
d7265db9 MS |
263 | assert ( |
264 | result is True | |
1155a662 | 265 | ), "Testcase {} : Failed \nError: Routes are missing in RIB".format(tc_name) |
26bbe9af | 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 | ) | |
d7265db9 MS |
318 | assert ( |
319 | result is not True | |
1155a662 | 320 | ), "Testcase {} : Failed \nError: Routes are still present in RIB".format( |
d7265db9 MS |
321 | tc_name |
322 | ) | |
26bbe9af | 323 | |
1155a662 | 324 | step("Configure the static route with nexthop N1 to N8, one by one") |
26bbe9af | 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 | ) | |
d7265db9 MS |
349 | assert ( |
350 | result is True | |
1155a662 | 351 | ), "Testcase {} : Failed \nError: Routes are missing in RIB".format(tc_name) |
26bbe9af | 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 | ) | |
d7265db9 MS |
378 | assert ( |
379 | result is not True | |
1155a662 | 380 | ), "Testcase {} : Failed \n Error: Routes are still present in RIB".format( |
d7265db9 MS |
381 | tc_name |
382 | ) | |
26bbe9af | 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 | ) | |
d7265db9 MS |
392 | assert ( |
393 | result is True | |
1155a662 | 394 | ), "Testcase {} : Failed \n Error: Routes are missing in RIB".format(tc_name) |
26bbe9af | 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 | ) | |
d7265db9 MS |
404 | assert ( |
405 | result is True | |
1155a662 | 406 | ), "Testcase {} : Failed \nError: Routes are missing in RIB".format(tc_name) |
26bbe9af | 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) | |
26bbe9af | 425 | |
426 | step("Configure 8 interfaces / links between R1 and R2,") | |
427 | step("Configure IBGP IPv4 peering between R2 and R3 router.") | |
26bbe9af | 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 | ) | |
d7265db9 MS |
483 | assert result is True, ( |
484 | "Testcase {} : Failed \nError: Route with " | |
485 | " lowest AD is missing in RIB".format(tc_name) | |
486 | ) | |
26bbe9af | 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 | ) | |
d7265db9 MS |
501 | assert result is not True, ( |
502 | "Testcase {} : Failed \nError: Routes " | |
503 | " with high AD are active in RIB".format(tc_name) | |
504 | ) | |
26bbe9af | 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 | ) | |
d7265db9 MS |
547 | assert result is True, ( |
548 | "Testcase {} : Failed \nError: Route with " | |
549 | " lowest AD is missing in RIB".format(tc_name) | |
550 | ) | |
26bbe9af | 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 | ) | |
d7265db9 MS |
593 | assert ( |
594 | result is not True | |
1155a662 | 595 | ), "Testcase {} : Failed \nError: Routes are still present in RIB".format(tc_name) |
26bbe9af | 596 | |
1155a662 | 597 | step("Configure the static route with nexthop N1 to N8, one by one") |
26bbe9af | 598 | for addr_type in ADDR_TYPES: |
599 | # add static routes | |
600 | for nhp in range(1, 9): | |
601 | input_dict_4 = { | |
602 | "r2": { | |
603 | "static_routes": [ | |
604 | { | |
605 | "network": PREFIX1[addr_type], | |
606 | "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type], | |
607 | "admin_distance": 10 * nhp, | |
608 | } | |
609 | ] | |
610 | } | |
611 | } | |
612 | logger.info("Configure static routes") | |
613 | result = create_static_routes(tgen, input_dict_4) | |
614 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
615 | tc_name, result | |
616 | ) | |
617 | ||
618 | step("On R2, static route with lowest AD nexthop installed in FIB") | |
619 | input_dict_4 = { | |
620 | "r2": { | |
621 | "static_routes": [ | |
622 | { | |
623 | "network": PREFIX1[addr_type], | |
624 | "next_hop": NEXT_HOP_IP["nh1"][addr_type], | |
625 | "admin_distance": 10, | |
626 | } | |
627 | ] | |
628 | } | |
629 | } | |
630 | dut = "r2" | |
631 | protocol = "static" | |
632 | nh = NEXT_HOP_IP["nh1"][addr_type] | |
633 | result = verify_rib( | |
634 | tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True | |
635 | ) | |
d7265db9 MS |
636 | assert result is True, ( |
637 | "Testcase {} : Failed \nError: Route with " | |
638 | " lowest AD is missing in RIB".format(tc_name) | |
639 | ) | |
26bbe9af | 640 | |
641 | nh = [] | |
642 | for nhp in range(2, 9): | |
643 | nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type]) | |
644 | result = verify_rib( | |
645 | tgen, | |
646 | addr_type, | |
647 | dut, | |
648 | input_dict_4, | |
649 | next_hop=nh, | |
650 | protocol=protocol, | |
651 | fib=True, | |
652 | expected=False, | |
653 | ) | |
d7265db9 MS |
654 | assert result is not True, ( |
655 | "Testcase {} : Failed \nError: Routes " | |
656 | " with high AD are active in RIB".format(tc_name) | |
657 | ) | |
26bbe9af | 658 | |
659 | step("Random shut of the nexthop interfaces") | |
660 | randnum = random.randint(0, 7) | |
661 | for addr_type in ADDR_TYPES: | |
662 | intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"] | |
663 | shutdown_bringup_interface(tgen, dut, intf, False) | |
664 | nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type] | |
665 | input_dict_5 = { | |
666 | "r2": { | |
667 | "static_routes": [ | |
668 | { | |
669 | "network": PREFIX1[addr_type], | |
670 | "next_hop": NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type], | |
671 | } | |
672 | ] | |
673 | } | |
674 | } | |
675 | result = verify_rib( | |
676 | tgen, | |
677 | addr_type, | |
678 | dut, | |
679 | input_dict_5, | |
680 | next_hop=nhip, | |
681 | protocol=protocol, | |
682 | expected=False, | |
683 | ) | |
d7265db9 MS |
684 | assert ( |
685 | result is not True | |
1155a662 | 686 | ), "Testcase {} : Failed \n Error: Routes are still present in RIB".format( |
d7265db9 MS |
687 | tc_name |
688 | ) | |
26bbe9af | 689 | |
690 | step("Random no shut of the nexthop interfaces") | |
691 | for addr_type in ADDR_TYPES: | |
692 | intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"] | |
693 | shutdown_bringup_interface(tgen, dut, intf, True) | |
694 | nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type] | |
695 | result = verify_rib( | |
696 | tgen, addr_type, dut, input_dict_5, next_hop=nhip, protocol=protocol | |
697 | ) | |
d7265db9 MS |
698 | assert ( |
699 | result is True | |
1155a662 | 700 | ), "Testcase {} : Failed \n Error: Routes are missing in RIB".format(tc_name) |
26bbe9af | 701 | |
702 | step("Reload the FRR router") | |
703 | # stop/start -> restart FRR router and verify | |
704 | stop_router(tgen, "r2") | |
705 | start_router(tgen, "r2") | |
706 | ||
707 | step( | |
708 | "After reload of FRR router, static route installed " | |
709 | "in RIB and FIB properly ." | |
710 | ) | |
711 | for addr_type in ADDR_TYPES: | |
712 | input_dict_4 = { | |
713 | "r2": { | |
714 | "static_routes": [ | |
715 | { | |
716 | "network": PREFIX1[addr_type], | |
717 | "next_hop": NEXT_HOP_IP["nh1"][addr_type], | |
718 | "admin_distance": 10, | |
719 | } | |
720 | ] | |
721 | } | |
722 | } | |
723 | dut = "r2" | |
724 | protocol = "static" | |
725 | nh = NEXT_HOP_IP["nh1"][addr_type] | |
726 | result = verify_rib( | |
727 | tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True | |
728 | ) | |
d7265db9 MS |
729 | assert result is True, ( |
730 | "Testcase {} : Failed \nError: Route with " | |
731 | " lowest AD is missing in RIB".format(tc_name) | |
732 | ) | |
26bbe9af | 733 | |
734 | nh = [] | |
735 | for nhp in range(2, 9): | |
736 | nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type]) | |
737 | result = verify_rib( | |
738 | tgen, | |
739 | addr_type, | |
740 | dut, | |
741 | input_dict_4, | |
742 | next_hop=nh, | |
743 | protocol=protocol, | |
744 | fib=True, | |
745 | expected=False, | |
746 | ) | |
d7265db9 MS |
747 | assert result is not True, ( |
748 | "Testcase {} : Failed \nError: Routes " | |
749 | " with high AD are active in RIB".format(tc_name) | |
750 | ) | |
26bbe9af | 751 | |
752 | write_test_footer(tc_name) | |
753 | ||
754 | ||
755 | def test_bgp_local_nexthop_p1_tc14_ebgp(request): | |
756 | """ | |
757 | Verify BGP did not install the static route when it receive route | |
758 | with local next hop | |
759 | ||
760 | """ | |
761 | tc_name = request.node.name | |
762 | write_test_header(tc_name) | |
763 | tgen = get_topogen() | |
764 | ||
765 | step("Configure BGP IPv4 session between R2 and R3") | |
766 | step("Configure IPv4 static route on R2") | |
767 | reset_config_on_routers(tgen) | |
768 | ||
769 | for addr_type in ADDR_TYPES: | |
770 | # Enable static routes | |
771 | input_dict_4 = { | |
772 | "r2": { | |
773 | "static_routes": [ | |
774 | { | |
775 | "network": NETWORK[addr_type], | |
776 | "next_hop": topo["routers"]["r3"]["links"]["r2-link0"][ | |
777 | addr_type | |
778 | ].split("/")[0], | |
779 | } | |
780 | ] | |
781 | } | |
782 | } | |
783 | ||
784 | logger.info("Configure static routes") | |
785 | result = create_static_routes(tgen, input_dict_4) | |
786 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
787 | tc_name, result | |
788 | ) | |
789 | ||
790 | step("Configure redistribute static in the BGP") | |
791 | ||
792 | input_dict_2 = { | |
793 | "r2": { | |
794 | "bgp": { | |
795 | "address_family": { | |
796 | addr_type: { | |
797 | "unicast": {"redistribute": [{"redist_type": "static"}]} | |
798 | } | |
799 | } | |
800 | } | |
801 | } | |
802 | } | |
803 | result = create_router_bgp(tgen, topo, input_dict_2) | |
804 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
805 | tc_name, result | |
806 | ) | |
807 | ||
808 | step("Verify R2 BGP table has IPv4 route") | |
809 | dut = "r2" | |
810 | result = verify_rib(tgen, addr_type, dut, input_dict_4) | |
d7265db9 MS |
811 | assert ( |
812 | result is True | |
1155a662 | 813 | ), "Testcase {} : Failed \nError: routes are missing in RIB of R2".format( |
d7265db9 MS |
814 | tc_name |
815 | ) | |
26bbe9af | 816 | |
817 | step(" Verify route did not install in the R3 BGP table, RIB/FIB") | |
818 | dut = "r3" | |
819 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4, expected=False) | |
d7265db9 | 820 | assert result is not True, ( |
1155a662 | 821 | "Testcase {} : Failed \nError: routes are" |
d7265db9 MS |
822 | " still present in BGP RIB of R2".format(tc_name) |
823 | ) | |
26bbe9af | 824 | |
825 | result = verify_rib(tgen, addr_type, dut, input_dict_4, expected=False) | |
d7265db9 | 826 | assert result is not True, ( |
1155a662 | 827 | "Testcase {} : Failed \nError: routes are" |
d7265db9 MS |
828 | " still present in RIB of R2".format(tc_name) |
829 | ) | |
26bbe9af | 830 | |
831 | write_test_footer(tc_name) | |
832 | ||
833 | ||
834 | def test_frr_intf_name_as_gw_gap_tc4_ebgp_p0(request): | |
835 | """ | |
836 | Verify static route configure with interface name as gateway' | |
837 | 'address' | |
838 | """ | |
839 | tc_name = request.node.name | |
840 | write_test_header(tc_name) | |
841 | tgen = get_topogen() | |
842 | ||
843 | # Don't run this test if we have any failure. | |
844 | if tgen.routers_have_failure(): | |
845 | pytest.skip(tgen.errors) | |
846 | ||
847 | reset_config_on_routers(tgen) | |
848 | ||
849 | dut = "r1" | |
850 | intf = topo["routers"]["r1"]["links"]["r2-link0"]["interface"] | |
851 | nh = topo["routers"]["r1"]["links"]["r2-link0"] | |
852 | ip_list = { | |
853 | "ipv4": [(dut, intf, ["1.1.1.1/32"], nh["ipv4"].split("/")[0])], | |
854 | "ipv6": [(dut, intf, ["4001::32/128"], nh["ipv6"].split("/")[0])], | |
855 | } | |
856 | ||
857 | step( | |
858 | "Configure IPv4 and IPv6 static route in FRR with different next" | |
859 | "hop (ens224 as nexthop))" | |
860 | ) | |
861 | step("ip route 2.2.2.0/24 20.1.1.1 ens224 ----from FRR cli") | |
862 | step("ipv6 route 2000::1/120 5000::1 ens224 ----from FRR cli") | |
863 | ||
864 | for addr_type in ADDR_TYPES: | |
865 | # Enable static routes | |
866 | nh = topo["routers"]["r2"]["links"]["r1-link0"][addr_type].split("/")[0] | |
867 | input_dict_4 = { | |
868 | "r1": { | |
869 | "static_routes": [ | |
870 | {"network": ip_list[addr_type][0][2][0], "next_hop": nh} | |
871 | ] | |
872 | } | |
873 | } | |
874 | ||
875 | logger.info("Configure static routes") | |
876 | result = create_static_routes(tgen, input_dict_4) | |
877 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
878 | tc_name, result | |
879 | ) | |
880 | ||
881 | step( | |
882 | "IPv4 and IPv6 Static route added in FRR verify using " | |
883 | "show ip route , nexthop is resolved using show nht" | |
884 | ) | |
885 | protocol = "static" | |
886 | result = verify_rib( | |
887 | tgen, addr_type, dut, input_dict_4, protocol=protocol, next_hop=nh | |
888 | ) | |
d7265db9 MS |
889 | assert ( |
890 | result is True | |
1155a662 | 891 | ), "Testcase {} : Failed \nError: routes are missing in RIB".format(tc_name) |
26bbe9af | 892 | |
893 | input_dict_nh = { | |
894 | "r1": { | |
895 | nh: { | |
896 | "Address": nh, | |
897 | "resolvedVia": "connected", | |
898 | "nexthops": {"nexthop1": {"Interfcae": intf}}, | |
899 | } | |
900 | } | |
901 | } | |
902 | result = verify_ip_nht(tgen, input_dict_nh) | |
d7265db9 MS |
903 | assert ( |
904 | result is True | |
1155a662 | 905 | ), "Testcase {} : Failed \nError: Nexthop is missing in RIB".format(tc_name) |
26bbe9af | 906 | |
907 | step( | |
908 | "Shut / no shut IPv4 and IPv6 static next hop interface from" | |
909 | "kernel and FRR CLI" | |
910 | ) | |
911 | ||
912 | shutdown_bringup_interface(tgen, dut, intf, False) | |
913 | ||
914 | step( | |
915 | "After shut of nexthop interface, IPv4 and IPv6 route got removed " | |
916 | "from RIB verify using show ip route show nht" | |
917 | ) | |
918 | result = verify_rib( | |
919 | tgen, | |
920 | addr_type, | |
921 | dut, | |
922 | input_dict_4, | |
923 | protocol=protocol, | |
924 | next_hop=nh, | |
925 | expected=False, | |
926 | ) | |
d7265db9 MS |
927 | assert ( |
928 | result is not True | |
1155a662 | 929 | ), "Testcase {} : Failed \nError: routes are missing in RIB".format(tc_name) |
26bbe9af | 930 | |
931 | shutdown_bringup_interface(tgen, dut, intf, True) | |
932 | ||
933 | step( | |
934 | "After no shut route got added again in RIB /FIB using " | |
935 | "show ip route nexthop is resolved using show nht" | |
936 | ) | |
937 | result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) | |
938 | assert result is True, "Testcase {} : Failed".format(tc_name) | |
939 | ||
940 | for addr_type in ADDR_TYPES: | |
941 | nh = topo["routers"]["r2"]["links"]["r1-link0"][addr_type].split("/")[0] | |
942 | input_dict_4 = { | |
943 | "r1": { | |
944 | "static_routes": [ | |
945 | { | |
946 | "network": ip_list[addr_type][0][2][0], | |
947 | "next_hop": nh, | |
948 | "delete": True, | |
949 | } | |
950 | ] | |
951 | } | |
952 | } | |
953 | ||
954 | logger.info("Configure static routes") | |
955 | result = create_static_routes(tgen, input_dict_4) | |
956 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
957 | tc_name, result | |
958 | ) | |
959 | ||
960 | step( | |
961 | "Removing FRR configured static route verify FRR route also " | |
962 | "removed from FRR" | |
963 | ) | |
964 | result = verify_rib( | |
965 | tgen, | |
966 | addr_type, | |
967 | dut, | |
968 | input_dict_4, | |
969 | protocol=protocol, | |
970 | next_hop=nh, | |
971 | expected=False, | |
972 | ) | |
d7265db9 MS |
973 | assert ( |
974 | result is not True | |
1155a662 | 975 | ), "Testcase {} : Failed \nError: Routes still present in RIB".format(tc_name) |
26bbe9af | 976 | |
977 | write_test_footer(tc_name) | |
978 | ||
979 | ||
980 | def test_static_route_with_tag_p0_tc_13_ebgp(request): | |
981 | """ | |
982 | Verify static route with tag option | |
983 | ||
984 | """ | |
985 | tc_name = request.node.name | |
986 | write_test_header(tc_name) | |
987 | tgen = get_topogen() | |
988 | ||
989 | # Don't run this test if we have any failure. | |
990 | if tgen.routers_have_failure(): | |
991 | pytest.skip(tgen.errors) | |
992 | ||
993 | step("Configure 8 links between R1 and R2") | |
994 | step("Configure 1 links between R2 and R3") | |
995 | NEXT_HOP_IP = populate_nh() | |
996 | ||
997 | step( | |
998 | "Configure 2 IPv4 static route (S1 and S2) in R2 with same" | |
999 | "next hop N1 28.1.1.2" | |
1000 | ) | |
1155a662 | 1001 | step("Configure static route S1 with tag 1 and static route S2 with tag2") |
26bbe9af | 1002 | step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1") |
1003 | step("S2= ip route 20.1.1.1/24 28.1.1.2 tag 2") | |
1004 | step("Enable redistribute static in BGP with route-map") | |
1005 | reset_config_on_routers(tgen) | |
1006 | ||
1007 | for addr_type in ADDR_TYPES: | |
1008 | # Enable static routes | |
1009 | input_dict_4 = { | |
1010 | "r2": { | |
1011 | "static_routes": [ | |
1012 | { | |
1013 | "network": NETWORK[addr_type], | |
1014 | "next_hop": NEXT_HOP_IP["nh1"][addr_type], | |
1015 | "tag": 4001, | |
1016 | }, | |
1017 | { | |
1018 | "network": NETWORK2[addr_type], | |
1019 | "next_hop": NEXT_HOP_IP["nh1"][addr_type], | |
1020 | "tag": 4002, | |
1021 | }, | |
1022 | ] | |
1023 | } | |
1024 | } | |
1025 | ||
1026 | logger.info("Configure static routes") | |
1027 | result = create_static_routes(tgen, input_dict_4) | |
1028 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1029 | tc_name, result | |
1030 | ) | |
1031 | step("verify routes are present in RIB") | |
1032 | dut = "r2" | |
1033 | protocol = "static" | |
1034 | nh = NEXT_HOP_IP["nh1"][addr_type] | |
1035 | result = verify_rib( | |
1036 | tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol | |
1037 | ) | |
d7265db9 MS |
1038 | assert ( |
1039 | result is True | |
1155a662 | 1040 | ), "Testcase {} : Failed \nError: Routes are missing in RIB".format(tc_name) |
26bbe9af | 1041 | |
1042 | step("Configure route-map on R2 with allow tag1 and deny tag2") | |
1043 | ||
1044 | # Create route map | |
1045 | input_dict_3 = { | |
1046 | "r2": { | |
1047 | "route_maps": { | |
1048 | "rmap_match_tag_1_{}".format(addr_type): [ | |
1049 | { | |
1050 | "action": "permit", | |
1051 | "seq_id": 10, | |
1052 | "match": {addr_type: {"tag": "4001"}}, | |
1053 | }, | |
1054 | { | |
1055 | "action": "deny", | |
1056 | "seq_id": 20, | |
1057 | "match": {addr_type: {"tag": "4002"}}, | |
1058 | }, | |
1059 | ] | |
1060 | } | |
1061 | } | |
1062 | } | |
1063 | result = create_route_maps(tgen, input_dict_3) | |
1064 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1065 | tc_name, result | |
1066 | ) | |
1067 | ||
1068 | # Configure neighbor for route map | |
1069 | input_dict_4 = { | |
1070 | "r2": { | |
1071 | "bgp": { | |
1072 | "address_family": { | |
1073 | addr_type: { | |
1074 | "unicast": { | |
1075 | "neighbor": { | |
1076 | "r3": { | |
1077 | "dest_link": { | |
1078 | "r2-link0": { | |
1079 | "route_maps": [ | |
1080 | { | |
1081 | "name": "rmap_match_tag_1_ipv4", | |
1082 | "direction": "out", | |
1083 | } | |
1084 | ] | |
1085 | } | |
1086 | } | |
1087 | } | |
1088 | }, | |
1089 | "redistribute": [{"redist_type": "static"}], | |
1090 | } | |
1091 | } | |
1092 | } | |
1093 | } | |
1094 | } | |
1095 | } | |
1096 | result = create_router_bgp(tgen, topo, input_dict_4) | |
1097 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1098 | tc_name, result | |
1099 | ) | |
1100 | ||
1101 | step( | |
1102 | "Verify static route S1 advetised in BGP table when tag1 permit" | |
1103 | "in route-map else it is denied" | |
1104 | ) | |
1105 | dut = "r3" | |
1106 | input_dict_0 = { | |
1107 | "r2": { | |
1108 | "static_routes": [ | |
1109 | { | |
1110 | "network": NETWORK2[addr_type], | |
1111 | "next_hop": NEXT_HOP_IP["nh1"][addr_type], | |
1112 | "tag": 4002, | |
1113 | } | |
1114 | ] | |
1115 | } | |
1116 | } | |
1117 | ||
1118 | result = verify_rib( | |
1119 | tgen, addr_type, dut, input_dict_0, protocol=protocol, expected=False | |
1120 | ) | |
d7265db9 MS |
1121 | assert result is not True, ( |
1122 | "Testcase {} : Failed \nError: Route with " | |
1123 | "tag 4002 is still present in RIB".format(tc_name) | |
1124 | ) | |
26bbe9af | 1125 | |
1126 | dut = "r2" | |
1127 | input_dict_1 = { | |
1128 | "r2": {"static_routes": [{"network": NETWORK[addr_type], "tag": 4001}]} | |
1129 | } | |
1130 | ||
1131 | result = verify_rib(tgen, addr_type, dut, input_dict_0, protocol=protocol) | |
d7265db9 MS |
1132 | assert result is True, ( |
1133 | "Testcase {} : Failed \nError: Route with " | |
1134 | "tag 4001 is missing in RIB".format(tc_name) | |
1135 | ) | |
26bbe9af | 1136 | |
1137 | step("Modify the route-map to allow tag2 and deny tag1") | |
1138 | # Create route map | |
1139 | input_dict_3 = { | |
1140 | "r2": { | |
1141 | "route_maps": { | |
1142 | "rmap_match_tag_1_{}".format(addr_type): [ | |
1143 | { | |
1144 | "action": "deny", | |
1145 | "seq_id": 10, | |
1146 | "match": {addr_type: {"tag": "4001"}}, | |
1147 | }, | |
1148 | { | |
1149 | "action": "permit", | |
1150 | "seq_id": 20, | |
1151 | "match": {addr_type: {"tag": "4002"}}, | |
1152 | }, | |
1153 | ] | |
1154 | } | |
1155 | } | |
1156 | } | |
1157 | result = create_route_maps(tgen, input_dict_3) | |
1158 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1159 | tc_name, result | |
1160 | ) | |
1161 | ||
1162 | dut = "r3" | |
1163 | step( | |
1164 | "Verify static route S2 advertised in BGP table when tag2" | |
1165 | "permit in route-map else it is denied" | |
1166 | ) | |
1167 | protocol = "bgp" | |
1168 | input_dict_0 = { | |
1169 | "r2": {"static_routes": [{"network": NETWORK2[addr_type], "tag": 4002}]} | |
1170 | } | |
1171 | ||
1172 | result = verify_rib(tgen, addr_type, dut, input_dict_0, protocol=protocol) | |
d7265db9 MS |
1173 | assert result is True, ( |
1174 | "Testcase {} : Failed \nError: Route with " | |
1175 | "tag 4002 is missing in RIB".format(tc_name) | |
1176 | ) | |
26bbe9af | 1177 | |
1178 | input_dict_1 = { | |
1179 | "r2": {"static_routes": [{"network": NETWORK[addr_type], "tag": 4001}]} | |
1180 | } | |
1181 | result = verify_rib( | |
1182 | tgen, addr_type, dut, input_dict_1, protocol=protocol, expected=False | |
1183 | ) | |
d7265db9 MS |
1184 | assert result is not True, ( |
1185 | "Testcase {} : Failed \nError: Route with " | |
1186 | "tag 4001 is still present in RIB".format(tc_name) | |
1187 | ) | |
26bbe9af | 1188 | |
1189 | step("Configure one static route with 2 ECMP nexthop N1 and N2") | |
1190 | step("For N1 configure tag 1 and for N2 configure tag 2") | |
1191 | step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1") | |
1192 | step("S1= ip route 10.1.1.1/24 29.1.1.2 tag 2") | |
1193 | step("configure the route-map to allow tag1 and deny tag 2") | |
1194 | step("Modify the route-map to allow tag2 and deny tag1") | |
1195 | ||
1196 | for addr_type in ADDR_TYPES: | |
1197 | # Enable static routes | |
1198 | input_dict_4 = { | |
1199 | "r2": { | |
1200 | "static_routes": [ | |
1201 | { | |
1202 | "network": NETWORK2[addr_type], | |
1203 | "next_hop": NEXT_HOP_IP["nh1"][addr_type], | |
1204 | "tag": 4001, | |
1205 | }, | |
1206 | { | |
1207 | "network": NETWORK2[addr_type], | |
1208 | "next_hop": NEXT_HOP_IP["nh2"][addr_type], | |
1209 | "tag": 4002, | |
1210 | }, | |
1211 | ] | |
1212 | } | |
1213 | } | |
1214 | ||
1215 | logger.info("Configure static routes") | |
1216 | result = create_static_routes(tgen, input_dict_4) | |
1217 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1218 | tc_name, result | |
1219 | ) | |
1220 | ||
1221 | dut = "r2" | |
1222 | protocol = "static" | |
1223 | result = verify_rib( | |
1224 | tgen, addr_type, dut, input_dict_4, protocol=protocol, fib=True | |
1225 | ) | |
d7265db9 MS |
1226 | assert ( |
1227 | result is True | |
1155a662 | 1228 | ), "Testcase {} : Failed \nError: Routes are missing in RIB".format(tc_name) |
26bbe9af | 1229 | |
1230 | step("shut/no shut of tag1 and tag2 nexthop") | |
1231 | ||
1232 | intf = topo["routers"]["r2"]["links"]["r1-link0"]["interface"] | |
1233 | shutdown_bringup_interface(tgen, dut, intf, False) | |
1234 | ||
1235 | shutdown_bringup_interface(tgen, dut, intf, True) | |
1236 | ||
1237 | step("configure one static route with 3 next-hop") | |
1238 | step("N1-tag1, N2-tag2, N3-tag3") | |
1239 | step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1") | |
1240 | step("S1= ip route 10.1.1.1/24 29.1.1.2 tag 2") | |
1241 | step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 3") | |
1242 | ||
1243 | for addr_type in ADDR_TYPES: | |
1244 | # Enable static routes | |
1245 | input_dict_4 = { | |
1246 | "r2": { | |
1247 | "static_routes": [ | |
1248 | { | |
1249 | "network": NETWORK2[addr_type], | |
1250 | "next_hop": NEXT_HOP_IP["nh1"][addr_type], | |
1251 | "tag": 4001, | |
1252 | }, | |
1253 | { | |
1254 | "network": NETWORK2[addr_type], | |
1255 | "next_hop": NEXT_HOP_IP["nh2"][addr_type], | |
1256 | "tag": 4002, | |
1257 | }, | |
1258 | { | |
1259 | "network": NETWORK2[addr_type], | |
1260 | "next_hop": NEXT_HOP_IP["nh3"][addr_type], | |
1261 | "tag": 4003, | |
1262 | }, | |
1263 | ] | |
1264 | } | |
1265 | } | |
1266 | ||
1267 | logger.info("Configure static routes") | |
1268 | result = create_static_routes(tgen, input_dict_4) | |
1269 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1270 | tc_name, result | |
1271 | ) | |
1272 | ||
1273 | dut = "r2" | |
1274 | protocol = "static" | |
1275 | result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) | |
1276 | ||
1277 | step("configure the route-map to allow tag2 & tag3 and deny tag1") | |
1278 | # Create route map | |
1279 | input_dict_3 = { | |
1280 | "r2": { | |
1281 | "route_maps": { | |
1282 | "rmap_match_tag_1_{}".format(addr_type): [ | |
1283 | { | |
1284 | "action": "deny", | |
1285 | "seq_id": 10, | |
1286 | "match": {addr_type: {"tag": "4001"}}, | |
1287 | }, | |
1288 | { | |
1289 | "action": "permit", | |
1290 | "seq_id": 20, | |
1291 | "match": {addr_type: {"tag": "4002"}}, | |
1292 | }, | |
1293 | { | |
1294 | "action": "permit", | |
1295 | "seq_id": 30, | |
1296 | "match": {addr_type: {"tag": "4003"}}, | |
1297 | }, | |
1298 | ] | |
1299 | } | |
1300 | } | |
1301 | } | |
1302 | result = create_route_maps(tgen, input_dict_3) | |
1303 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1304 | tc_name, result | |
1305 | ) | |
1306 | ||
1307 | step( | |
1308 | "Verify static route advertised in BGP table with tag3" | |
1309 | " nexthop if tag2 is down" | |
1310 | ) | |
1311 | dut = "r3" | |
1312 | protocol = "bgp" | |
1313 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4) | |
1314 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1315 | tc_name, result | |
1316 | ) | |
1317 | ||
1318 | step("shut / no shut of tag2 and tag3 next-hop") | |
1319 | ||
1320 | intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"] | |
1321 | shutdown_bringup_interface(tgen, dut, intf, False) | |
1322 | ||
1323 | intf = topo["routers"]["r2"]["links"]["r1-link2"]["interface"] | |
1324 | shutdown_bringup_interface(tgen, dut, intf, False) | |
1325 | ||
1326 | step("shut/no shut of tag2 and tag3 nexthop") | |
1327 | intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"] | |
1328 | shutdown_bringup_interface(tgen, dut, intf, True) | |
1329 | ||
1330 | intf = topo["routers"]["r2"]["links"]["r1-link2"]["interface"] | |
1331 | shutdown_bringup_interface(tgen, dut, intf, True) | |
1332 | ||
1333 | step("Verify after shut/noshut of nexthop BGP table updated correctly") | |
1334 | dut = "r3" | |
1335 | protocol = "bgp" | |
1336 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4) | |
1337 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
1338 | tc_name, result | |
1339 | ) | |
1340 | ||
1341 | write_test_footer(tc_name) | |
1342 | ||
1343 | ||
1344 | if __name__ == "__main__": | |
1345 | args = ["-s"] + sys.argv[1:] | |
1346 | sys.exit(pytest.main(args)) |