]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_vrf_lite_best_path_test / test_bgp_vrf_lite_best_path_topo2.py
CommitLineData
687c62fc 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
687c62fc
IS
3
4#
5# Copyright (c) 2021 by VMware, Inc. ("VMware")
6# Used Copyright (c) 2018 by Network Device Education Foundation,
7# Inc. ("NetDEF") in this file.
8#
687c62fc
IS
9
10"""
11Following tests are covered to test BGP VRF Lite:
121. Verify that locally imported routes are selected as best path over eBGP imported routes
13 peers.
142. Verify ECMP for imported routes from different VRFs.
15"""
16
17import os
18import sys
19import time
20import pytest
21import platform
22from time import sleep
23
24# Save the Current Working Directory to find configuration files.
25CWD = os.path.dirname(os.path.realpath(__file__))
26sys.path.append(os.path.join(CWD, "../"))
27sys.path.append(os.path.join(CWD, "../lib/"))
28
29# Required to instantiate the topology builder class.
30
31# pylint: disable=C0413
32# Import topogen and topotest helpers
33from lib.topogen import Topogen, get_topogen
34from lib.topotest import version_cmp
35
36from lib.common_config import (
37 start_topology,
38 write_test_header,
39 check_address_types,
40 write_test_footer,
41 reset_config_on_routers,
42 verify_rib,
43 step,
44 create_static_routes,
45 check_router_status,
46 apply_raw_config
47)
48
49from lib.topolog import logger
50from lib.bgp import (
51 verify_bgp_convergence,
52 create_router_bgp,
53 verify_bgp_rib,
54 verify_bgp_bestpath
55)
56from lib.topojson import build_config_from_json
57
58pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
59
60# Global variables
61NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"}
62NETWORK1_2 = {"ipv4": "11.11.11.11/32", "ipv6": "11:11::11/128"}
63NETWORK1_3 = {"ipv4": "10.10.10.1/32", "ipv6": "10:10::1/128"}
64NETWORK1_4 = {"ipv4": "10.10.10.100/32", "ipv6": "10:10::100/128"}
65NETWORK1_5 = {"ipv4": "110.110.110.1/32", "ipv6": "110:110::1/128"}
66NETWORK1_6 = {"ipv4": "110.110.110.100/32", "ipv6": "110:110::100/128"}
67
68NETWORK2_1 = {"ipv4": "22.22.22.2/32", "ipv6": "22:22::2/128"}
69NETWORK2_2 = {"ipv4": "22.22.22.22/32", "ipv6": "22:22::22/128"}
70NETWORK2_3 = {"ipv4": "20.20.20.20/32", "ipv6": "20:20::20/128"}
71NETWORK2_4 = {"ipv4": "20.20.20.200/32", "ipv6": "20:20::200/128"}
72NETWORK2_5 = {"ipv4": "220.220.220.20/32", "ipv6": "220:220::20/128"}
73NETWORK2_6 = {"ipv4": "220.220.220.200/32", "ipv6": "220:220::200/128"}
74
75NETWORK3_1 = {"ipv4": "30.30.30.3/32", "ipv6": "30:30::3/128"}
76NETWORK3_2 = {"ipv4": "30.30.30.30/32", "ipv6": "30:30::30/128"}
77
78PREFIX_LIST = {
79 "ipv4": ["11.11.11.1", "22.22.22.2", "22.22.22.22"],
80 "ipv6": ["11:11::1", "22:22::2", "22:22::22"],
81}
82PREFERRED_NEXT_HOP = "global"
83VRF_LIST = ["RED", "BLUE", "GREEN"]
84COMM_VAL_1 = "100:100"
85COMM_VAL_2 = "500:500"
86COMM_VAL_3 = "600:600"
87BESTPATH = {
88 "ipv4": "0.0.0.0",
89 "ipv6": "::"
90}
91
92def setup_module(mod):
93 """
94 Sets up the pytest environment
95
96 * `mod`: module name
97 """
98
99 testsuite_run_time = time.asctime(time.localtime(time.time()))
100 logger.info("Testsuite start time: {}".format(testsuite_run_time))
101 logger.info("=" * 40)
102
103 logger.info("Running setup_module to create topology")
104
105 # This function initiates the topology build with Topogen...
106 json_file = "{}/bgp_vrf_lite_best_path_topo2.json".format(CWD)
107 tgen = Topogen(json_file, mod.__name__)
108 global topo
109 topo = tgen.json_topo
110 # ... and here it calls Mininet initialization functions.
111
112 # Starting topology, create tmp files which are loaded to routers
d60a3f0e 113 # to start daemons and then start routers
687c62fc
IS
114 start_topology(tgen)
115
116 # Run these tests for kernel version 4.19 or above
117 if version_cmp(platform.release(), "4.19") < 0:
118 error_msg = (
119 "BGP vrf dynamic route leak tests will not run "
120 '(have kernel "{}", but it requires >= 4.19)'.format(platform.release())
121 )
122 pytest.skip(error_msg)
123
124 # Creating configuration from JSON
125 build_config_from_json(tgen, topo)
126
127 global BGP_CONVERGENCE
128 global ADDR_TYPES
129 ADDR_TYPES = check_address_types()
130
131 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
132 assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format(
133 BGP_CONVERGENCE
134 )
135
136 logger.info("Running setup_module() done")
137
138
139def teardown_module():
140 """Teardown the pytest environment"""
141
142 logger.info("Running teardown_module to delete topology")
143
144 tgen = get_topogen()
145
146 # Stop toplogy and Remove tmp files
147 tgen.stop_topology()
148
149 logger.info(
150 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
151 )
152 logger.info("=" * 40)
153
154
155#####################################################
156#
157# Testcases
158#
159#####################################################
160
161def test_dynamic_import_ecmp_imported_routed_diffrent_vrfs_p0(request):
162 """
163 Verify ECMP for imported routes from different VRFs.
164 """
165
166 tgen = get_topogen()
167 tc_name = request.node.name
168 write_test_header(tc_name)
169 if tgen.routers_have_failure():
170 check_router_status(tgen)
171 reset_config_on_routers(tgen)
172
173 step("Configure same static routes in tenant vrfs RED and GREEN on router "
174 "R3 and redistribute in respective BGP process")
175
176 for vrf_name in ["RED", "GREEN"]:
177 for addr_type in ADDR_TYPES:
178 if vrf_name == "GREEN":
179 next_hop_vrf = topo["routers"]["r1"]["links"][
180 "r3-link3"][addr_type].split("/")[0]
181 else:
182 next_hop_vrf = topo["routers"]["r2"]["links"][
183 "r3-link1"][addr_type].split("/")[0]
184 static_routes = {
185 "r3": {
186 "static_routes": [
187 {
188 "network": [NETWORK1_1[addr_type]],
189 "next_hop": next_hop_vrf,
190 "vrf": vrf_name
191 }
192 ]
193 }
194 }
195
196 result = create_static_routes(tgen, static_routes)
197 assert result is True, "Testcase {} :Failed \n Error: {}". \
198 format(tc_name, result)
199
200 step("Redistribute static route on BGP VRF : {}".format(vrf_name))
201 temp = {}
202 for addr_type in ADDR_TYPES:
203 temp.update({
204 addr_type: {
205 "unicast": {
206 "redistribute": [{
207 "redist_type": "static"
208 }]
209 }
210 }
211 })
212
213 redist_dict = {"r3": {"bgp": [{
214 "vrf": vrf_name, "local_as": 3, "address_family": temp
215 }]}}
216
217 result = create_router_bgp(tgen, topo, redist_dict)
218 assert result is True, "Testcase {} :Failed \n Error: {}". \
219 format(tc_name, result)
220
221 step("Verify that configured static routes are installed in respective "
222 "BGP table for vrf RED & GREEN")
223 for vrf_name in ["RED", "GREEN"]:
224 for addr_type in ADDR_TYPES:
225 if vrf_name == "GREEN":
226 next_hop_vrf = topo["routers"]["r1"]["links"][
227 "r3-link3"][addr_type].split("/")[0]
228 else:
229 next_hop_vrf = topo["routers"]["r2"]["links"][
230 "r3-link1"][addr_type].split("/")[0]
231 static_routes = {
232 "r3": {
233 "static_routes": [
234 {
235 "network": [NETWORK1_1[addr_type]],
236 "vrf": vrf_name
237 }
238 ]
239 }
240 }
241
242 result = verify_bgp_rib(tgen, addr_type, "r3", static_routes,
243 next_hop=next_hop_vrf)
244 assert result is True, "Testcase {} : Failed \n Error {}". \
245 format(tc_name, result)
246
247 result = verify_rib(tgen, addr_type, "r3", static_routes,
248 next_hop=next_hop_vrf)
249 assert result is True, "Testcase {} : Failed \n Error {}". \
250 format(tc_name, result)
251
252 step("Import vrf RED and GREEN into default vrf and Configure ECMP")
253 bgp_val = []
254 for vrf_name in ["RED", "GREEN"]:
255 temp = {}
256 for addr_type in ADDR_TYPES:
257 temp.update({
258 addr_type: {
259 "unicast": {
260 "import": {
261 "vrf": vrf_name
262 },
263 "maximum_paths": {
264 "ebgp": 2
265 }
266 }
267 }
268 })
269
270 bgp_val.append({
271 "local_as": 3, "address_family": temp
272 })
273
274 import_dict = {"r3": {"bgp": bgp_val}}
275
276 result = create_router_bgp(tgen, topo, import_dict)
277 assert result is True, "Testcase {} :Failed \n Error: {}". \
278 format(tc_name, result)
279
280 step("Configure bgp bestpath on router r3")
281 r3_raw_config = {
282 "r3": {
283 "raw_config": [
284 "router bgp 3",
285 "bgp bestpath as-path multipath-relax"
286 ]
287 }
288 }
289 result = apply_raw_config(tgen, r3_raw_config)
290 assert result is True, "Testcase {} :Failed \n Error: {}". \
291 format(tc_name, result)
292
293 step("Verify that routes are imported with two different next-hop vrfs "
294 "and IPs. Additionally R3 must do ECMP for both the routes.")
295
296 for addr_type in ADDR_TYPES:
297 next_hop_vrf = [
298 topo["routers"]["r2"]["links"]["r3-link1"][addr_type]. \
299 split("/")[0],
300 topo["routers"]["r1"]["links"]["r3-link3"][addr_type]. \
301 split("/")[0]
302 ]
303 static_routes = {
304 "r3": {
305 "static_routes": [
306 {
307 "network": [NETWORK1_1[addr_type]],
308 }
309 ]
310 }
311 }
312
313 result = verify_bgp_rib(tgen, addr_type, "r3", static_routes,
314 next_hop=next_hop_vrf)
315 assert result is True, "Testcase {} : Failed \n Error {}". \
316 format(tc_name, result)
317
318 result = verify_rib(tgen, addr_type, "r3", static_routes,
319 next_hop=next_hop_vrf)
320 assert result is True, "Testcase {} : Failed \n Error {}". \
321 format(tc_name, result)
322
323 step("Now change the next-hop of static routes in vrf RED and GREEN to "
324 "same IP address")
325 for addr_type in ADDR_TYPES:
326 next_hop_vrf = topo["routers"]["r1"]["links"][
327 "r3-link3"][addr_type].split("/")[0]
328 static_routes = {
329 "r3": {
330 "static_routes": [
331 {
332 "network": [NETWORK1_1[addr_type]],
333 "next_hop": next_hop_vrf,
334 "vrf": "RED"
335 },
336 {
337 "network": [NETWORK1_1[addr_type]],
338 "next_hop": topo["routers"]["r2"]["links"][
339 "r3-link1"][addr_type].split("/")[0],
340 "vrf": "RED",
341 "delete": True
342 }
343 ]
344 }
345 }
346
347 result = create_static_routes(tgen, static_routes)
348 assert result is True, "Testcase {} :Failed \n Error: {}". \
349 format(tc_name, result)
350
351 step("Verify that now routes are imported with two different next-hop "
352 "vrfs but same IPs. Additionally R3 must do ECMP for both the routes")
353
354 for addr_type in ADDR_TYPES:
355 next_hop_vrf = [
356 topo["routers"]["r1"]["links"]["r3-link3"][addr_type].\
357 split("/")[0],
358 topo["routers"]["r1"]["links"]["r3-link3"][addr_type]. \
359 split("/")[0]
360 ]
361 static_routes = {
362 "r3": {
363 "static_routes": [
364 {
365 "network": [NETWORK1_1[addr_type]],
366 }
367 ]
368 }
369 }
370
371 result = verify_bgp_rib(tgen, addr_type, "r3", static_routes,
372 next_hop=next_hop_vrf)
373 assert result is True, "Testcase {} : Failed \n Error {}". \
374 format(tc_name, result)
375
376 result = verify_rib(tgen, addr_type, "r3", static_routes,
377 next_hop=next_hop_vrf)
378 assert result is True, "Testcase {} : Failed \n Error {}". \
379 format(tc_name, result)
380
381 write_test_footer(tc_name)
382
383
384def test_locally_imported_routes_selected_as_bestpath_over_ebgp_imported_routes_p0(request):
385 """
386 Verify ECMP for imported routes from different VRFs.
387 """
388
389 tgen = get_topogen()
390 tc_name = request.node.name
391 write_test_header(tc_name)
392 if tgen.routers_have_failure():
393 check_router_status(tgen)
394 reset_config_on_routers(tgen)
395
396 step("Configure same static routes on R2 and R3 vrfs and redistribute in BGP "
397 "for GREEN and RED vrf instances")
398 for dut, network in zip(["r2", "r3"], [
399 [NETWORK1_1, NETWORK1_2], [NETWORK1_1, NETWORK1_2]]):
400 for vrf_name, network_vrf in zip(["RED", "GREEN"], network):
401 step("Configure static route for VRF : {} on {}".format(vrf_name,
402 dut))
403 for addr_type in ADDR_TYPES:
404 static_routes = {
405 dut: {
406 "static_routes": [
407 {
408 "network": [network_vrf[addr_type]],
409 "next_hop": "blackhole",
410 "vrf": vrf_name
411 }
412 ]
413 }
414 }
415
416 result = create_static_routes(tgen, static_routes)
417 assert result is True, "Testcase {} :Failed \n Error: {}". \
418 format(tc_name, result)
419
420 for dut, as_num in zip(["r2", "r3"], ["2", "3"]):
421 for vrf_name in ["RED", "GREEN"]:
422 step("Redistribute static route on BGP VRF : {}".format(vrf_name))
423 temp = {}
424 for addr_type in ADDR_TYPES:
425 temp.update({
426 addr_type: {
427 "unicast": {
428 "redistribute": [{
429 "redist_type": "static"
430 }]
431 }
432 }
433 })
434
435 redist_dict = {dut: {"bgp": [{
436 "vrf": vrf_name, "local_as": as_num, "address_family": temp
437 }]}}
438
439 result = create_router_bgp(tgen, topo, redist_dict)
440 assert result is True, "Testcase {} :Failed \n Error: {}". \
441 format(tc_name, result)
442
443 step("Verify that R2 and R3 has installed redistributed routes in default "
444 "and RED vrfs and GREEN respectively:")
445 for dut, network in zip(["r2", "r3"],
446 [[NETWORK1_1, NETWORK1_2],
447 [NETWORK1_1, NETWORK1_2]]):
448 for vrf_name, network_vrf in zip(["RED", "GREEN"], network):
449 for addr_type in ADDR_TYPES:
450 static_routes = {
451 dut: {
452 "static_routes": [
453 {
454 "network": [network_vrf[addr_type]],
455 "next_hop": "blackhole",
456 "vrf": vrf_name
457 }
458 ]
459 }
460 }
461 result = verify_bgp_rib(tgen, addr_type, dut, static_routes)
462 assert result is True, "Testcase {} : Failed \n Error {}". \
463 format(tc_name, result)
464
465 step("Import vrf RED's route in vrf GREEN on R3")
466 temp = {}
467 for addr_type in ADDR_TYPES:
468 temp.update({
469 addr_type: {
470 "unicast": {
471 "import": {
472 "vrf": "RED"
473 }
474 }
475 }
476 })
477
478 import_dict = {"r3": {"bgp": [{
479 "vrf": "GREEN", "local_as": 3, "address_family": temp
480 }]}}
481
482 result = create_router_bgp(tgen, topo, import_dict)
483 assert result is True, "Testcase {} :Failed \n Error: {}". \
484 format(tc_name, result)
485
486 step("Verify that locally imported routes are installed over eBGP imported"
487 " routes from VRF RED into VRF GREEN")
488 for addr_type in ADDR_TYPES:
489 static_routes = {
490 "r3": {
491 "static_routes": [
492 {
493 "network": [NETWORK1_2[addr_type]],
494 "next_hop": "blackhole",
495 "vrf": "GREEN"
496 }
497 ]
498 }
499 }
500
501 input_routes = {
502 "r3": {
503 addr_type: [
504 {
505 "network": NETWORK1_2[addr_type],
506 "bestpath": BESTPATH[addr_type],
507 "vrf": "GREEN"
508 }
509 ]
510 }
511 }
512
513 result = verify_bgp_bestpath(tgen, addr_type, input_routes)
514 assert result is True, "Testcase {} : Failed \n Error {}". \
515 format(tc_name, result)
516
517 result = verify_rib(tgen, addr_type, "r3", static_routes)
518 assert result is True, "Testcase {} : Failed \n Error {}". \
519 format(tc_name, result)
520
521 write_test_footer(tc_name)
522
523
524if __name__ == "__main__":
525 args = ["-s"] + sys.argv[1:]
526 sys.exit(pytest.main(args))