]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_nbr.py
Merge pull request #9551 from mobash-rasool/ospfv2-bug-fixes-04
[mirror_frr.git] / tests / topotests / bgp_ipv4_over_ipv6 / test_rfc5549_ibgp_nbr.py
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."""
25 import os
26 import sys
27 import time
28 import pytest
29 from copy import deepcopy
30
31 # Save the Current Working Directory to find configuration files.
32 CWD = os.path.dirname(os.path.realpath(__file__))
33 sys.path.append(os.path.join(CWD, "../"))
34 sys.path.append(os.path.join(CWD, "../../"))
35
36 # pylint: disable=C0413
37 # Import topogen and topotest helpers
38 from lib.topogen import Topogen, get_topogen
39
40 from lib.common_config import (
41 start_topology,
42 write_test_header,
43 addKernelRoute,
44 write_test_footer,
45 create_prefix_lists,
46 verify_rib,
47 create_static_routes,
48 reset_config_on_routers,
49 step,
50 create_route_maps,
51 get_frr_ipv6_linklocal,
52 )
53 from lib.topolog import logger
54 from lib.bgp import (
55 verify_bgp_convergence,
56 create_router_bgp,
57 verify_bgp_rib,
58 )
59 from lib.topojson import build_config_from_json
60
61 # Global variables
62 topo = None
63
64 # Global variables
65 NETWORK = {
66 "ipv4": [
67 "11.0.20.1/32",
68 "11.0.20.2/32",
69 "11.0.20.3/32",
70 "11.0.20.4/32",
71 "11.0.20.5/32",
72 ],
73 "ipv6": ["1::1/128", "1::2/128", "1::3/128", "1::4/128", "1::5/128"],
74 }
75 MASK = {"ipv4": "32", "ipv6": "128"}
76 NEXT_HOP = {
77 "ipv4": ["10.0.0.1", "10.0.1.1", "10.0.2.1", "10.0.3.1", "10.0.4.1"],
78 "ipv6": ["Null0", "Null0", "Null0", "Null0", "Null0"],
79 }
80 NETWORK_CMD_IP = "1.0.1.17/32"
81 NO_OF_RTES = 2
82 TOPOOLOGY = """
83 Please view in a fixed-width font such as Courier.
84
85 +----+
86 | R4 |
87 | |
88 +--+-+
89 | ipv4 nbr
90 no bgp ebgp/ibgp |
91 | ebgp/ibgp
92 +----+ 5links +----+ +--+-+ +----+
93 |R0 +----------+ R1 | | R2 | ipv6 nbr |R3 |
94 | +----------+ +------------+ +-------------+ |
95 +----+ +----+ ipv6 nbr +----+ +----+
96 """
97
98 TESTCASES = """
99 1. Verify IPv4 and IPv6 routes advertise using "redistribute static"
100 and "network command" are received on IBGP peer with IPv6 nexthop
101 2. Verify IPv4 routes are advertised and withdrawn when IPv6 IBGP session
102 established using loopback interface
103 3. Verify IPv4 routes are advertised to peer when static routes are
104 configured with ADMIN distance and tag option
105 4. Verify IPv4 routes advertised to peer when BGP session established
106 using link-local address
107 """
108
109
110 def setup_module(mod):
111 """Set up the pytest environment."""
112
113 global topo
114 testsuite_run_time = time.asctime(time.localtime(time.time()))
115 logger.info("Testsuite start time: {}".format(testsuite_run_time))
116 logger.info("=" * 40)
117
118 logger.info("Running setup_module to create topology")
119
120 # This function initiates the topology build with Topogen...
121 json_file = "{}/rfc5549_ibgp_nbr.json".format(CWD)
122 tgen = Topogen(json_file, mod.__name__)
123 global topo
124 topo = tgen.json_topo
125
126 # Starting topology, create tmp files which are loaded to routers
127 # to start deamons and then start routers
128 start_topology(tgen)
129
130 # Creating configuration from JSON
131 build_config_from_json(tgen, topo)
132 # Don't run this test if we have any failure.
133 if tgen.routers_have_failure():
134 pytest.skip(tgen.errors)
135
136 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
137 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format(
138 BGP_CONVERGENCE
139 )
140 logger.info("Running setup_module() done")
141
142
143 def teardown_module():
144 """Teardown the pytest environment."""
145 logger.info("Running teardown_module to delete topology")
146
147 tgen = get_topogen()
148
149 # Stop toplogy and Remove tmp files
150 tgen.stop_topology()
151
152
153 def get_llip(onrouter, intf):
154 """
155 API to get the link local ipv6 address of a perticular interface
156
157 Parameters
158 ----------
159 * `fromnode`: Source node
160 * `tonode` : interface for which link local ip needs to be returned.
161
162 Usage
163 -----
164 result = get_llip('r1', 'r2-link0')
165
166 Returns
167 -------
168 1) link local ipv6 address from the interface.
169 2) errormsg - when link local ip not found.
170 """
171 tgen = get_topogen()
172 intf = topo["routers"][onrouter]["links"][intf]["interface"]
173 llip = get_frr_ipv6_linklocal(tgen, onrouter, intf)
174
175 if llip:
176 logger.info("llip ipv6 address to be set as NH is %s", llip)
177 return llip
178 return None
179
180
181 def get_glipv6(onrouter, intf):
182 """
183 API to get the global ipv6 address of a perticular interface
184
185 Parameters
186 ----------
187 * `onrouter`: Source node
188 * `intf` : interface for which link local ip needs to be returned.
189
190 Usage
191 -----
192 result = get_glipv6('r1', 'r2-link0')
193
194 Returns
195 -------
196 1) global ipv6 address from the interface.
197 2) errormsg - when link local ip not found.
198 """
199 glipv6 = (topo["routers"][onrouter]["links"][intf]["ipv6"]).split("/")[0]
200 if glipv6:
201 logger.info("Global ipv6 address to be set as NH is %s", glipv6)
202 return glipv6
203 return None
204
205
206 # ##################################
207 # Test cases start here.
208 # ##################################
209
210
211 def test_ext_nh_cap_red_static_network_ibgp_peer_p1(request):
212 """
213
214 Test extended capability nexthop with ibgp peer.
215
216 Verify IPv4 and IPv6 routes advertise using "redistribute static"
217 and "network command" are received on IBGP peer with IPv6 nexthop
218 """
219 tc_name = request.node.name
220 write_test_header(tc_name)
221 tgen = get_topogen()
222 # Don't run this test if we have any failure.
223 if tgen.routers_have_failure():
224 pytest.skip(tgen.errors)
225 reset_config_on_routers(tgen)
226 step(
227 "Configure IPv6 EBGP session between R1 and R2 with global IPv6"
228 " address Enable capability extended-nexthop on the nbr from both"
229 " the routers"
230 )
231 step(
232 "Change ebgp to ibgp nbrs between r1 and r2 , Activate same IPv6"
233 " nbr from IPv4 unicast family "
234 )
235
236 step(
237 " Configure 5 IPv4 static routes"
238 " on R1 nexthop for static route exists on different link of R0"
239 )
240
241 for rte in range(0, NO_OF_RTES):
242 # Create Static routes
243 input_dict = {
244 "r1": {
245 "static_routes": [
246 {
247 "network": NETWORK["ipv4"][rte],
248 "no_of_ip": 1,
249 "next_hop": NEXT_HOP["ipv4"][rte],
250 }
251 ]
252 }
253 }
254 result = create_static_routes(tgen, input_dict)
255 assert result is True, "Testcase {} : Failed \n Error: {}".format(
256 tc_name, result
257 )
258 step(
259 "Advertise static routes from IPv4 unicast family and IPv6 unicast"
260 " family respectively from R1.Configure loopback on R1 with IPv4 addr"
261 " & Advertise loopback from IPv4 unicast family using network cmd "
262 " from R1"
263 )
264 # this test case needs ipv6 routes to be configured
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
285 glip = get_llip("r1", "r2-link0")
286 assert glip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
287
288 step(
289 "IPv4 and IPv6 routes advertised using static & network command are"
290 "received on R2 BGP and routing table , verify using show ip bgp"
291 "show ip route for IPv4 routes and show bgp, show ipv6 routes"
292 "for IPv6 routes ."
293 )
294
295 dut = "r2"
296 protocol = "bgp"
297 # verify the routes with nh as ext_nh
298 verify_nh_for_static_rtes = {
299 "r1": {
300 "static_routes": [
301 {
302 "network": NETWORK["ipv4"][0],
303 "no_of_ip": NO_OF_RTES,
304 "next_hop": glip,
305 }
306 ]
307 }
308 }
309 bgp_rib = verify_bgp_rib(
310 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=glip
311 )
312 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
313 result = verify_rib(
314 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=glip, protocol=protocol
315 )
316 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
317
318 step(
319 "Verify IPv4 routes are installed with IPv6 global nexthop of R1"
320 "R1 to R2 connected link"
321 )
322 verify_nh_for_nw_cmd_rtes = {
323 "r1": {
324 "static_routes": [
325 {
326 "network": NETWORK_CMD_IP,
327 "no_of_ip": 1,
328 "next_hop": glip,
329 }
330 ]
331 }
332 }
333 bgp_rib = verify_bgp_rib(
334 tgen, "ipv4", dut, verify_nh_for_nw_cmd_rtes, next_hop=glip
335 )
336 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
337 result = verify_rib(
338 tgen, "ipv4", dut, verify_nh_for_nw_cmd_rtes, next_hop=glip, protocol=protocol
339 )
340 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
341
342 write_test_footer(tc_name)
343
344
345 def test_ext_nh_cap_admin_dist_tag_ibgp_peer_p1(request):
346 """
347
348 Test extended capability nexthop with admin distance and route tag.
349
350 Verify IPv4 routes are advertised to peer when static routes
351 are configured with ADMIN distance and tag option
352 """
353 tc_name = request.node.name
354 write_test_header(tc_name)
355 tgen = get_topogen()
356 # Don't run this test if we have any failure.
357 if tgen.routers_have_failure():
358 pytest.skip(tgen.errors)
359 reset_config_on_routers(tgen)
360 step(
361 "Configure IPv6 EBGP session between R1 and R2 with global IPv6"
362 " address Enable capability extended-nexthop on the nbr from both"
363 " the routers"
364 )
365 step(
366 "Change ebgp to ibgp nbrs between r1 and r2 , Activate same IPv6"
367 " nbr from IPv4 unicast family "
368 )
369 step(
370 " Configure 5 IPv4 static routes"
371 " on R1 nexthop for static route exists on different link of R0"
372 )
373 count = 0
374 for rte in range(0, NO_OF_RTES):
375 count += 1
376 # Create Static routes
377 input_dict = {
378 "r1": {
379 "static_routes": [
380 {
381 "network": NETWORK["ipv4"][rte],
382 "no_of_ip": 1,
383 "next_hop": NEXT_HOP["ipv4"][rte],
384 "admin_distance": 100 + count,
385 "tag": 4001 + count,
386 }
387 ]
388 }
389 }
390 result = create_static_routes(tgen, input_dict)
391 assert result is True, "Testcase {} : Failed \n Error: {}".format(
392 tc_name, result
393 )
394 step(
395 "Advertise static routes from IPv4 unicast family & IPv6 unicast"
396 " family respectively from R1.Configure loopback on R1 with IPv4 "
397 "address & Advertise loopback from IPv4 unicast family "
398 "using network cmd from R1"
399 )
400 configure_bgp_on_r1 = {
401 "r1": {
402 "bgp": {
403 "address_family": {
404 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}}
405 }
406 }
407 }
408 }
409 result = create_router_bgp(tgen, topo, configure_bgp_on_r1)
410 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
411
412 glip = get_llip("r1", "r2-link0")
413 assert glip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
414
415 step(
416 "IPv4 and IPv6 routes advertised using static & network cmd are"
417 "received on R2 BGP and routing table , verify using show ip bgp"
418 "show ip route for IPv4 routes and show bgp, show ipv6 routes"
419 "for IPv6 routes ."
420 )
421
422 dut = "r2"
423 protocol = "bgp"
424 count = 0
425 # verify the routes with nh as ext_nh
426 verify_nh_for_static_rtes = {
427 "r1": {
428 "static_routes": [
429 {
430 "network": NETWORK["ipv4"][0],
431 "no_of_ip": NO_OF_RTES,
432 "next_hop": glip,
433 "admin_distance": 100 + count,
434 "tag": 4001 + count,
435 }
436 ]
437 }
438 }
439 bgp_rib = verify_bgp_rib(
440 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=glip
441 )
442 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
443 result = verify_rib(
444 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=glip, protocol=protocol
445 )
446 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
447 count = 0
448 for rte in range(0, NO_OF_RTES):
449 count += 10
450 input_dict_2 = {
451 "r3": {
452 "prefix_lists": {
453 "ipv4": {
454 "pf_list_1_ipv4": [
455 {
456 "seqid": 0 + count,
457 "action": "permit",
458 "network": NETWORK["ipv4"][rte],
459 }
460 ]
461 }
462 }
463 }
464 }
465 result = create_prefix_lists(tgen, input_dict_2)
466 assert result is True, "Testcase {} : Failed \n " "Error: {}".format(
467 tc_name, result
468 )
469
470 # Create route map
471 input_dict_6 = {
472 "r3": {
473 "route_maps": {
474 "rmap_match_tag_1_{}".format("ipv4"): [
475 {
476 "action": "deny",
477 "match": {
478 "ipv4": {"prefix_lists": "pf_list_1_{}".format("ipv4")}
479 },
480 }
481 ]
482 }
483 }
484 }
485 result = create_route_maps(tgen, input_dict_6)
486 assert result is True, "Testcase {} : Failed \n Error: {}".format(
487 tc_name, result
488 )
489
490 # Configure neighbor for route map
491 input_dict_7 = {
492 "r1": {
493 "bgp": {
494 "address_family": {
495 "ipv6": {
496 "unicast": {
497 "neighbor": {
498 "r2": {
499 "dest_link": {
500 "r1-link0": {
501 "route_maps": [
502 {
503 "name": "rmap_match_tag_1_ipv4",
504 "direction": "out",
505 }
506 ]
507 }
508 }
509 }
510 }
511 }
512 }
513 }
514 }
515 }
516 }
517
518 result = create_router_bgp(tgen, topo, input_dict_7)
519 assert result is True, "Testcase {} : Failed \n Error: {}".format(
520 tc_name, result
521 )
522
523 write_test_footer(tc_name)
524
525
526 def test_ibgp_loopback_nbr_p1(request):
527 """
528 Verify Extended capability nexthop with loopback interface.
529
530 Verify IPv4 routes are advertised and withdrawn when IPv6 IBGP
531 session established using loopback interface
532 """
533 tc_name = request.node.name
534 write_test_header(tc_name)
535 tgen = get_topogen()
536 # Don't run this test if we have any failure.
537 if tgen.routers_have_failure():
538 pytest.skip(tgen.errors)
539 global topo
540 topo1 = deepcopy(topo)
541 reset_config_on_routers(tgen)
542 step("Configure IPv6 global address between R1 and R2")
543 step(
544 "Configure loopback on R1 and R2 and establish EBGP session "
545 "between R1 and R2 over loopback global ip"
546 )
547 step("Configure static route on R1 and R2 for loopback reachability")
548 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
549
550 for routerN in ["r1", "r2"]:
551 for addr_type in ["ipv6"]:
552 for bgp_neighbor in topo1["routers"][routerN]["bgp"]["address_family"][
553 addr_type
554 ]["unicast"]["neighbor"].keys():
555 # Adding ['source_link'] = 'lo' key:value pair
556 if bgp_neighbor == "r1" or bgp_neighbor == "r2":
557 topo1["routers"][routerN]["bgp"]["address_family"][addr_type][
558 "unicast"
559 ]["neighbor"][bgp_neighbor]["dest_link"] = {
560 "lo": {
561 "source_link": "lo",
562 "ebgp_multihop": 2,
563 "capability": "extended-nexthop",
564 "activate": "ipv4",
565 }
566 }
567 # Creating configuration from JSON
568 build_config_from_json(tgen, topo1, save_bkup=False)
569
570 configure_bgp_on_r1 = {
571 "r1": {
572 "bgp": {
573 "address_family": {
574 "ipv6": {
575 "unicast": {
576 "neighbor": {
577 "r2": {
578 "dest_link": {"r1-link0": {"deactivate": "ipv6"}}
579 }
580 }
581 }
582 }
583 }
584 }
585 }
586 }
587 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
588 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
589
590 configure_bgp_on_r2 = {
591 "r2": {
592 "bgp": {
593 "address_family": {
594 "ipv6": {
595 "unicast": {
596 "neighbor": {
597 "r1": {
598 "dest_link": {"r2-link0": {"deactivate": "ipv6"}}
599 }
600 }
601 }
602 }
603 }
604 }
605 }
606 }
607 result = create_router_bgp(tgen, topo1, configure_bgp_on_r2)
608 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
609
610 configure_bgp_on_r1 = {
611 "r1": {
612 "bgp": {
613 "address_family": {
614 "ipv6": {
615 "unicast": {
616 "neighbor": {
617 "r2": {
618 "dest_link": {"r1-link0": {"deactivate": "ipv4"}}
619 }
620 }
621 }
622 }
623 }
624 }
625 }
626 }
627 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
628 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
629
630 configure_bgp_on_r2 = {
631 "r2": {
632 "bgp": {
633 "address_family": {
634 "ipv6": {
635 "unicast": {
636 "neighbor": {
637 "r1": {
638 "dest_link": {"r2-link0": {"deactivate": "ipv4"}}
639 }
640 }
641 }
642 }
643 }
644 }
645 }
646 }
647 result = create_router_bgp(tgen, topo1, configure_bgp_on_r2)
648 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
649 r2_lo_v4 = topo["routers"]["r2"]["links"]["lo"]["ipv4"]
650 r2_lo_v6 = topo["routers"]["r2"]["links"]["lo"]["ipv6"]
651 r1_lo_v4 = topo["routers"]["r1"]["links"]["lo"]["ipv4"]
652 r1_lo_v6 = topo["routers"]["r1"]["links"]["lo"]["ipv6"]
653 r1_r2_intf = topo["routers"]["r1"]["links"]["r2-link0"]["interface"]
654 r2_r1_intf = topo["routers"]["r2"]["links"]["r1-link0"]["interface"]
655
656 r1_r2_v6_nh = topo["routers"]["r1"]["links"]["r2-link0"]["ipv6"].split("/")[0]
657 r2_r1_v6_nh = topo["routers"]["r2"]["links"]["r1-link0"]["ipv6"].split("/")[0]
658
659 ipv4_list = [("r1", r1_r2_intf, [r2_lo_v4]), ("r2", r2_r1_intf, [r1_lo_v4])]
660
661 ipv6_list = [
662 ("r1", r1_r2_intf, [r2_lo_v6], r2_r1_v6_nh),
663 ("r2", r2_r1_intf, [r1_lo_v6], r1_r2_v6_nh),
664 ]
665
666 for dut, intf, loop_addr in ipv4_list:
667 result = addKernelRoute(tgen, dut, intf, loop_addr)
668 # assert result is True, "Testcase {}:Failed \n Error: {}". \
669 # format(tc_name, result)
670
671 for dut, intf, loop_addr, next_hop in ipv6_list:
672 result = addKernelRoute(tgen, dut, intf, loop_addr, next_hop)
673 # assert result is True, "Testcase {}:Failed \n Error: {}". \
674 # format(tc_name, result)
675
676 r2_lo_v4 = topo["routers"]["r2"]["links"]["lo"]["ipv4"]
677 r2_lo_v6 = topo["routers"]["r2"]["links"]["lo"]["ipv6"]
678 r1_lo_v4 = topo["routers"]["r1"]["links"]["lo"]["ipv4"]
679 r1_lo_v6 = topo["routers"]["r1"]["links"]["lo"]["ipv6"]
680 r1_r2_intf = topo["routers"]["r1"]["links"]["r2-link0"]["interface"]
681 r2_r1_intf = topo["routers"]["r2"]["links"]["r1-link0"]["interface"]
682
683 r1_r2_v6_nh = topo["routers"]["r1"]["links"]["r2-link0"]["ipv6"].split("/")[0]
684 r2_r1_v6_nh = topo["routers"]["r2"]["links"]["r1-link0"]["ipv6"].split("/")[0]
685
686 r1_r2_v4_nh = topo["routers"]["r1"]["links"]["r2-link0"]["ipv4"].split("/")[0]
687 r2_r1_v4_nh = topo["routers"]["r2"]["links"]["r1-link0"]["ipv4"].split("/")[0]
688
689 input_dict = {
690 "r1": {
691 "static_routes": [
692 {"network": r2_lo_v4, "next_hop": r2_r1_v4_nh},
693 {"network": r2_lo_v6, "next_hop": r2_r1_v6_nh},
694 ]
695 },
696 "r2": {
697 "static_routes": [
698 {"network": r1_lo_v4, "next_hop": r1_r2_v4_nh},
699 {"network": r1_lo_v6, "next_hop": r1_r2_v6_nh},
700 ]
701 },
702 }
703 result = create_static_routes(tgen, input_dict)
704 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
705
706 # Api call verify whether BGP is converged
707 result = verify_bgp_convergence(tgen, topo1)
708 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
709
710 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
711 configure_bgp_on_r1 = {
712 "r1": {
713 "default_ipv4_unicast": False,
714 "bgp": {
715 "address_family": {
716 "ipv6": {
717 "unicast": {
718 "neighbor": {
719 "r2": {
720 "dest_link": {
721 "lo": {
722 "activate": "ipv4",
723 "capability": "extended-nexthop",
724 }
725 }
726 }
727 }
728 }
729 }
730 }
731 },
732 }
733 }
734 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
735 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
736
737 configure_bgp_on_r2 = {
738 "r2": {
739 "default_ipv4_unicast": False,
740 "bgp": {
741 "address_family": {
742 "ipv6": {
743 "unicast": {
744 "neighbor": {
745 "r1": {
746 "dest_link": {
747 "lo": {
748 "activate": "ipv4",
749 "capability": "extended-nexthop",
750 }
751 }
752 }
753 }
754 }
755 }
756 }
757 },
758 }
759 }
760 result = create_router_bgp(tgen, topo1, configure_bgp_on_r2)
761 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
762
763 step("Verify bgp convergence.")
764 bgp_convergence = verify_bgp_convergence(tgen, topo1)
765 assert bgp_convergence is True, "Testcase {} : Failed \n Error: {}".format(
766 tc_name, bgp_convergence
767 )
768
769 step("Configure 2 IPv4 static" " routes on R1, Nexthop as different links of R0")
770
771 for rte in range(0, NO_OF_RTES):
772 # Create Static routes
773 input_dict = {
774 "r1": {
775 "static_routes": [
776 {
777 "network": NETWORK["ipv4"][rte],
778 "no_of_ip": 1,
779 "next_hop": NEXT_HOP["ipv4"][rte],
780 }
781 ]
782 }
783 }
784 result = create_static_routes(tgen, input_dict)
785 assert result is True, "Testcase {} : Failed \n Error: {}".format(
786 tc_name, result
787 )
788
789 step(
790 "Advertise static routes from IPv4 unicast family and IPv6 "
791 "unicast family respectively from R1 using red static cmd "
792 "Advertise loopback from IPv4 unicast family using network command "
793 "from R1"
794 )
795
796 configure_bgp_on_r1 = {
797 "r1": {
798 "bgp": {
799 "address_family": {
800 "ipv4": {
801 "unicast": {
802 "redistribute": [{"redist_type": "static"}],
803 "advertise_networks": [
804 {"network": NETWORK_CMD_IP, "no_of_network": 1}
805 ],
806 }
807 }
808 }
809 }
810 }
811 }
812 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
813 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
814
815 step(
816 "IPv4 routes advertised using static and network command are "
817 " received on R2 BGP and routing table , "
818 "verify using show ip bgp, show ip route for IPv4 routes ."
819 )
820
821 gllip = (topo1["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]).lower()
822 assert gllip is not None, "Testcase {} : Failed \n Error: {}".format(
823 tc_name, result
824 )
825
826 dut = "r2"
827 protocol = "bgp"
828 verify_nh_for_static_rtes = {
829 "r1": {
830 "static_routes": [
831 {
832 "network": NETWORK["ipv4"][0],
833 "no_of_ip": NO_OF_RTES,
834 "next_hop": gllip,
835 }
836 ]
837 }
838 }
839 bgp_rib = verify_bgp_rib(
840 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=gllip
841 )
842 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
843 result = verify_rib(
844 tgen, "ipv4", dut, verify_nh_for_static_rtes, next_hop=gllip, protocol=protocol
845 )
846 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
847
848 verify_nh_for_nw_rtes = {
849 "r1": {
850 "static_routes": [
851 {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": gllip}
852 ]
853 }
854 }
855 bgp_rib = verify_bgp_rib(tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=gllip)
856 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
857 result = verify_rib(
858 tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=gllip, protocol=protocol
859 )
860 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
861
862 step(
863 "Remove IPv4 routes advertised using network command"
864 " from R1 and advertise again"
865 )
866
867 configure_bgp_on_r1 = {
868 "r1": {
869 "bgp": {
870 "address_family": {
871 "ipv4": {
872 "unicast": {
873 "redistribute": [{"redist_type": "static"}],
874 "advertise_networks": [
875 {
876 "network": NETWORK_CMD_IP,
877 "no_of_network": 1,
878 "delete": True,
879 }
880 ],
881 }
882 }
883 }
884 }
885 }
886 }
887 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
888 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
889
890 configure_bgp_on_r1 = {
891 "r1": {
892 "bgp": {
893 "address_family": {
894 "ipv4": {
895 "unicast": {
896 "redistribute": [{"redist_type": "static"}],
897 "advertise_networks": [
898 {
899 "network": NETWORK_CMD_IP,
900 "no_of_network": 1,
901 }
902 ],
903 }
904 }
905 }
906 }
907 }
908 }
909 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
910 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
911 step(
912 "After removing IPv4 routes from network command , routes which are "
913 "advertised using redistribute static are still present in the on "
914 "R2 , verify using show ip bgp and show ip route"
915 )
916
917 verify_nh_for_nw_rtes = {
918 "r1": {
919 "static_routes": [
920 {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": gllip}
921 ]
922 }
923 }
924 bgp_rib = verify_bgp_rib(tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=gllip)
925 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
926 result = verify_rib(
927 tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=gllip, protocol=protocol
928 )
929 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
930
931 step(
932 "Remove IPv4 routes advertised using redistribute static"
933 " command from R1 and advertise again"
934 )
935
936 configure_bgp_on_r1 = {
937 "r1": {
938 "bgp": {
939 "address_family": {
940 "ipv4": {
941 "unicast": {
942 "redistribute": [{"redist_type": "static", "delete": True}]
943 }
944 }
945 }
946 }
947 }
948 }
949 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
950 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
951
952 configure_bgp_on_r1 = {
953 "r1": {
954 "bgp": {
955 "address_family": {
956 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}}
957 }
958 }
959 }
960 }
961 result = create_router_bgp(tgen, topo1, configure_bgp_on_r1)
962 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
963 step(
964 "After removing IPv4 routes from redistribute static , routes which"
965 " are advertised using network are still present in the on R2 , "
966 "verify using show ip bgp and show ip route"
967 )
968
969 verify_nh_for_nw_rtes = {
970 "r1": {
971 "static_routes": [
972 {"network": NETWORK_CMD_IP, "no_of_ip": 1, "next_hop": gllip}
973 ]
974 }
975 }
976 bgp_rib = verify_bgp_rib(tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=gllip)
977 assert bgp_rib is True, "Testcase {} : Failed \n Error: {}".format(tc_name, bgp_rib)
978 result = verify_rib(
979 tgen, "ipv4", dut, verify_nh_for_nw_rtes, next_hop=gllip, protocol=protocol
980 )
981 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
982 write_test_footer(tc_name)
983
984
985 if __name__ == "__main__":
986 args = ["-s"] + sys.argv[1:]
987 sys.exit(pytest.main(args))