]>
Commit | Line | Data |
---|---|---|
985195f2 | 1 | #!/usr/bin/env python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
985195f2 KK |
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 | # | |
985195f2 KK |
9 | |
10 | """ | |
11 | Following tests are covered to test BGP Multi-VRF Dynamic Route Leaking: | |
12 | ||
13 | 1. Verify that Changing route-map configurations(match/set clauses) on | |
14 | the fly it takes immediate effect. | |
15 | 2. Verify BGP best path selection algorithm works fine when | |
16 | routes are imported from ISR to default vrf and vice versa. | |
17 | """ | |
18 | ||
19 | import os | |
20 | import sys | |
21 | import json | |
22 | import time | |
23 | import pytest | |
24 | import platform | |
25 | ||
26 | # Save the Current Working Directory to find configuration files. | |
27 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
701a0192 | 28 | sys.path.append(os.path.join(CWD, "../")) |
29 | sys.path.append(os.path.join(CWD, "../lib/")) | |
985195f2 KK |
30 | |
31 | # Required to instantiate the topology builder class. | |
32 | ||
33 | # pylint: disable=C0413 | |
34 | # Import topogen and topotest helpers | |
35 | from lib.topogen import Topogen, get_topogen | |
36 | from lib.topotest import version_cmp | |
985195f2 KK |
37 | |
38 | from lib.common_config import ( | |
701a0192 | 39 | start_topology, |
40 | write_test_header, | |
41 | check_address_types, | |
985195f2 | 42 | write_test_footer, |
701a0192 | 43 | step, |
44 | create_route_maps, | |
985195f2 KK |
45 | create_prefix_lists, |
46 | create_bgp_community_lists, | |
47 | check_router_status, | |
48 | get_frr_ipv6_linklocal, | |
701a0192 | 49 | shutdown_bringup_interface, |
985195f2 KK |
50 | ) |
51 | ||
52 | from lib.topolog import logger | |
53 | from lib.bgp import ( | |
701a0192 | 54 | verify_bgp_convergence, |
55 | create_router_bgp, | |
56 | verify_bgp_community, | |
57 | verify_bgp_attributes, | |
58 | verify_best_path_as_per_bgp_attribute, | |
59 | verify_bgp_rib, | |
985195f2 KK |
60 | ) |
61 | from lib.topojson import build_topo_from_json, build_config_from_json | |
62 | ||
bf3a0a9a DS |
63 | pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] |
64 | ||
985195f2 KK |
65 | # Global variables |
66 | NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"} | |
67 | NETWORK3_3 = {"ipv4": "50.50.50.5/32", "ipv6": "50:50::5/128"} | |
68 | NETWORK3_4 = {"ipv4": "50.50.50.50/32", "ipv6": "50:50::50/128"} | |
69 | ||
70 | PREFERRED_NEXT_HOP = "global" | |
71 | ||
72 | ||
985195f2 KK |
73 | def setup_module(mod): |
74 | """ | |
75 | Sets up the pytest environment | |
76 | ||
77 | * `mod`: module name | |
78 | """ | |
79 | ||
80 | global topo | |
81 | testsuite_run_time = time.asctime(time.localtime(time.time())) | |
82 | logger.info("Testsuite start time: {}".format(testsuite_run_time)) | |
83 | logger.info("=" * 40) | |
84 | ||
85 | logger.info("Running setup_module to create topology") | |
86 | ||
87 | # This function initiates the topology build with Topogen... | |
dc4c450f KK |
88 | json_file = "{}/bgp_vrf_dynamic_route_leak_topo2.json".format(CWD) |
89 | tgen = Topogen(json_file, mod.__name__) | |
90 | topo = tgen.json_topo | |
985195f2 KK |
91 | # ... and here it calls Mininet initialization functions. |
92 | ||
93 | # Starting topology, create tmp files which are loaded to routers | |
d60a3f0e | 94 | # to start daemons and then start routers |
985195f2 KK |
95 | start_topology(tgen) |
96 | ||
97 | # Run these tests for kernel version 4.19 or above | |
701a0192 | 98 | if version_cmp(platform.release(), "4.19") < 0: |
99 | error_msg = ( | |
100 | "BGP vrf dynamic route leak tests will not run " | |
101 | '(have kernel "{}", but it requires >= 4.19)'.format(platform.release()) | |
102 | ) | |
985195f2 KK |
103 | pytest.skip(error_msg) |
104 | ||
105 | # Creating configuration from JSON | |
106 | build_config_from_json(tgen, topo) | |
107 | ||
108 | global BGP_CONVERGENCE | |
109 | global ADDR_TYPES | |
110 | ADDR_TYPES = check_address_types() | |
111 | ||
112 | BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) | |
701a0192 | 113 | assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format( |
114 | BGP_CONVERGENCE | |
115 | ) | |
985195f2 KK |
116 | |
117 | logger.info("Running setup_module() done") | |
118 | ||
119 | ||
120 | def teardown_module(): | |
121 | """Teardown the pytest environment""" | |
122 | ||
123 | logger.info("Running teardown_module to delete topology") | |
124 | ||
125 | tgen = get_topogen() | |
126 | ||
127 | # Stop toplogy and Remove tmp files | |
128 | tgen.stop_topology() | |
129 | ||
701a0192 | 130 | logger.info( |
131 | "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) | |
132 | ) | |
985195f2 KK |
133 | logger.info("=" * 40) |
134 | ||
135 | ||
136 | ##################################################### | |
137 | # | |
138 | # Testcases | |
139 | # | |
140 | ##################################################### | |
141 | ||
701a0192 | 142 | |
985195f2 KK |
143 | def test_bgp_best_path_with_dynamic_import_p0(request): |
144 | """ | |
145 | TC6_FUNC_6: | |
146 | 1.5.6. Verify BGP best path selection algorithm works fine when | |
147 | routes are imported from ISR to default vrf and vice versa. | |
148 | """ | |
149 | ||
150 | tgen = get_topogen() | |
151 | tc_name = request.node.name | |
152 | write_test_header(tc_name) | |
153 | build_config_from_json(tgen, topo) | |
154 | ||
155 | if tgen.routers_have_failure(): | |
156 | check_router_status(tgen) | |
157 | ||
158 | for addr_type in ADDR_TYPES: | |
159 | ||
701a0192 | 160 | step( |
161 | "Redistribute configured static routes into BGP process" " on R1/R2 and R3" | |
162 | ) | |
985195f2 | 163 | |
701a0192 | 164 | input_dict_1 = {} |
985195f2 KK |
165 | DUT = ["r1", "r2", "r3", "r4"] |
166 | VRFS = ["ISR", "ISR", "default", "default"] | |
167 | AS_NUM = [100, 100, 300, 400] | |
168 | ||
169 | for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): | |
170 | temp = {dut: {"bgp": []}} | |
171 | input_dict_1.update(temp) | |
172 | ||
173 | temp[dut]["bgp"].append( | |
174 | { | |
175 | "local_as": as_num, | |
176 | "vrf": vrf, | |
177 | "address_family": { | |
178 | addr_type: { | |
701a0192 | 179 | "unicast": {"redistribute": [{"redist_type": "static"}]} |
985195f2 | 180 | } |
701a0192 | 181 | }, |
182 | } | |
183 | ) | |
985195f2 KK |
184 | |
185 | result = create_router_bgp(tgen, topo, input_dict_1) | |
701a0192 | 186 | assert result is True, "Testcase {} :Failed \n Error: {}".format( |
187 | tc_name, result | |
188 | ) | |
985195f2 KK |
189 | |
190 | for addr_type in ADDR_TYPES: | |
191 | ||
192 | step("Import from default vrf into vrf ISR on R1 and R2 as below") | |
193 | ||
701a0192 | 194 | input_dict_vrf = {} |
985195f2 KK |
195 | DUT = ["r1", "r2"] |
196 | VRFS = ["ISR", "ISR"] | |
197 | AS_NUM = [100, 100] | |
198 | ||
199 | for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): | |
200 | temp = {dut: {"bgp": []}} | |
201 | input_dict_vrf.update(temp) | |
202 | ||
203 | temp[dut]["bgp"].append( | |
204 | { | |
205 | "local_as": as_num, | |
206 | "vrf": vrf, | |
207 | "address_family": { | |
701a0192 | 208 | addr_type: {"unicast": {"import": {"vrf": "default"}}} |
209 | }, | |
210 | } | |
211 | ) | |
985195f2 KK |
212 | |
213 | result = create_router_bgp(tgen, topo, input_dict_vrf) | |
701a0192 | 214 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
215 | tc_name, result | |
216 | ) | |
985195f2 | 217 | |
701a0192 | 218 | input_dict_default = {} |
985195f2 KK |
219 | DUT = ["r1", "r2"] |
220 | VRFS = ["default", "default"] | |
221 | AS_NUM = [100, 100] | |
222 | ||
223 | for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): | |
224 | temp = {dut: {"bgp": []}} | |
225 | input_dict_default.update(temp) | |
226 | ||
227 | temp[dut]["bgp"].append( | |
228 | { | |
229 | "local_as": as_num, | |
230 | "vrf": vrf, | |
231 | "address_family": { | |
701a0192 | 232 | addr_type: {"unicast": {"import": {"vrf": "ISR"}}} |
233 | }, | |
234 | } | |
235 | ) | |
985195f2 KK |
236 | |
237 | result = create_router_bgp(tgen, topo, input_dict_default) | |
701a0192 | 238 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
239 | tc_name, result | |
240 | ) | |
985195f2 | 241 | |
701a0192 | 242 | step( |
243 | "Verify ECMP/Next-hop/Imported routes Vs Locally originated " | |
244 | "routes/eBGP routes vs iBGP routes --already covered in almost" | |
245 | " all tests" | |
246 | ) | |
985195f2 KK |
247 | |
248 | for addr_type in ADDR_TYPES: | |
249 | ||
250 | step("Verify Pre-emption") | |
251 | ||
252 | input_routes_r3 = { | |
701a0192 | 253 | "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]} |
985195f2 KK |
254 | } |
255 | ||
256 | intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] | |
257 | intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"] | |
258 | ||
259 | if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP: | |
260 | nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) | |
261 | nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) | |
262 | else: | |
701a0192 | 263 | nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[ |
264 | 0 | |
265 | ] | |
266 | nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[ | |
267 | 0 | |
268 | ] | |
985195f2 | 269 | |
701a0192 | 270 | result = verify_bgp_rib( |
271 | tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r4_r1] | |
272 | ) | |
273 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
274 | tc_name, result | |
275 | ) | |
985195f2 KK |
276 | |
277 | step("Shutdown interface connected to r1 from r4:") | |
701a0192 | 278 | shutdown_bringup_interface(tgen, "r4", intf_r4_r1, False) |
985195f2 KK |
279 | |
280 | for addr_type in ADDR_TYPES: | |
281 | ||
282 | input_routes_r3 = { | |
701a0192 | 283 | "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]} |
985195f2 KK |
284 | } |
285 | ||
286 | intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] | |
287 | intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"] | |
288 | ||
289 | if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP: | |
290 | nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) | |
291 | nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) | |
292 | else: | |
701a0192 | 293 | nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[ |
294 | 0 | |
295 | ] | |
296 | nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[ | |
297 | 0 | |
298 | ] | |
985195f2 KK |
299 | |
300 | step("Verify next-hop is changed") | |
701a0192 | 301 | result = verify_bgp_rib( |
302 | tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1] | |
303 | ) | |
304 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
305 | tc_name, result | |
306 | ) | |
985195f2 KK |
307 | |
308 | step("Bringup interface connected to r1 from r4:") | |
701a0192 | 309 | shutdown_bringup_interface(tgen, "r4", intf_r4_r1, True) |
985195f2 KK |
310 | |
311 | for addr_type in ADDR_TYPES: | |
312 | ||
313 | input_routes_r3 = { | |
701a0192 | 314 | "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]} |
985195f2 KK |
315 | } |
316 | ||
317 | intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"] | |
318 | intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"] | |
319 | ||
320 | if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP: | |
321 | nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1) | |
322 | nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1) | |
323 | else: | |
701a0192 | 324 | nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[ |
325 | 0 | |
326 | ] | |
327 | nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[ | |
328 | 0 | |
329 | ] | |
985195f2 KK |
330 | |
331 | step("Verify next-hop is not chnaged aftr shutdown:") | |
701a0192 | 332 | result = verify_bgp_rib( |
333 | tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1] | |
334 | ) | |
335 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
336 | tc_name, result | |
337 | ) | |
985195f2 KK |
338 | |
339 | step("Active-Standby scenario(as-path prepend and Local pref)") | |
340 | ||
341 | for addr_type in ADDR_TYPES: | |
342 | ||
343 | step("Create prefix-list") | |
344 | ||
345 | input_dict_pf = { | |
346 | "r1": { | |
347 | "prefix_lists": { | |
348 | addr_type: { | |
701a0192 | 349 | "pf_ls_{}".format(addr_type): [ |
350 | { | |
351 | "seqid": 10, | |
352 | "network": NETWORK3_4[addr_type], | |
353 | "action": "permit", | |
354 | } | |
355 | ] | |
985195f2 KK |
356 | } |
357 | } | |
358 | } | |
359 | } | |
360 | result = create_prefix_lists(tgen, input_dict_pf) | |
361 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
701a0192 | 362 | tc_name, result |
363 | ) | |
985195f2 KK |
364 | |
365 | for addr_type in ADDR_TYPES: | |
366 | ||
367 | step("Create route-map to match prefix-list and set localpref 500") | |
368 | ||
369 | input_dict_rm = { | |
370 | "r1": { | |
371 | "route_maps": { | |
701a0192 | 372 | "rmap_PATH1_{}".format(addr_type): [ |
373 | { | |
374 | "action": "permit", | |
375 | "seq_id": 10, | |
376 | "match": { | |
377 | addr_type: { | |
378 | "prefix_lists": "pf_ls_{}".format(addr_type) | |
379 | } | |
380 | }, | |
381 | "set": {"locPrf": 500}, | |
985195f2 | 382 | } |
701a0192 | 383 | ] |
985195f2 KK |
384 | } |
385 | } | |
386 | } | |
387 | ||
388 | result = create_route_maps(tgen, input_dict_rm) | |
701a0192 | 389 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
390 | tc_name, result | |
391 | ) | |
985195f2 KK |
392 | |
393 | step("Create route-map to match prefix-list and set localpref 600") | |
394 | ||
395 | input_dict_rm = { | |
396 | "r1": { | |
397 | "route_maps": { | |
701a0192 | 398 | "rmap_PATH2_{}".format(addr_type): [ |
399 | { | |
400 | "action": "permit", | |
401 | "seq_id": 20, | |
402 | "match": { | |
403 | addr_type: { | |
404 | "prefix_lists": "pf_ls_{}".format(addr_type) | |
405 | } | |
406 | }, | |
407 | "set": {"locPrf": 600}, | |
985195f2 | 408 | } |
701a0192 | 409 | ] |
985195f2 KK |
410 | } |
411 | } | |
412 | } | |
413 | ||
414 | result = create_route_maps(tgen, input_dict_rm) | |
701a0192 | 415 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
416 | tc_name, result | |
417 | ) | |
985195f2 | 418 | |
701a0192 | 419 | input_dict_rma = { |
985195f2 | 420 | "r1": { |
701a0192 | 421 | "bgp": [ |
985195f2 KK |
422 | { |
423 | "local_as": "100", | |
424 | "address_family": { | |
425 | addr_type: { | |
426 | "unicast": { | |
427 | "neighbor": { | |
428 | "r3": { | |
429 | "dest_link": { | |
430 | "r1-link1": { | |
701a0192 | 431 | "route_maps": [ |
432 | { | |
433 | "name": "rmap_PATH1_{}".format( | |
434 | addr_type | |
435 | ), | |
436 | "direction": "in", | |
437 | } | |
438 | ] | |
985195f2 KK |
439 | } |
440 | } | |
441 | }, | |
442 | "r4": { | |
443 | "dest_link": { | |
444 | "r1-link1": { | |
701a0192 | 445 | "route_maps": [ |
446 | { | |
447 | "name": "rmap_PATH2_{}".format( | |
448 | addr_type | |
449 | ), | |
450 | "direction": "in", | |
451 | } | |
452 | ] | |
985195f2 KK |
453 | } |
454 | } | |
701a0192 | 455 | }, |
985195f2 KK |
456 | } |
457 | } | |
458 | } | |
701a0192 | 459 | }, |
985195f2 | 460 | } |
701a0192 | 461 | ] |
985195f2 | 462 | } |
701a0192 | 463 | } |
985195f2 KK |
464 | |
465 | result = create_router_bgp(tgen, topo, input_dict_rma) | |
466 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
701a0192 | 467 | tc_name, result |
468 | ) | |
985195f2 KK |
469 | |
470 | dut = "r1" | |
471 | attribute = "locPrf" | |
472 | ||
473 | for addr_type in ADDR_TYPES: | |
474 | ||
475 | step("Verify bestpath is installed as per highest localpref") | |
476 | ||
477 | input_routes_r3 = { | |
478 | "r3": { | |
701a0192 | 479 | "static_routes": [ |
480 | {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]} | |
481 | ] | |
985195f2 KK |
482 | } |
483 | } | |
484 | ||
701a0192 | 485 | result = verify_best_path_as_per_bgp_attribute( |
486 | tgen, addr_type, dut, input_routes_r3, attribute | |
487 | ) | |
985195f2 | 488 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
701a0192 | 489 | tc_name, result |
490 | ) | |
985195f2 KK |
491 | |
492 | for addr_type in ADDR_TYPES: | |
493 | ||
494 | step("Create route-map to match prefix-list and set localpref 700") | |
495 | ||
496 | input_dict_rm = { | |
497 | "r1": { | |
498 | "route_maps": { | |
701a0192 | 499 | "rmap_PATH1_{}".format(addr_type): [ |
500 | { | |
501 | "action": "permit", | |
502 | "seq_id": 10, | |
503 | "match": { | |
504 | addr_type: { | |
505 | "prefix_lists": "pf_ls_{}".format(addr_type) | |
506 | } | |
507 | }, | |
508 | "set": {"locPrf": 700}, | |
985195f2 | 509 | } |
701a0192 | 510 | ] |
985195f2 KK |
511 | } |
512 | } | |
513 | } | |
514 | ||
515 | result = create_route_maps(tgen, input_dict_rm) | |
701a0192 | 516 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
517 | tc_name, result | |
518 | ) | |
985195f2 KK |
519 | |
520 | for addr_type in ADDR_TYPES: | |
521 | ||
522 | step("Verify bestpath is changed as per highest localpref") | |
523 | ||
524 | input_routes_r3 = { | |
525 | "r3": { | |
701a0192 | 526 | "static_routes": [ |
527 | {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]} | |
528 | ] | |
985195f2 KK |
529 | } |
530 | } | |
531 | ||
701a0192 | 532 | result = verify_best_path_as_per_bgp_attribute( |
533 | tgen, addr_type, dut, input_routes_r3, attribute | |
534 | ) | |
985195f2 | 535 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
701a0192 | 536 | tc_name, result |
537 | ) | |
985195f2 KK |
538 | |
539 | for addr_type in ADDR_TYPES: | |
540 | ||
541 | step("Create route-map to match prefix-list and set as-path prepend") | |
542 | ||
543 | input_dict_rm = { | |
544 | "r1": { | |
545 | "route_maps": { | |
701a0192 | 546 | "rmap_PATH2_{}".format(addr_type): [ |
547 | { | |
548 | "action": "permit", | |
549 | "seq_id": 20, | |
550 | "match": { | |
551 | addr_type: { | |
552 | "prefix_lists": "pf_ls_{}".format(addr_type) | |
553 | } | |
554 | }, | |
555 | "set": { | |
556 | "localpref": 700, | |
557 | "path": {"as_num": "111", "as_action": "prepend"}, | |
558 | }, | |
985195f2 | 559 | } |
701a0192 | 560 | ] |
985195f2 KK |
561 | } |
562 | } | |
563 | } | |
564 | ||
565 | result = create_route_maps(tgen, input_dict_rm) | |
701a0192 | 566 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
567 | tc_name, result | |
568 | ) | |
985195f2 KK |
569 | |
570 | attribute = "path" | |
571 | ||
572 | for addr_type in ADDR_TYPES: | |
573 | ||
574 | step("Verify bestpath is changed as per shortest as-path") | |
575 | ||
576 | input_routes_r3 = { | |
577 | "r3": { | |
701a0192 | 578 | "static_routes": [ |
579 | {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]} | |
580 | ] | |
985195f2 KK |
581 | } |
582 | } | |
583 | ||
701a0192 | 584 | result = verify_best_path_as_per_bgp_attribute( |
585 | tgen, addr_type, dut, input_routes_r3, attribute | |
586 | ) | |
985195f2 | 587 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
701a0192 | 588 | tc_name, result |
589 | ) | |
985195f2 KK |
590 | |
591 | write_test_footer(tc_name) | |
592 | ||
593 | ||
594 | def test_modify_route_map_match_set_clauses_p1(request): | |
595 | """ | |
596 | TC13_CHAOS_4: | |
597 | 1.5.13. Verify that Changing route-map configurations(match/set clauses) on | |
598 | the fly it takes immediate effect. | |
599 | """ | |
600 | ||
601 | tgen = get_topogen() | |
602 | tc_name = request.node.name | |
603 | write_test_header(tc_name) | |
604 | build_config_from_json(tgen, topo) | |
605 | ||
606 | if tgen.routers_have_failure(): | |
607 | check_router_status(tgen) | |
608 | ||
609 | for addr_type in ADDR_TYPES: | |
610 | ||
701a0192 | 611 | step( |
612 | "Configure route-map to set community attribute for a specific" | |
613 | "prefix on R1 in vrf ISR" | |
614 | ) | |
985195f2 KK |
615 | |
616 | input_dict_pf = { | |
617 | "r1": { | |
618 | "prefix_lists": { | |
619 | addr_type: { | |
701a0192 | 620 | "pflist_ABC_{}".format(addr_type): [ |
621 | { | |
622 | "seqid": 10, | |
623 | "network": NETWORK1_1[addr_type], | |
624 | "action": "permit", | |
625 | } | |
626 | ] | |
985195f2 KK |
627 | } |
628 | } | |
629 | } | |
630 | } | |
631 | result = create_prefix_lists(tgen, input_dict_pf) | |
632 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
701a0192 | 633 | tc_name, result |
634 | ) | |
985195f2 KK |
635 | |
636 | input_dict_cl = { | |
637 | "r1": { | |
638 | "bgp_community_lists": [ | |
701a0192 | 639 | { |
640 | "community_type": "expanded", | |
641 | "action": "permit", | |
642 | "name": "COMM", | |
643 | "value": "100:100", | |
985195f2 KK |
644 | } |
645 | ] | |
646 | } | |
647 | } | |
648 | result = create_bgp_community_lists(tgen, input_dict_cl) | |
701a0192 | 649 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) |
985195f2 KK |
650 | |
651 | for addr_type in ADDR_TYPES: | |
652 | input_dict_rm = { | |
653 | "r1": { | |
654 | "route_maps": { | |
701a0192 | 655 | "rmap_XYZ_{}".format(addr_type): [ |
656 | { | |
657 | "action": "permit", | |
658 | "match": { | |
659 | addr_type: { | |
660 | "prefix_lists": "pflist_ABC_{}".format(addr_type) | |
661 | } | |
662 | }, | |
663 | "set": {"community": {"num": "100:100"}}, | |
985195f2 | 664 | } |
701a0192 | 665 | ] |
985195f2 KK |
666 | } |
667 | } | |
668 | } | |
669 | result = create_route_maps(tgen, input_dict_rm) | |
701a0192 | 670 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
671 | tc_name, result | |
672 | ) | |
985195f2 KK |
673 | |
674 | for addr_type in ADDR_TYPES: | |
675 | ||
701a0192 | 676 | step( |
677 | "Apply this route-map on R1 to vrf ISR while redistributing the" | |
678 | " prefixes into BGP" | |
679 | ) | |
985195f2 | 680 | |
701a0192 | 681 | input_dict_1 = {} |
985195f2 KK |
682 | DUT = ["r1"] |
683 | VRFS = ["ISR"] | |
684 | AS_NUM = [100] | |
685 | ||
686 | for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): | |
687 | temp = {dut: {"bgp": []}} | |
688 | input_dict_1.update(temp) | |
689 | ||
690 | temp[dut]["bgp"].append( | |
691 | { | |
692 | "local_as": as_num, | |
693 | "vrf": vrf, | |
694 | "address_family": { | |
695 | addr_type: { | |
696 | "unicast": { | |
701a0192 | 697 | "redistribute": [ |
698 | { | |
699 | "redist_type": "static", | |
985195f2 | 700 | "attribute": { |
701a0192 | 701 | "route-map": "rmap_XYZ_{}".format(addr_type) |
702 | }, | |
985195f2 KK |
703 | } |
704 | ] | |
705 | } | |
706 | } | |
701a0192 | 707 | }, |
708 | } | |
709 | ) | |
985195f2 KK |
710 | |
711 | result = create_router_bgp(tgen, topo, input_dict_1) | |
701a0192 | 712 | assert result is True, "Testcase {} :Failed \n Error: {}".format( |
713 | tc_name, result | |
714 | ) | |
985195f2 KK |
715 | |
716 | for addr_type in ADDR_TYPES: | |
717 | ||
701a0192 | 718 | step( |
719 | "Configure another route-map for filtering the prefixes based on" | |
720 | " community attribute while importing into default vrf" | |
721 | ) | |
985195f2 KK |
722 | |
723 | input_dict_rm = { | |
724 | "r1": { | |
725 | "route_maps": { | |
701a0192 | 726 | "rmap_IMP_{}".format(addr_type): [ |
727 | { | |
728 | "action": "permit", | |
729 | "seq_id": 10, | |
730 | "match": {"community_list": {"id": "COMM"}}, | |
731 | "set": {"community": {"num": "none"}}, | |
985195f2 | 732 | } |
701a0192 | 733 | ] |
985195f2 KK |
734 | } |
735 | } | |
736 | } | |
737 | result = create_route_maps(tgen, input_dict_rm) | |
701a0192 | 738 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
739 | tc_name, result | |
740 | ) | |
985195f2 KK |
741 | |
742 | for addr_type in ADDR_TYPES: | |
743 | ||
701a0192 | 744 | step( |
745 | "Apply the route-map while Importing vrf ISR's prefixes into " | |
746 | "default vrf on router R1:" | |
747 | ) | |
985195f2 | 748 | |
701a0192 | 749 | input_dict_isr = {} |
985195f2 KK |
750 | DUT = ["r1"] |
751 | VRFS = ["default"] | |
752 | AS_NUM = [100] | |
753 | ||
754 | for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM): | |
755 | temp = {dut: {"bgp": []}} | |
756 | input_dict_isr.update(temp) | |
757 | ||
758 | temp[dut]["bgp"].append( | |
759 | { | |
760 | "local_as": as_num, | |
761 | "vrf": vrf, | |
762 | "address_family": { | |
701a0192 | 763 | addr_type: {"unicast": {"import": {"vrf": "ISR"}}} |
764 | }, | |
765 | } | |
766 | ) | |
985195f2 KK |
767 | |
768 | temp[dut]["bgp"].append( | |
769 | { | |
770 | "local_as": as_num, | |
771 | "vrf": vrf, | |
772 | "address_family": { | |
773 | addr_type: { | |
774 | "unicast": { | |
775 | "import": { | |
776 | "vrf": "route-map rmap_IMP_{}".format(addr_type) | |
777 | } | |
778 | } | |
779 | } | |
701a0192 | 780 | }, |
781 | } | |
782 | ) | |
985195f2 KK |
783 | |
784 | result = create_router_bgp(tgen, topo, input_dict_isr) | |
701a0192 | 785 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
786 | tc_name, result | |
787 | ) | |
985195f2 KK |
788 | |
789 | for addr_type in ADDR_TYPES: | |
790 | ||
701a0192 | 791 | step( |
792 | "Verify on R1 that only prefixes with community value 100:100" | |
985195f2 | 793 | "in vrf ISR are imported to vrf default. While importing, the" |
701a0192 | 794 | " community value has been stripped off:" |
795 | ) | |
985195f2 KK |
796 | |
797 | input_routes_r1 = { | |
798 | "r1": { | |
701a0192 | 799 | "static_routes": [ |
800 | {"network": [NETWORK1_1[addr_type]], "vrf": "default"} | |
801 | ] | |
985195f2 KK |
802 | } |
803 | } | |
804 | ||
805 | result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1) | |
701a0192 | 806 | assert result is True, "Testcase {} : Failed \n Error {}".format( |
807 | tc_name, result | |
808 | ) | |
985195f2 KK |
809 | |
810 | for addr_type in ADDR_TYPES: | |
811 | ||
812 | step("Add set clause in route-map IMP:") | |
813 | ||
814 | input_dict_rm = { | |
815 | "r1": { | |
816 | "route_maps": { | |
701a0192 | 817 | "rmap_IMP_{}".format(addr_type): [ |
818 | { | |
819 | "action": "permit", | |
820 | "seq_id": 10, | |
821 | "match": {"community_list": {"id": "COMM"}}, | |
822 | "set": { | |
823 | "large_community": {"num": "100:100:100"}, | |
824 | "locPrf": 500, | |
825 | "path": {"as_num": "100 100", "as_action": "prepend"}, | |
826 | }, | |
985195f2 | 827 | } |
701a0192 | 828 | ] |
985195f2 KK |
829 | } |
830 | } | |
831 | } | |
832 | result = create_route_maps(tgen, input_dict_rm) | |
701a0192 | 833 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
834 | tc_name, result | |
835 | ) | |
985195f2 KK |
836 | |
837 | for addr_type in ADDR_TYPES: | |
838 | ||
701a0192 | 839 | step( |
840 | "Verify that as we continue adding different attributes " | |
985195f2 | 841 | "step-by-step in route-map IMP those attributes gets " |
701a0192 | 842 | "attached to prefixes:" |
843 | ) | |
985195f2 KK |
844 | |
845 | input_routes_r1 = { | |
846 | "r1": { | |
701a0192 | 847 | "static_routes": [ |
848 | {"network": [NETWORK1_1[addr_type]], "vrf": "default"} | |
849 | ] | |
985195f2 KK |
850 | } |
851 | } | |
852 | ||
701a0192 | 853 | input_dict_comm = {"largeCommunity": "100:100:100"} |
985195f2 | 854 | |
701a0192 | 855 | result = verify_bgp_community( |
856 | tgen, addr_type, dut, [NETWORK1_1[addr_type]], input_dict_comm | |
857 | ) | |
858 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
859 | tc_name, result | |
860 | ) | |
985195f2 KK |
861 | |
862 | input_rmap = { | |
863 | "r1": { | |
864 | "route_maps": { | |
701a0192 | 865 | "rmap_IMP_{}".format(addr_type): [{"set": {"locPrf": 500}}] |
985195f2 KK |
866 | } |
867 | } | |
868 | } | |
869 | ||
701a0192 | 870 | result = verify_bgp_attributes( |
871 | tgen, | |
872 | addr_type, | |
873 | "r1", | |
874 | [NETWORK1_1[addr_type]], | |
875 | rmap_name="rmap_IMP_{}".format(addr_type), | |
876 | input_dict=input_rmap, | |
877 | ) | |
a53c08bc CH |
878 | assert result is True, "Testcase {} : Failed \n Error: {}".format( |
879 | tc_name, result | |
880 | ) | |
985195f2 | 881 | |
701a0192 | 882 | step("Change community-list to match a different value then " "100:100.") |
985195f2 KK |
883 | |
884 | input_dict_cl = { | |
885 | "r1": { | |
886 | "bgp_community_lists": [ | |
701a0192 | 887 | { |
888 | "community_type": "expanded", | |
889 | "action": "permit", | |
890 | "name": "COMM", | |
891 | "value": "100:100", | |
892 | "delete": True, | |
985195f2 KK |
893 | } |
894 | ] | |
895 | } | |
896 | } | |
897 | result = create_bgp_community_lists(tgen, input_dict_cl) | |
701a0192 | 898 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) |
985195f2 KK |
899 | |
900 | for addr_type in ADDR_TYPES: | |
901 | ||
902 | input_routes_r1 = { | |
903 | "r1": { | |
701a0192 | 904 | "static_routes": [ |
905 | {"network": [NETWORK1_1[addr_type]], "vrf": "default"} | |
906 | ] | |
985195f2 KK |
907 | } |
908 | } | |
909 | ||
701a0192 | 910 | result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False) |
9fa6ec14 | 911 | assert ( |
912 | result is not True | |
913 | ), "Testcase {} : Failed \n Error : Routes are still " "present {}".format( | |
914 | tc_name, result | |
701a0192 | 915 | ) |
985195f2 KK |
916 | |
917 | write_test_footer(tc_name) | |
918 | ||
919 | ||
701a0192 | 920 | if __name__ == "__main__": |
985195f2 KK |
921 | args = ["-s"] + sys.argv[1:] |
922 | sys.exit(pytest.main(args)) |