]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py
Merge pull request #10942 from opensourcerouting/feature/printfrr_extension_for_peer_...
[mirror_frr.git] / tests / topotests / bgp_ipv4_over_ipv6 / test_rfc5549_ebgp_unnumbered_nbr.py
CommitLineData
9e3bab5f 1#!/usr/bin/env python
2
3#
4# Copyright (c) 2021 by VMware, Inc. ("VMware")
5# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
6# ("NetDEF") in this file.
7#
8# Permission to use, copy, modify, and/or distribute this software
9# for any purpose with or without fee is hereby granted, provided
10# that the above copyright notice and this permission notice appear
11# in all copies.
12#
13# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20# OF THIS SOFTWARE.
21#
22
23
24"""RFC5549 Automation."""
25import os
26import sys
27import time
9e3bab5f 28import pytest
9e3bab5f 29
30# Save the Current Working Directory to find configuration files.
31CWD = os.path.dirname(os.path.realpath(__file__))
32sys.path.append(os.path.join(CWD, "../"))
33sys.path.append(os.path.join(CWD, "../../"))
34
35from lib.topogen import Topogen, get_topogen
9e3bab5f 36
37from lib.common_config import (
38 write_test_header,
39 start_topology,
9e3bab5f 40 write_test_footer,
41 start_router,
42 stop_router,
43 verify_rib,
44 create_static_routes,
45 check_address_types,
46 reset_config_on_routers,
47 step,
9e3bab5f 48 get_frr_ipv6_linklocal,
49)
50from lib.topolog import logger
4953ca97 51from lib.bgp import create_router_bgp, verify_bgp_convergence, verify_bgp_rib
9e3bab5f 52
4953ca97 53from lib.topojson import build_config_from_json
9e3bab5f 54
55# Global variables
56topo = None
9e3bab5f 57
58# Global variables
59NO_OF_RTES = 2
60NETWORK_CMD_IP = "1.0.1.17/32"
61NETWORK = {
62 "ipv4": [
63 "11.0.20.1/32",
64 "11.0.20.2/32",
65 "11.0.20.3/32",
66 "11.0.20.4/32",
67 "11.0.20.5/32",
68 ],
69 "ipv6": ["1::1/128", "1::2/128", "1::3/128", "1::4/128", "1::5/128"],
70}
71MASK = {"ipv4": "32", "ipv6": "128"}
72NEXT_HOP = {
73 "ipv4": ["10.0.0.1", "10.0.1.1", "10.0.2.1", "10.0.3.1", "10.0.4.1"],
74 "ipv6": ["Null0", "Null0", "Null0", "Null0", "Null0"],
75}
76INTF_LIST = [
77 "r2-link0",
78 "r2-link1",
79 "r2-link2",
80 "r2-link3",
81 "r2-link4",
82 "r2-link5",
83 "r2-link6",
84 "r2-link7",
85]
86ADDR_TYPES = check_address_types()
87TOPOOLOGY = """
88 Please view in a fixed-width font such as Courier.
89
90 +----+
91 | R4 |
92 | |
93 +--+-+
94 | ipv4 nbr
95 no bgp ebgp/ibgp |
96 | ebgp/ibgp
97 +----+ 5links +----+ 8links +--+-+ +----+
98 |R0 +----------+ R1 +------------+ R2 | ipv6 nbr |R3 |
99 | +----------+ +------------+ +-------------+ |
100 +----+ +----+ ipv6 nbr +----+ +----+
101"""
102
103TESTCASES = """
1041. Verify IPv4 routes are advertised when IPv6 EBGP loopback session
105 established using Unnumbered interface
1062. Verify IPv4 routes are installed with correct nexthop after
107shut / no shut of nexthop and BGP peer interfaces
1083. Verify IPv4 routes are intact after stop and start the FRR services
109 """
110
111
9e3bab5f 112def setup_module(mod):
113 """Set up the pytest environment."""
114 global topo, ADDR_TYPES
115
116 testsuite_run_time = time.asctime(time.localtime(time.time()))
117 logger.info("Testsuite start time: {}".format(testsuite_run_time))
118 logger.info("=" * 40)
119
120 logger.info("Running setup_module to create topology")
121
122 # This function initiates the topology build with Topogen...
e82b531d
CH
123 json_file = "{}/rfc5549_ebgp_unnumbered_nbr.json".format(CWD)
124 tgen = Topogen(json_file, mod.__name__)
125 global topo
126 topo = tgen.json_topo
9e3bab5f 127
128 # Starting topology, create tmp files which are loaded to routers
129 # to start deamons and then start routers
130 start_topology(tgen)
131
132 # Creating configuration from JSON
133 build_config_from_json(tgen, topo)
134 # Don't run this test if we have any failure.
135 if tgen.routers_have_failure():
136 pytest.skip(tgen.errors)
137
138 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
139 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format(
140 BGP_CONVERGENCE
141 )
142 logger.info("Running setup_module() done")
143
144
145def teardown_module():
146 """Teardown the pytest environment."""
147 logger.info("Running teardown_module to delete topology")
148
149 tgen = get_topogen()
150
151 # Stop toplogy and Remove tmp files
152 tgen.stop_topology()
153
154
155def get_llip(onrouter, intf):
156 """
157 API to get the link local ipv6 address of a perticular interface
158
159 Parameters
160 ----------
161 * `fromnode`: Source node
162 * `tonode` : interface for which link local ip needs to be returned.
163
164 Usage
165 -----
166 result = get_llip('r1', 'r2-link0')
167
168 Returns
169 -------
170 1) link local ipv6 address from the interface.
171 2) errormsg - when link local ip not found.
172 """
173 tgen = get_topogen()
174 intf = topo["routers"][onrouter]["links"][intf]["interface"]
175 llip = get_frr_ipv6_linklocal(tgen, onrouter, intf)
176 if llip:
177 logger.info("llip ipv6 address to be set as NH is %s", llip)
178 return llip
179 return None
180
181
182def get_glipv6(onrouter, intf):
183 """
184 API to get the global ipv6 address of a perticular interface
185
186 Parameters
187 ----------
188 * `onrouter`: Source node
189 * `intf` : interface for which link local ip needs to be returned.
190
191 Usage
192 -----
193 result = get_glipv6('r1', 'r2-link0')
194
195 Returns
196 -------
197 1) global ipv6 address from the interface.
198 2) errormsg - when link local ip not found.
199 """
200 glipv6 = (topo["routers"][onrouter]["links"][intf]["ipv6"]).split("/")[0]
201 if glipv6:
202 logger.info("Global ipv6 address to be set as NH is %s", glipv6)
203 return glipv6
204 return None
205
206
207# ##################################
208# Test cases start here.
209# ##################################
210
211
212def test_unnumbered_loopback_ebgp_nbr_p0(request):
213 """
214
215 Test extended capability nexthop with un numbered ebgp.
216
217 Verify IPv4 routes are advertised when IPv6 EBGP loopback
218 session established using Unnumbered interface
219 """
220 tc_name = request.node.name
221 write_test_header(tc_name)
222 tgen = get_topogen()
223 # Don't run this test if we have any failure.
224 if tgen.routers_have_failure():
225 pytest.skip(tgen.errors)
226 reset_config_on_routers(tgen)
227
228 step("Configure IPv6 EBGP Unnumbered session between R1 and R2")
229 step("Enable capability extended-nexthop on both the IPv6 BGP peers")
230 step("Activate same IPv6 nbr from IPv4 unicast family")
231 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
232 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
233
234 bgp_convergence = verify_bgp_convergence(tgen, topo)
235 assert bgp_convergence is True, "Testcase {} :Failed \n Error: {}".format(
236 tc_name, bgp_convergence
237 )
238
239 step(" Configure 5 IPv4 static" " routes on R1, Nexthop as different links of R0")
240 for rte in range(0, NO_OF_RTES):
241 # Create Static routes
242 input_dict = {
243 "r1": {
244 "static_routes": [
245 {
246 "network": NETWORK["ipv4"][rte],
247 "no_of_ip": 1,
248 "next_hop": NEXT_HOP["ipv4"][rte],
249 }
250 ]
251 }
252 }
253 result = create_static_routes(tgen, input_dict)
254 assert result is True, "Testcase {} : Failed \n Error: {}".format(
255 tc_name, result
256 )
257
258 step(
259 "Advertise static routes from IPv4 unicast family and IPv6 "
260 "unicast family respectively from R1 using red static cmd "
261 "Advertise loopback from IPv4 unicast family using network command "
262 "from R1"
263 )
264
265 configure_bgp_on_r1 = {
266 "r1": {
267 "bgp": {
268 "address_family": {
269 "ipv4": {
270 "unicast": {
271 "redistribute": [{"redist_type": "static"}],
272 "advertise_networks": [
273 {"network": NETWORK_CMD_IP, "no_of_network": 1}
274 ],
275 }
276 },
277 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
278 }
279 }
280 }
281 }
282 result = create_router_bgp(tgen, topo, configure_bgp_on_r1)
283 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
284 step(
285 "IPv4 routes advertised using static and network command are "
286 " received on R2 BGP and routing table , "
287 "verify using show ip bgp, show ip route for IPv4 routes ."
288 )
289
290 llip = get_llip("r1", "r2-link0")
291 assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, llip)
292
293 dut = "r2"
294 protocol = "bgp"
295 for rte in range(0, NO_OF_RTES):
296 # verify the routes with nh as ext_nh
297 verify_nh_for_static_rtes = {
298 "r1": {
299 "static_routes": [
300 {"network": NETWORK["ipv4"][rte], "no_of_ip": 1, "next_hop": llip}
301 ]
302 }
303 }
304 """ interface_list = ['r1-link0','r1-link1']
305 nh_list =[]
306 for i in range(NO_OF_RTES):
307 nh_list.append(topo['routers']['r2']['links'][i][
308 'interface']) """
309 bgp_rib = verify_rib(
310 tgen,
311 "ipv4",
312 dut,
313 # verify_nh_for_static_rtes, next_hop='r2-r1-eth0')
314 verify_nh_for_static_rtes,
315 next_hop=llip,
316 )
317 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(
318 tc_name, bgp_rib
319 )
320 result = verify_rib(
321 tgen,
322 "ipv4",
323 dut,
324 verify_nh_for_static_rtes,
325 next_hop=llip,
326 protocol=protocol,
327 )
328 assert result is True, "Testcase {} : Failed \n Error: {}".format(
329 tc_name, result
330 )
331
332 # verify the routes with nh as ext_nh
333 verify_nh_for_nw_rtes = {
334 "r1": {
335 "static_routes": [
336 {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": llip}
337 ]
338 }
339 }
340
341 bgp_rib = verify_rib(
342 tgen,
343 "ipv4",
344 dut,
345 # verify_nh_for_nw_rtes, next_hop='r2-r1-eth0')
346 verify_nh_for_nw_rtes,
347 next_hop=llip,
348 )
349 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
350 result = verify_rib(
351 tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip, protocol=protocol
352 )
353 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
354 # stop/start -> restart FRR router and verify
355 stop_router(tgen, "r1")
356 stop_router(tgen, "r2")
357 start_router(tgen, "r1")
358 start_router(tgen, "r2")
359 step(
360 "After stop/start of FRR services , verify session up and routes "
361 "came up fine ,nh is proper using show bgp & show ipv6 route on R2 "
362 )
363 bgp_convergence = verify_bgp_convergence(tgen, topo)
364 assert bgp_convergence is True, "Testcase {} :Failed \n Error: {}".format(
365 tc_name, bgp_convergence
366 )
367
368 llip = get_llip("r1", "r2-link0")
369 assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
370
371 # verify the routes with nh as ext_nh
372 verify_nh_for_static_rtes = {
373 "r1": {
374 "static_routes": [
375 {
376 "network": NETWORK["ipv4"][0],
377 "no_of_ip": NO_OF_RTES,
378 "next_hop": llip,
379 }
380 ]
381 }
382 }
383 bgp_rib = verify_bgp_rib(
384 tgen,
385 "ipv4",
386 dut,
387 # verify_nh_for_static_rtes, next_hop='r2-r1-eth0')
388 verify_nh_for_static_rtes,
389 next_hop=llip,
390 )
391 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
392 result = verify_rib(
393 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip, protocol=protocol
394 )
395 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
396
397 verify_nh_for_nw_rtes = {
398 "r1": {
399 "static_routes": [
400 {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": llip}
401 ]
402 }
403 }
404 bgp_rib = verify_rib(
405 tgen,
406 "ipv4",
407 dut,
408 # verify_nh_for_nw_rtes, next_hop='r2-r1-eth0')
409 verify_nh_for_nw_rtes,
410 next_hop=llip,
411 )
412 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
413 result = verify_rib(
414 tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip, protocol=protocol
415 )
416 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
417 write_test_footer(tc_name)
418
419
420def test_restart_frr_p2(request):
421 """
422
423 Test extended capability nexthop , restart frr.
424
425 Verify IPv4 routes are intact after stop and start the FRR services
426 """
427 tc_name = request.node.name
428 write_test_header(tc_name)
429 tgen = get_topogen()
430 # Don't run this test if we have any failure.
431 if tgen.routers_have_failure():
432 pytest.skip(tgen.errors)
433 reset_config_on_routers(tgen)
434 step("Configure IPv6 EBGP Unnumbered session between R1 and R2")
435 step("Enable capability extended-nexthop on both the IPv6 BGP peers")
436 step("Activate same IPv6 nbr from IPv4 unicast family")
437 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
438 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
439 reset_config_on_routers(tgen)
440 bgp_convergence = verify_bgp_convergence(tgen, topo)
441 assert bgp_convergence is True, "Testcase {} :Failed \n Error: {}".format(
442 tc_name, bgp_convergence
443 )
444
445 step(" Configure 5 IPv4 static" " routes on R1, Nexthop as different links of R0")
446 for rte in range(0, NO_OF_RTES):
447 # Create Static routes
448 input_dict = {
449 "r1": {
450 "static_routes": [
451 {
452 "network": NETWORK["ipv4"][rte],
453 "no_of_ip": 1,
454 "next_hop": NEXT_HOP["ipv4"][rte],
455 }
456 ]
457 }
458 }
459 result = create_static_routes(tgen, input_dict)
460 assert result is True, "Testcase {} : Failed \n Error: {}".format(
461 tc_name, result
462 )
463
464 step(
465 "Advertise static routes from IPv4 unicast family and IPv6 "
466 "unicast family respectively from R1 using red static cmd "
467 "Advertise loopback from IPv4 unicast family using network command "
468 "from R1"
469 )
470
471 configure_bgp_on_r1 = {
472 "r1": {
473 "bgp": {
474 "address_family": {
475 "ipv4": {
476 "unicast": {
477 "redistribute": [{"redist_type": "static"}],
478 "advertise_networks": [
479 {"network": NETWORK_CMD_IP, "no_of_network": 1}
480 ],
481 }
482 },
483 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
484 }
485 }
486 }
487 }
488 result = create_router_bgp(tgen, topo, configure_bgp_on_r1)
489 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
490 step(
491 "IPv4 routes advertised using static and network command are "
492 " received on R2 BGP and routing table , "
493 "verify using show ip bgp, show ip route for IPv4 routes ."
494 )
495
496 llip = get_llip("r1", "r2-link0")
497 assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
498
499 dut = "r2"
500 protocol = "bgp"
501 verify_nh_for_static_rtes = {
502 "r1": {
503 "static_routes": [
504 {
505 "network": NETWORK["ipv4"][0],
506 "no_of_ip": NO_OF_RTES,
507 "next_hop": llip,
508 }
509 ]
510 }
511 }
512 bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip)
513 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
514 result = verify_rib(
515 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip, protocol=protocol
516 )
517 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
518
519 verify_nh_for_nw_rtes = {
520 "r1": {
521 "static_routes": [
522 {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": llip}
523 ]
524 }
525 }
526
527 bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip)
528 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
529 result = verify_rib(
530 tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip, protocol=protocol
531 )
532 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
533
534 # stop/start -> restart FRR router and verify
535 stop_router(tgen, "r1")
536 stop_router(tgen, "r2")
537 start_router(tgen, "r1")
538 start_router(tgen, "r2")
539
540 step(
541 "After stop/start of FRR services , verify session up and routes "
542 "came up fine ,nh is proper using show bgp & show ipv6 route on R2 "
543 )
544 bgp_convergence = verify_bgp_convergence(tgen, topo)
545 assert bgp_convergence is True, "Testcase {} :Failed \n Error: {}".format(
546 tc_name, bgp_convergence
547 )
548
549 llip = get_llip("r1", "r2-link0")
550 assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
551
552 # verify the routes with nh as ext_nh
553 verify_nh_for_static_rtes = {
554 "r1": {
555 "static_routes": [
556 {"network": NETWORK["ipv4"][0], "no_of_ip": 1, "next_hop": llip}
557 ]
558 }
559 }
560 bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip)
561 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
562 result = verify_rib(
563 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=llip, protocol=protocol
564 )
565 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
566
567 # verify the routes with nh as ext_nh
568 verify_nh_for_nw_rtes = {
569 "r1": {
570 "static_routes": [
571 {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": llip}
572 ]
573 }
574 }
575 bgp_rib = verify_rib(tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip)
576 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
577 result = verify_rib(
578 tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=llip, protocol=protocol
579 )
580 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
581 write_test_footer(tc_name)
582
583
584if __name__ == "__main__":
585 args = ["-s"] + sys.argv[1:]
586 sys.exit(pytest.main(args))