]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / tests / topotests / bgp_recursive_route_ebgp_multi_hop / test_bgp_recursive_route_ebgp_multi_hop.py
1 #!/usr/bin/python
2 #
3 # Copyright (c) 2020 by VMware, Inc. ("VMware")
4 # Used Copyright (c) 2018 by Network Device Education Foundation,
5 # Inc. ("NetDEF") in this file.
6 #
7 # Permission to use, copy, modify, and/or distribute this software
8 # for any purpose with or without fee is hereby granted, provided
9 # that the above copyright notice and this permission notice appear
10 # in all copies.
11 #
12 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
15 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
16 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
18 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
19 # OF THIS SOFTWARE.
20 #
21
22 """
23 Following tests are covered to test bgp recursive route and ebgp
24 multi-hop functionality:
25
26 1. Verify that BGP routes are installed in iBGP peer, only when there
27 is a recursive route for next-hop reachability.
28 2. Verify that any BGP prefix received with next hop as self-ip is
29 not installed in BGP RIB or FIB table.
30 3. Verify password authentication for eBGP and iBGP peers.
31 4. Verify that for a BGP prefix next-hop information doesn't change
32 when same prefix is received from another peer via recursive lookup.
33 5. Verify that BGP path attributes are present in CLI outputs and
34 JSON format, even if set to default.
35 6. Verifying the BGP peering between loopback and physical link's IP
36 of 2 peer routers.
37 7. Verify that BGP Active/Standby/Pre-emption/ECMP.
38 """
39
40 import os
41 import sys
42 import time
43 import pytest
44 from time import sleep
45
46 # Save the Current Working Directory to find configuration files.
47 CWD = os.path.dirname(os.path.realpath(__file__))
48 sys.path.append(os.path.join(CWD, "../"))
49
50 # pylint: disable=C0413
51 # Import topogen and topotest helpers
52 from lib.topogen import Topogen, get_topogen
53
54 # Import topoJson from lib, to create topology and initial configuration
55 from lib.common_config import (
56 start_topology,
57 write_test_header,
58 apply_raw_config,
59 write_test_footer,
60 reset_config_on_routers,
61 verify_rib,
62 create_static_routes,
63 check_address_types,
64 step,
65 create_route_maps,
66 create_interface_in_kernel,
67 shutdown_bringup_interface,
68 )
69 from lib.topolog import logger
70 from lib.bgp import (
71 verify_bgp_convergence,
72 create_router_bgp,
73 verify_bgp_rib,
74 verify_bgp_convergence_from_running_config,
75 modify_as_number,
76 verify_bgp_attributes,
77 clear_bgp,
78 )
79 from lib.topojson import build_config_from_json
80
81
82 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
83
84
85 # Global variables
86 BGP_CONVERGENCE = False
87 KEEP_ALIVE_TIMER = 2
88 HOLD_DOWN_TIMER = 6
89 ADDR_TYPES = check_address_types()
90 NETWORK = {
91 "ipv4": ["100.1.1.1/32", "100.1.1.2/32"],
92 "ipv6": ["100::1/128", "100::2/128"],
93 }
94
95 RECUR_NEXT_HOP = {
96 "N1": {"ipv4": "20.20.20.20/24", "ipv6": "20:20::20:20/120"},
97 "N2": {"ipv4": "30.30.30.30/24", "ipv6": "30:30::30:30/120"},
98 "N3": {"ipv4": "40.40.40.40/24", "ipv6": "40:40::40:40/120"},
99 }
100
101 CHANGED_NEXT_HOP = {
102 "4thOctate": {"ipv4": "10.0.1.250/24", "ipv6": "fd00:0:0:1::100/64"},
103 "3rdOctate": {"ipv4": "10.0.10.2/24", "ipv6": "fd00:0:0:10::2/64"},
104 }
105
106 Loopabck_IP = {
107 "Lo_R1": {"ipv4": "1.1.1.1/32", "ipv6": "1:1::1:1/128"},
108 "Lo_R4": {"ipv4": "4.4.4.4/32", "ipv6": "4:4::4:4/128"},
109 }
110
111
112 def setup_module(mod):
113 """
114 Sets up the pytest environment
115
116 * `mod`: module name
117 """
118
119 testsuite_run_time = time.asctime(time.localtime(time.time()))
120 logger.info("Testsuite start time: {}".format(testsuite_run_time))
121 logger.info("=" * 40)
122
123 logger.info("Running setup_module to create topology")
124
125 # This function initiates the topology build with Topogen...
126 json_file = "{}/bgp_recursive_route_ebgp_multi_hop.json".format(CWD)
127 tgen = Topogen(json_file, mod.__name__)
128 global topo
129 topo = tgen.json_topo
130 # ... and here it calls Mininet initialization functions.
131
132 # Starting topology, create tmp files which are loaded to routers
133 # to start daemons and then start routers
134 start_topology(tgen)
135
136 # Creating configuration from JSON
137 build_config_from_json(tgen, topo)
138
139 global BGP_CONVERGENCE
140 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
141 assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error : {}".format(
142 BGP_CONVERGENCE
143 )
144
145 logger.info("Running setup_module() done")
146
147
148 def teardown_module():
149 """Teardown the pytest environment"""
150
151 logger.info("Running teardown_module to delete topology")
152
153 tgen = get_topogen()
154
155 # Stop toplogy and Remove tmp files
156 tgen.stop_topology()
157
158 logger.info(
159 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
160 )
161 logger.info("=" * 40)
162
163
164 #####################################################
165 #
166 # Tests starting
167 #
168 #####################################################
169
170
171 def test_recursive_routes_iBGP_peer_p1(request):
172 """
173 Verify that BGP routes are installed in iBGP peer, only
174 when there is a recursive route for next-hop reachability.
175 """
176
177 tc_name = request.node.name
178 write_test_header(tc_name)
179 tgen = get_topogen()
180
181 # Don"t run this test if we have any failure.
182 if tgen.routers_have_failure():
183 pytest.skip(tgen.errors)
184
185 step("Initial config :Configure BGP neighborship between R1 and R3.")
186 reset_config_on_routers(tgen)
187
188 dut = "r1"
189 protocol = "static"
190
191 step(
192 "Configure static routes on R1 pointing next-hop as connected"
193 "link between R1 & R3's IP"
194 )
195 for addr_type in ADDR_TYPES:
196 input_dict_4 = {
197 "r1": {
198 "static_routes": [
199 {
200 "network": NETWORK[addr_type],
201 "next_hop": topo["routers"]["r3"]["links"]["r1"][
202 addr_type
203 ].split("/")[0],
204 }
205 ]
206 }
207 }
208 result = create_static_routes(tgen, input_dict_4)
209
210 step(
211 "Verify on router R1 that these static routes are "
212 "installed in RIB+FIB of R1"
213 )
214 result = verify_rib(
215 tgen,
216 addr_type,
217 dut,
218 input_dict_4,
219 next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
220 protocol=protocol,
221 )
222 assert result is True, "Testcase {} : Failed \n Error : {}".format(
223 tc_name, result
224 )
225
226 step("Redistribute these static routes in BGP on router R1")
227 input_dict_2 = {
228 "r1": {
229 "bgp": {
230 "address_family": {
231 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
232 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
233 }
234 }
235 }
236 }
237 result = create_router_bgp(tgen, topo, input_dict_2)
238
239 step(
240 "Verify on router R1 that these static routes are installed"
241 "in RIB table as well"
242 )
243 for addr_type in ADDR_TYPES:
244 input_dict_4 = {
245 "r1": {
246 "static_routes": [
247 {
248 "network": NETWORK[addr_type],
249 "next_hop": topo["routers"]["r3"]["links"]["r1"][
250 addr_type
251 ].split("/")[0],
252 }
253 ]
254 }
255 }
256 result = verify_bgp_rib(
257 tgen,
258 addr_type,
259 dut,
260 input_dict_4,
261 next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
262 )
263 assert result is True, "Testcase {}: Failed \n Error : {}".format(
264 tc_name, result
265 )
266
267 step(
268 "Configure a static routes for next hop IP on R2 via multiple"
269 "recursive static routes"
270 )
271 dut = "r2"
272 create_interface_in_kernel(
273 tgen, dut, "lo", "40.40.40.50", netmask="255.255.255.0", create=True
274 )
275 create_interface_in_kernel(
276 tgen, dut, "lo", "40:40::40:50", netmask="120", create=True
277 )
278 for addr_type in ADDR_TYPES:
279 input_dict_3 = {
280 "r2": {
281 "static_routes": [
282 {
283 "network": topo["routers"]["r3"]["links"]["r1"][addr_type],
284 "next_hop": RECUR_NEXT_HOP["N1"][addr_type].split("/")[0],
285 },
286 {
287 "network": RECUR_NEXT_HOP["N1"][addr_type],
288 "next_hop": RECUR_NEXT_HOP["N2"][addr_type].split("/")[0],
289 },
290 {
291 "network": RECUR_NEXT_HOP["N2"][addr_type],
292 "next_hop": RECUR_NEXT_HOP["N3"][addr_type].split("/")[0],
293 },
294 ]
295 }
296 }
297 result = create_static_routes(tgen, input_dict_3)
298 assert result is True, "Testcase {}: Failed \n Error : {}".format(
299 tc_name, result
300 )
301
302 step("verify if redistributed routes are now installed in FIB of R2")
303 result = verify_rib(
304 tgen,
305 addr_type,
306 "r2",
307 input_dict_4,
308 next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
309 protocol="bgp",
310 )
311 assert result is True, "Testcase {}: Failed \n Error : {}".format(
312 tc_name, result
313 )
314
315 step("Delete 1 route from static recursive for the next-hop IP")
316 dut = "r2"
317 for addr_type in ADDR_TYPES:
318 input_dict_3 = {
319 "r2": {
320 "static_routes": [
321 {
322 "network": RECUR_NEXT_HOP["N1"][addr_type],
323 "next_hop": RECUR_NEXT_HOP["N2"][addr_type].split("/")[0],
324 "delete": True,
325 }
326 ]
327 }
328 }
329 result = create_static_routes(tgen, input_dict_3)
330 assert result is True, "Testcase {}: Failed \n Error : {}".format(
331 tc_name, result
332 )
333
334 step("Verify that redistributed routes are withdrawn from FIB of R2")
335 result = verify_rib(
336 tgen,
337 addr_type,
338 dut,
339 input_dict_4,
340 next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
341 protocol="bgp",
342 expected=False,
343 )
344 assert (
345 result is not True
346 ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format(
347 tc_name, result
348 )
349
350 step("Reconfigure the same static route on R2 again")
351 dut = "r2"
352 for addr_type in ADDR_TYPES:
353 input_dict_3 = {
354 "r2": {
355 "static_routes": [
356 {
357 "network": RECUR_NEXT_HOP["N1"][addr_type],
358 "next_hop": RECUR_NEXT_HOP["N2"][addr_type].split("/")[0],
359 }
360 ]
361 }
362 }
363 result = create_static_routes(tgen, input_dict_3)
364 assert result is True, "Testcase {}: Failed \n Error : {}".format(
365 tc_name, result
366 )
367
368 step("Verify that redistributed routes are again installed" "in FIB of R2")
369 result = verify_rib(
370 tgen,
371 addr_type,
372 dut,
373 input_dict_4,
374 next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
375 protocol="bgp",
376 )
377 assert result is True, "Testcase {}: Failed \n Error : {}".format(
378 tc_name, result
379 )
380
381 step("Configure static route with changed next-hop from same subnet")
382 for addr_type in ADDR_TYPES:
383 input_dict_4 = {
384 "r1": {
385 "static_routes": [
386 {
387 "network": NETWORK[addr_type],
388 "next_hop": topo["routers"]["r3"]["links"]["r1"][
389 addr_type
390 ].split("/")[0],
391 "delete": True,
392 },
393 {
394 "network": NETWORK[addr_type],
395 "next_hop": CHANGED_NEXT_HOP["4thOctate"][addr_type].split("/")[
396 0
397 ],
398 },
399 ]
400 }
401 }
402 result = create_static_routes(tgen, input_dict_4)
403 assert result is True, "Testcase {}: Failed \n Error : {}".format(
404 tc_name, result
405 )
406
407 result = verify_rib(tgen, addr_type, "r1", input_dict_4, protocol="static")
408 assert result is True, "Testcase {} : Failed \n Error : {}".format(
409 tc_name, result
410 )
411
412 step(
413 "Verify that redistributed routes are not withdrawn as changed"
414 "next-hop IP, belongs to the same subnet"
415 )
416 result = verify_rib(tgen, addr_type, "r2", input_dict_4, protocol="bgp")
417 assert result is True, "Testcase {} : Failed \n Error : {}".format(
418 tc_name, result
419 )
420
421 step("Configure static route with changed next-hop from different subnet")
422 dut = "r1"
423 create_interface_in_kernel(
424 tgen, dut, "lo10", "10.0.10.10", netmask="255.255.255.0", create=True
425 )
426 create_interface_in_kernel(
427 tgen, dut, "lo10", "fd00:0:0:10::104", netmask="64", create=True
428 )
429 for addr_type in ADDR_TYPES:
430 input_dict_4 = {
431 "r1": {
432 "static_routes": [
433 {
434 "network": NETWORK[addr_type],
435 "next_hop": CHANGED_NEXT_HOP["4thOctate"][addr_type].split("/")[
436 0
437 ],
438 "delete": True,
439 },
440 {
441 "network": NETWORK[addr_type],
442 "next_hop": CHANGED_NEXT_HOP["3rdOctate"][addr_type].split("/")[
443 0
444 ],
445 },
446 ]
447 }
448 }
449 result = create_static_routes(tgen, input_dict_4)
450 assert result is True, "Testcase {}: Failed \n Error : {}".format(
451 tc_name, result
452 )
453
454 result = verify_rib(tgen, addr_type, "r1", input_dict_4, protocol="static")
455 assert result is True, "Testcase {} : Failed \n Error : {}".format(
456 tc_name, result
457 )
458
459 step(
460 "Verify that redistributed routes are withdrawn as changed "
461 "next-hop IP, belongs to different subnet"
462 )
463 result = verify_rib(
464 tgen, addr_type, "r2", input_dict_4, protocol="bgp", expected=False
465 )
466 assert (
467 result is not True
468 ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format(
469 tc_name, result
470 )
471
472 write_test_footer(tc_name)
473
474
475 def test_next_hop_as_self_ip_p1(request):
476 """
477 Verify that any BGP prefix received with next hop as
478 self-ip is not installed in BGP RIB or FIB table.
479 """
480
481 tc_name = request.node.name
482 write_test_header(tc_name)
483 tgen = get_topogen()
484
485 # Don"t run this test if we have any failure.
486 if tgen.routers_have_failure():
487 pytest.skip(tgen.errors)
488
489 step("Initial config :Configure BGP neighborship between R1 and R3.")
490 reset_config_on_routers(tgen)
491
492 step(
493 "Configure static routes on R1 with a next-hop IP belonging"
494 "to the same subnet of R2's link IP."
495 )
496 dut = "r1"
497 create_interface_in_kernel(
498 tgen,
499 dut,
500 "lo10",
501 topo["routers"]["r4"]["links"]["r2"]["ipv4"].split("/")[0],
502 netmask="255.255.255.0",
503 create=True,
504 )
505 create_interface_in_kernel(
506 tgen,
507 dut,
508 "lo10",
509 topo["routers"]["r4"]["links"]["r2"]["ipv6"].split("/")[0],
510 netmask="64",
511 create=True,
512 )
513 for addr_type in ADDR_TYPES:
514 input_dict_4 = {
515 "r1": {
516 "static_routes": [
517 {
518 "network": NETWORK[addr_type],
519 "next_hop": topo["routers"]["r2"]["links"]["r4"][
520 addr_type
521 ].split("/")[0],
522 }
523 ]
524 }
525 }
526 result = create_static_routes(tgen, input_dict_4)
527
528 step("Verify that static routes are installed in RIB and FIB of R1")
529 result = verify_rib(
530 tgen,
531 addr_type,
532 dut,
533 input_dict_4,
534 next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
535 protocol="static",
536 )
537 assert result is True, "Testcase {} : Failed \n Error : {}".format(
538 tc_name, result
539 )
540
541 step("Redistribute static routes into BGP on R1")
542 input_dict_2 = {
543 "r1": {
544 "bgp": {
545 "address_family": {
546 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
547 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
548 }
549 }
550 }
551 }
552 result = create_router_bgp(tgen, topo, input_dict_2)
553
554 step(
555 "Verify that R2 denies the prefixes received in update message,"
556 "as next-hop IP belongs to connected interface"
557 )
558 for addr_type in ADDR_TYPES:
559 input_dict_4 = {
560 "r1": {
561 "static_routes": [
562 {
563 "network": NETWORK[addr_type],
564 "next_hop": topo["routers"]["r2"]["links"]["r4"][
565 addr_type
566 ].split("/")[0],
567 }
568 ]
569 }
570 }
571 result = verify_bgp_rib(
572 tgen,
573 addr_type,
574 "r2",
575 input_dict_4,
576 next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
577 expected=False,
578 )
579 assert (
580 result is not True
581 ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format(
582 tc_name, result
583 )
584
585 step("Shut interface on R2 that has IP from the subnet as BGP next-hop")
586 intf_r2_r4 = topo["routers"]["r2"]["links"]["r4"]["interface"]
587 shutdown_bringup_interface(tgen, "r2", intf_r2_r4)
588
589 for addr_type in ADDR_TYPES:
590 clear_bgp(tgen, addr_type, "r2")
591 step(
592 "Verify that redistributed routes now appear only in BGP table,"
593 "as next-hop IP is no more active on R2"
594 )
595 for addr_type in ADDR_TYPES:
596 input_dict_4 = {
597 "r1": {
598 "static_routes": [
599 {
600 "network": NETWORK[addr_type],
601 "next_hop": topo["routers"]["r2"]["links"]["r4"][
602 addr_type
603 ].split("/")[0],
604 }
605 ]
606 }
607 }
608 result = verify_bgp_rib(
609 tgen,
610 addr_type,
611 "r2",
612 input_dict_4,
613 next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
614 )
615 assert result is True, "Testcase {}: Failed \n Error : {}".format(
616 tc_name, result
617 )
618
619 step("No shutdown interface on R2 which was shut in previous step")
620 intf_r2_r4 = topo["routers"]["r2"]["links"]["r4"]["interface"]
621 shutdown_bringup_interface(tgen, "r2", intf_r2_r4, ifaceaction=True)
622
623 step(
624 "Verify that R2 dosn't install prefixes RIB to FIB as next-hop"
625 "interface is up now"
626 )
627 for addr_type in ADDR_TYPES:
628 input_dict_4 = {
629 "r1": {
630 "static_routes": [
631 {
632 "network": NETWORK[addr_type],
633 "next_hop": topo["routers"]["r2"]["links"]["r4"][
634 addr_type
635 ].split("/")[0],
636 }
637 ]
638 }
639 }
640 result = verify_bgp_rib(
641 tgen,
642 addr_type,
643 "r2",
644 input_dict_4,
645 next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
646 )
647 assert result is True, "Testcase {}: Failed \n Error : {}".format(
648 tc_name, result
649 )
650 result = verify_rib(
651 tgen,
652 addr_type,
653 "r2",
654 input_dict_4,
655 next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
656 expected=False,
657 )
658 assert (
659 result is not True
660 ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format(
661 tc_name, result
662 )
663
664 write_test_footer(tc_name)
665
666
667 def test_next_hop_with_recursive_lookup_p1(request):
668 """
669 Verify that for a BGP prefix next-hop information doesn't change
670 when same prefix is received from another peer via recursive lookup.
671 """
672
673 tc_name = request.node.name
674 write_test_header(tc_name)
675 tgen = get_topogen()
676
677 # Don"t run this test if we have any failure.
678 if tgen.routers_have_failure():
679 pytest.skip(tgen.errors)
680
681 step("Initial config :Configure BGP neighborship between R1 and R3.")
682 reset_config_on_routers(tgen)
683
684 step("Verify that BGP peering comes up.")
685
686 result = verify_bgp_convergence_from_running_config(tgen)
687 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
688
689 step("Do redistribute connected on router R3.")
690 input_dict_1 = {
691 "r3": {
692 "bgp": {
693 "address_family": {
694 "ipv4": {
695 "unicast": {"redistribute": [{"redist_type": "connected"}]}
696 },
697 "ipv6": {
698 "unicast": {"redistribute": [{"redist_type": "connected"}]}
699 },
700 }
701 }
702 }
703 }
704
705 result = create_router_bgp(tgen, topo, input_dict_1)
706 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
707
708 step("Verify that R1 receives all connected")
709 for addr_type in ADDR_TYPES:
710 routes = {
711 "ipv4": ["1.0.3.17/32", "10.0.1.0/24", "10.0.3.0/24"],
712 "ipv6": ["2001:db8:f::3:17/128", "fd00:0:0:1::/64", "fd00:0:0:3::/64"],
713 }
714 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
715 result = verify_rib(tgen, addr_type, "r1", input_dict, protocol="bgp")
716 assert result is True, "Testcase {} : Failed \n Error : {}".format(
717 tc_name, result
718 )
719
720 step(
721 "Configure a BGP neighborship between R1 and R4, directly via "
722 "eBGP multi-hop."
723 )
724 r1_local_as = topo["routers"]["r1"]["bgp"]["local_as"]
725 r1_r3_addr = topo["routers"]["r1"]["links"]["r3"]
726 r4_local_as = topo["routers"]["r4"]["bgp"]["local_as"]
727 r4_r3_addr = topo["routers"]["r4"]["links"]["r3"]
728 ebgp_multi_hop = 3
729
730 for addr_type in ADDR_TYPES:
731 raw_config = {
732 "r1": {
733 "raw_config": [
734 "router bgp {}".format(r1_local_as),
735 "neighbor {} remote-as {}".format(
736 r4_r3_addr[addr_type].split("/")[0], r4_local_as
737 ),
738 "neighbor {} timers {} {}".format(
739 r4_r3_addr[addr_type].split("/")[0],
740 KEEP_ALIVE_TIMER,
741 HOLD_DOWN_TIMER,
742 ),
743 "neighbor {} ebgp-multihop {}".format(
744 r4_r3_addr[addr_type].split("/")[0], ebgp_multi_hop
745 ),
746 ]
747 },
748 "r4": {
749 "raw_config": [
750 "router bgp {}".format(r4_local_as),
751 "neighbor {} remote-as {}".format(
752 r1_r3_addr[addr_type].split("/")[0], r1_local_as
753 ),
754 "neighbor {} timers {} {}".format(
755 r1_r3_addr[addr_type].split("/")[0],
756 KEEP_ALIVE_TIMER,
757 HOLD_DOWN_TIMER,
758 ),
759 "neighbor {} ebgp-multihop {}".format(
760 r1_r3_addr[addr_type].split("/")[0], ebgp_multi_hop
761 ),
762 ]
763 },
764 }
765 result = apply_raw_config(tgen, raw_config)
766 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
767
768 for addr_type in ADDR_TYPES:
769 if addr_type == "ipv4":
770 raw_config = {
771 "r1": {
772 "raw_config": [
773 "router bgp {}".format(r1_local_as),
774 "address-family {} unicast".format(addr_type),
775 "no neighbor {} activate".format(
776 r4_r3_addr["ipv6"].split("/")[0]
777 ),
778 ]
779 },
780 "r4": {
781 "raw_config": [
782 "router bgp {}".format(r4_local_as),
783 "address-family {} unicast".format(addr_type),
784 "no neighbor {} activate".format(
785 r1_r3_addr["ipv6"].split("/")[0]
786 ),
787 ]
788 },
789 }
790 else:
791 raw_config = {
792 "r1": {
793 "raw_config": [
794 "router bgp {}".format(r1_local_as),
795 "address-family {} unicast".format(addr_type),
796 "neighbor {} activate".format(
797 r4_r3_addr[addr_type].split("/")[0]
798 ),
799 ]
800 },
801 "r4": {
802 "raw_config": [
803 "router bgp {}".format(r4_local_as),
804 "address-family {} unicast".format(addr_type),
805 "neighbor {} activate".format(
806 r1_r3_addr[addr_type].split("/")[0]
807 ),
808 ]
809 },
810 }
811 result = apply_raw_config(tgen, raw_config)
812 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
813
814 step("Verify that BGP session between R1 and R4 comes up" "(recursively via R3).")
815 result = verify_bgp_convergence_from_running_config(tgen)
816 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
817
818 step("Do redistribute connected on router R4.")
819 input_dict_1 = {
820 "r4": {
821 "bgp": {
822 "address_family": {
823 "ipv4": {
824 "unicast": {"redistribute": [{"redist_type": "connected"}]}
825 },
826 "ipv6": {
827 "unicast": {"redistribute": [{"redist_type": "connected"}]}
828 },
829 }
830 }
831 }
832 }
833
834 result = create_router_bgp(tgen, topo, input_dict_1)
835 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
836
837 step(
838 "Verify that R1 now receives BGP prefix of link r3-r4 via 2 "
839 "next-hops R3 and R4. however do not install with NHT R4 in FIB."
840 )
841 for addr_type in ADDR_TYPES:
842 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
843
844 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
845 next_hop = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
846
847 result = verify_rib(
848 tgen, addr_type, "r1", input_dict, protocol="bgp", next_hop=next_hop
849 )
850 assert result is True, "Testcase {} : Failed \n Error : {}".format(
851 tc_name, result
852 )
853
854 step("Clear bgp sessions from R1 using 'clear ip bgp *'")
855 for addr_type in ADDR_TYPES:
856 clear_bgp(tgen, addr_type, "r1")
857
858 step(
859 "Verify that prefix of link r3-r4 is again learned via 2 "
860 "next-hops (from R3 and R4 directly)"
861 )
862 for addr_type in ADDR_TYPES:
863 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
864
865 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
866 next_hop = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
867
868 result = verify_rib(
869 tgen, addr_type, "r1", input_dict, protocol="bgp", next_hop=next_hop
870 )
871 assert result is True, "Testcase {} : Failed \n Error : {}".format(
872 tc_name, result
873 )
874
875 step("Remove redistribution from router R3.")
876 input_dict_1 = {
877 "r3": {
878 "bgp": {
879 "local_as": "300",
880 "address_family": {
881 "ipv4": {
882 "unicast": {
883 "redistribute": [
884 {"redist_type": "connected", "delete": True}
885 ]
886 }
887 },
888 "ipv6": {
889 "unicast": {
890 "redistribute": [
891 {"redist_type": "connected", "delete": True}
892 ]
893 }
894 },
895 },
896 }
897 }
898 }
899
900 result = create_router_bgp(tgen, topo, input_dict_1)
901 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
902
903 step(
904 "Verify that peering between R1-R4 goes down and prefix "
905 "of link r3-r4, with NHT R4 is withdrawn."
906 )
907
908 logger.info("Sleeping for holddowntimer: {}".format(HOLD_DOWN_TIMER))
909 sleep(HOLD_DOWN_TIMER + 1)
910
911 result = verify_bgp_convergence_from_running_config(tgen, expected=False)
912 assert (
913 result is not True
914 ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(
915 tc_name, result
916 )
917 logger.info("Expected behaviour: {}".format(result))
918
919 for addr_type in ADDR_TYPES:
920 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
921
922 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
923 next_hop = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
924
925 result = verify_rib(
926 tgen, addr_type, "r1", input_dict, protocol="bgp", next_hop=next_hop
927 )
928 assert result is True, "Testcase {} : Failed \n Error : {}".format(
929 tc_name, result
930 )
931
932 step("Re-apply redistribution on R3.")
933
934 input_dict_1 = {
935 "r3": {
936 "bgp": {
937 "local_as": "300",
938 "address_family": {
939 "ipv4": {
940 "unicast": {"redistribute": [{"redist_type": "connected"}]}
941 },
942 "ipv6": {
943 "unicast": {"redistribute": [{"redist_type": "connected"}]}
944 },
945 },
946 }
947 }
948 }
949
950 result = create_router_bgp(tgen, topo, input_dict_1)
951 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
952
953 step(
954 "Verify that peering between R1-R4 goes down and prefix "
955 "of link r3-r4 with NHT R4 is withdrawn."
956 )
957
958 result = verify_bgp_convergence_from_running_config(tgen)
959 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
960
961 for addr_type in ADDR_TYPES:
962 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
963
964 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
965 next_hop = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
966
967 result = verify_rib(
968 tgen, addr_type, "r1", input_dict, protocol="bgp", next_hop=next_hop
969 )
970 assert result is True, "Testcase {} : Failed \n Error : {}".format(
971 tc_name, result
972 )
973
974 step("Remove redistribution from router R4.")
975
976 input_dict_1 = {
977 "r4": {
978 "bgp": {
979 "local_as": "400",
980 "address_family": {
981 "ipv4": {
982 "unicast": {
983 "redistribute": [
984 {"redist_type": "connected", "delete": True}
985 ]
986 }
987 },
988 "ipv6": {
989 "unicast": {
990 "redistribute": [
991 {"redist_type": "connected", "delete": True}
992 ]
993 }
994 },
995 },
996 }
997 }
998 }
999
1000 result = create_router_bgp(tgen, topo, input_dict_1)
1001 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1002
1003 step(
1004 "Verify that peering between R1-R4 doesn't go down but prefix "
1005 "of link r3-r4 with NHT R4 is withdrawn."
1006 )
1007
1008 logger.info("Sleeping for holddowntimer: {}".format(HOLD_DOWN_TIMER))
1009 sleep(HOLD_DOWN_TIMER + 1)
1010
1011 result = verify_bgp_convergence_from_running_config(tgen)
1012 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1013
1014 for addr_type in ADDR_TYPES:
1015 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
1016
1017 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
1018 next_hop = topo["routers"]["r4"]["links"]["r3"][addr_type].split("/")[0]
1019
1020 result = verify_rib(
1021 tgen,
1022 addr_type,
1023 "r1",
1024 input_dict,
1025 protocol="bgp",
1026 next_hop=next_hop,
1027 expected=False,
1028 )
1029 assert (
1030 result is not True
1031 ), "Testcase {} : Failed \n " "Route is still present \n Error : {}".format(
1032 tc_name, result
1033 )
1034
1035 step("Re-apply redistribution on R4.")
1036
1037 input_dict_1 = {
1038 "r4": {
1039 "bgp": {
1040 "local_as": "400",
1041 "address_family": {
1042 "ipv4": {
1043 "unicast": {
1044 "redistribute": [
1045 {"redist_type": "connected", "delete": True}
1046 ]
1047 }
1048 },
1049 "ipv6": {
1050 "unicast": {
1051 "redistribute": [
1052 {"redist_type": "connected", "delete": True}
1053 ]
1054 }
1055 },
1056 },
1057 }
1058 }
1059 }
1060
1061 result = create_router_bgp(tgen, topo, input_dict_1)
1062 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1063
1064 step("Verify that prefix of link r3-r4 is re-learned via NHT R4.")
1065
1066 for addr_type in ADDR_TYPES:
1067 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
1068
1069 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
1070 next_hop = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
1071
1072 result = verify_rib(
1073 tgen, addr_type, "r1", input_dict, protocol="bgp", next_hop=next_hop
1074 )
1075 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1076 tc_name, result
1077 )
1078
1079 step("Toggle the interface on R3.")
1080
1081 intf_r3_r4 = topo["routers"]["r3"]["links"]["r4"]["interface"]
1082 shutdown_bringup_interface(tgen, "r3", intf_r3_r4)
1083
1084 step(
1085 "Verify that peering between R1-R4 goes down and comes up when "
1086 "interface is toggled. Also prefix of link r3-r4(via both NHTs) is"
1087 " withdrawn and re-learned accordingly."
1088 )
1089
1090 result = verify_bgp_convergence_from_running_config(tgen, expected=False)
1091 assert (
1092 result is not True
1093 ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(
1094 tc_name, result
1095 )
1096 logger.info("Expected behaviour: {}".format(result))
1097
1098 for addr_type in ADDR_TYPES:
1099 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
1100
1101 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
1102 next_hop = topo["routers"]["r4"]["links"]["r3"][addr_type].split("/")[0]
1103
1104 result = verify_rib(
1105 tgen,
1106 addr_type,
1107 "r1",
1108 input_dict,
1109 protocol="bgp",
1110 next_hop=next_hop,
1111 expected=False,
1112 )
1113 assert (
1114 result is not True
1115 ), "Testcase {} : Failed \n " "Route is still present \n Error : {}".format(
1116 tc_name, result
1117 )
1118
1119 shutdown_bringup_interface(tgen, "r3", intf_r3_r4, True)
1120
1121 result = verify_bgp_convergence_from_running_config(tgen)
1122 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1123
1124 for addr_type in ADDR_TYPES:
1125 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
1126
1127 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
1128 next_hop = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
1129
1130 result = verify_rib(
1131 tgen, addr_type, "r1", input_dict, protocol="bgp", next_hop=next_hop
1132 )
1133 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1134 tc_name, result
1135 )
1136
1137 step("Toggle the interface on R4.")
1138
1139 intf_r4_r3 = topo["routers"]["r4"]["links"]["r3"]["interface"]
1140 shutdown_bringup_interface(tgen, "r4", intf_r4_r3)
1141
1142 step(
1143 "Verify that peering between R1-R4 goes down and comes up when"
1144 "interface is toggled. Also prefix of link r3-r4(via R4)"
1145 " is withdrawn and re-learned accordingly."
1146 )
1147
1148 result = verify_bgp_convergence_from_running_config(tgen, expected=False)
1149 assert (
1150 result is not True
1151 ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(
1152 tc_name, result
1153 )
1154 logger.info("Expected behaviour: {}".format(result))
1155
1156 for addr_type in ADDR_TYPES:
1157 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
1158
1159 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
1160 next_hop = topo["routers"]["r4"]["links"]["r3"][addr_type].split("/")[0]
1161
1162 result = verify_rib(
1163 tgen,
1164 addr_type,
1165 "r1",
1166 input_dict,
1167 protocol="bgp",
1168 next_hop=next_hop,
1169 expected=False,
1170 )
1171 assert (
1172 result is not True
1173 ), "Testcase {} : Failed \n " "Route is still present \n Error : {}".format(
1174 tc_name, result
1175 )
1176
1177 shutdown_bringup_interface(tgen, "r4", intf_r4_r3, True)
1178
1179 result = verify_bgp_convergence_from_running_config(tgen)
1180 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1181
1182 for addr_type in ADDR_TYPES:
1183 routes = {"ipv4": ["10.0.3.0/24"], "ipv6": ["fd00:0:0:3::/64"]}
1184
1185 input_dict = {"r1": {"static_routes": [{"network": routes[addr_type]}]}}
1186 next_hop = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
1187
1188 result = verify_rib(
1189 tgen, addr_type, "r1", input_dict, protocol="bgp", next_hop=next_hop
1190 )
1191 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1192 tc_name, result
1193 )
1194
1195 write_test_footer(tc_name)
1196
1197
1198 def test_BGP_path_attributes_default_values_p1(request):
1199 """
1200 Verify that BGP path attributes are present in CLI
1201 outputs and JSON format, even if set to default.
1202 """
1203
1204 tc_name = request.node.name
1205 write_test_header(tc_name)
1206 tgen = get_topogen()
1207
1208 # Don"t run this test if we have any failure.
1209 if tgen.routers_have_failure():
1210 pytest.skip(tgen.errors)
1211
1212 step("Initial config: Configure BGP neighborship, between R1-R2 & R1-R3")
1213 reset_config_on_routers(tgen)
1214
1215 step("Advertise a set of prefixes from R1 to both peers R2 and R3")
1216 for addr_type in ADDR_TYPES:
1217 input_dict_1 = {
1218 "r1": {
1219 "static_routes": [{"network": NETWORK[addr_type], "next_hop": "null0"}]
1220 }
1221 }
1222 result = create_static_routes(tgen, input_dict_1)
1223
1224 input_dict_2 = {
1225 "r1": {
1226 "bgp": {
1227 "address_family": {
1228 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
1229 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
1230 }
1231 }
1232 }
1233 }
1234 result = create_router_bgp(tgen, topo, input_dict_2)
1235
1236 step(
1237 "Verify that advertised prefixes are received on R4 and well"
1238 "known attributes are present in the CLI and JSON outputs with"
1239 "default values without any route-map config."
1240 )
1241 for addr_type in ADDR_TYPES:
1242 input_dict_3 = {"r4": {"static_routes": [{"network": NETWORK[addr_type]}]}}
1243 result = verify_bgp_rib(
1244 tgen,
1245 addr_type,
1246 "r4",
1247 input_dict_3,
1248 next_hop=[
1249 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
1250 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
1251 ],
1252 )
1253 assert result is True, "Testcase {}: Failed \n Error : {}".format(
1254 tc_name, result
1255 )
1256
1257 for addr_type in ADDR_TYPES:
1258 input_dict_4 = {
1259 "r4": {
1260 "route_maps": {
1261 "rmap_pf": [{"set": {"origin": "incomplete", "aspath": "300 100"}}]
1262 }
1263 }
1264 }
1265
1266 result = verify_bgp_attributes(
1267 tgen,
1268 addr_type,
1269 "r4",
1270 NETWORK[addr_type],
1271 rmap_name="rmap_pf",
1272 input_dict=input_dict_4,
1273 )
1274 assert result is True, "Testcase {}: Failed \n Error : {}".format(
1275 tc_name, result
1276 )
1277
1278 step(
1279 "Configure a route-map to set below attribute value as 500"
1280 "and apply on R4 in an inbound direction"
1281 )
1282 for addr_type in ADDR_TYPES:
1283 input_dict_4 = {
1284 "r4": {
1285 "route_maps": {
1286 "Path_Attribue": [
1287 {
1288 "action": "permit",
1289 "set": {
1290 "path": {"as_num": 500, "as_action": "prepend"},
1291 "locPrf": 500,
1292 "origin": "egp",
1293 },
1294 }
1295 ]
1296 }
1297 }
1298 }
1299 result = create_route_maps(tgen, input_dict_4)
1300 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1301
1302 input_dict_5 = {
1303 "r4": {
1304 "bgp": {
1305 "address_family": {
1306 "ipv4": {
1307 "unicast": {
1308 "neighbor": {
1309 "r3": {
1310 "dest_link": {
1311 "r4": {
1312 "route_maps": [
1313 {
1314 "name": "Path_Attribue",
1315 "direction": "in",
1316 }
1317 ]
1318 }
1319 }
1320 }
1321 }
1322 }
1323 },
1324 "ipv6": {
1325 "unicast": {
1326 "neighbor": {
1327 "r3": {
1328 "dest_link": {
1329 "r4": {
1330 "route_maps": [
1331 {
1332 "name": "Path_Attribue",
1333 "direction": "in",
1334 }
1335 ]
1336 }
1337 }
1338 }
1339 }
1340 }
1341 },
1342 }
1343 }
1344 }
1345 }
1346
1347 result = create_router_bgp(tgen, topo, input_dict_5)
1348 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1349
1350 step(
1351 "Verify that once the route-map is applied all the attributes"
1352 "part of route-map, changes value to 500"
1353 )
1354 for addr_type in ADDR_TYPES:
1355 input_dict_4 = {
1356 "r4": {
1357 "route_maps": {
1358 "rmap_pf": [
1359 {
1360 "set": {
1361 "locPrf": 500,
1362 "aspath": "500 300 100",
1363 "origin": "EGP",
1364 }
1365 }
1366 ]
1367 }
1368 }
1369 }
1370 result = verify_bgp_attributes(
1371 tgen,
1372 addr_type,
1373 "r4",
1374 NETWORK[addr_type],
1375 rmap_name="rmap_pf",
1376 input_dict=input_dict_4,
1377 )
1378 assert result is True, "Testcase {}: Failed \n Error : {}".format(
1379 tc_name, result
1380 )
1381
1382 step("Remove the route-map from R4")
1383 input_dict_5 = {
1384 "r4": {
1385 "bgp": {
1386 "address_family": {
1387 "ipv4": {
1388 "unicast": {
1389 "neighbor": {
1390 "r3": {
1391 "dest_link": {
1392 "r4": {
1393 "route_maps": [
1394 {
1395 "name": "Path_Attribue",
1396 "direction": "in",
1397 "delete": True,
1398 }
1399 ]
1400 }
1401 }
1402 }
1403 }
1404 }
1405 },
1406 "ipv6": {
1407 "unicast": {
1408 "neighbor": {
1409 "r3": {
1410 "dest_link": {
1411 "r4": {
1412 "route_maps": [
1413 {
1414 "name": "Path_Attribue",
1415 "direction": "in",
1416 "delete": True,
1417 }
1418 ]
1419 }
1420 }
1421 }
1422 }
1423 }
1424 },
1425 }
1426 }
1427 }
1428 }
1429
1430 result = create_router_bgp(tgen, topo, input_dict_5)
1431 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1432
1433 step(
1434 "Verify on R4 that well known attributes are present in the CLI &"
1435 "JSON outputs again with default values without route-map config"
1436 )
1437 for addr_type in ADDR_TYPES:
1438 input_dict_4 = {
1439 "r4": {
1440 "route_maps": {
1441 "rmap_pf": [{"set": {"aspath": "300 100", "origin": "incomplete"}}]
1442 }
1443 }
1444 }
1445 result = verify_bgp_attributes(
1446 tgen,
1447 addr_type,
1448 "r4",
1449 NETWORK[addr_type],
1450 rmap_name="rmap_pf",
1451 input_dict=input_dict_4,
1452 nexthop=None,
1453 )
1454 assert result is True, "Testcase {}: Failed \n Error : {}".format(
1455 tc_name, result
1456 )
1457
1458 write_test_footer(tc_name)
1459
1460
1461 def test_BGP_peering_bw_loopback_and_physical_p1(request):
1462 """
1463 Verifying the BGP peering between loopback and
1464 physical link's IP of 2 peer routers.
1465 """
1466
1467 tc_name = request.node.name
1468 write_test_header(tc_name)
1469 tgen = get_topogen()
1470
1471 # Don"t run this test if we have any failure.
1472 if tgen.routers_have_failure():
1473 pytest.skip(tgen.errors)
1474
1475 step("Initial config :Configure BGP neighborship between R1 and R3.")
1476 reset_config_on_routers(tgen)
1477
1478 step("Configure a loopback interface on R1")
1479 dut = "r1"
1480 create_interface_in_kernel(
1481 tgen, dut, "lo10", "1.1.1.1", netmask="255.255.255.255", create=True
1482 )
1483 create_interface_in_kernel(
1484 tgen, dut, "lo10", "1:1::1:1", netmask="128", create=True
1485 )
1486
1487 step("Configure BGP session between R1's loopbak & R3")
1488 for addr_type in ADDR_TYPES:
1489 input_dict_1 = {
1490 "r3": {
1491 "static_routes": [
1492 {
1493 "network": Loopabck_IP["Lo_R1"][addr_type],
1494 "next_hop": topo["routers"]["r1"]["links"]["r3"][
1495 addr_type
1496 ].split("/")[0],
1497 }
1498 ]
1499 }
1500 }
1501 result = create_static_routes(tgen, input_dict_1)
1502 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1503 tc_name, result
1504 )
1505 result = verify_rib(
1506 tgen,
1507 addr_type,
1508 "r3",
1509 input_dict_1,
1510 protocol="static",
1511 next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0],
1512 )
1513 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1514 tc_name, result
1515 )
1516
1517 for addr_type in ADDR_TYPES:
1518 raw_config = {
1519 "r1": {
1520 "raw_config": [
1521 "router bgp {}".format(topo["routers"]["r1"]["bgp"]["local_as"]),
1522 "address-family {} unicast".format(addr_type),
1523 "neighbor {} update-source lo10".format(
1524 topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
1525 ),
1526 "neighbor {} timers 1 3".format(
1527 topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
1528 ),
1529 ]
1530 },
1531 "r3": {
1532 "raw_config": [
1533 "router bgp {}".format(topo["routers"]["r3"]["bgp"]["local_as"]),
1534 "address-family {} unicast".format(addr_type),
1535 "no neighbor {} remote-as {}".format(
1536 topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0],
1537 topo["routers"]["r1"]["bgp"]["local_as"],
1538 ),
1539 "neighbor {} remote-as {}".format(
1540 Loopabck_IP["Lo_R1"][addr_type].split("/")[0],
1541 topo["routers"]["r1"]["bgp"]["local_as"],
1542 ),
1543 "neighbor {} ebgp-multihop 3".format(
1544 Loopabck_IP["Lo_R1"][addr_type].split("/")[0]
1545 ),
1546 ]
1547 },
1548 }
1549 result = apply_raw_config(tgen, raw_config)
1550 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
1551
1552 for addr_type in ADDR_TYPES:
1553 if addr_type == "ipv6":
1554 raw_config = {
1555 "r3": {
1556 "raw_config": [
1557 "router bgp {}".format(
1558 topo["routers"]["r3"]["bgp"]["local_as"]
1559 ),
1560 "address-family {} unicast".format(addr_type),
1561 "neighbor {} activate".format(
1562 Loopabck_IP["Lo_R1"][addr_type].split("/")[0]
1563 ),
1564 ]
1565 }
1566 }
1567 else:
1568 raw_config = {
1569 "r3": {
1570 "raw_config": [
1571 "router bgp {}".format(
1572 topo["routers"]["r3"]["bgp"]["local_as"]
1573 ),
1574 "address-family {} unicast".format(addr_type),
1575 "no neighbor {} activate".format(
1576 Loopabck_IP["Lo_R1"]["ipv6"].split("/")[0]
1577 ),
1578 ]
1579 }
1580 }
1581 result = apply_raw_config(tgen, raw_config)
1582 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
1583
1584 step("Verify that BGP neighborship between R1 and R3 comes up")
1585 result = verify_bgp_convergence_from_running_config(tgen)
1586 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1587
1588 step("Remove ebgp-multihop command from R3")
1589 for addr_type in ADDR_TYPES:
1590 raw_config = {
1591 "r3": {
1592 "raw_config": [
1593 "router bgp {}".format(topo["routers"]["r3"]["bgp"]["local_as"]),
1594 "no neighbor {} ebgp-multihop 3".format(
1595 Loopabck_IP["Lo_R1"][addr_type].split("/")[0]
1596 ),
1597 ]
1598 }
1599 }
1600 result = apply_raw_config(tgen, raw_config)
1601 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
1602
1603 step("Verify that once eBGP multi-hop is removed, BGP session goes down")
1604 result = verify_bgp_convergence_from_running_config(tgen, expected=False)
1605 assert (
1606 result is not True
1607 ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format(
1608 tc_name, result
1609 )
1610
1611 step("Add ebgp-multihop command on R3 again")
1612 for addr_type in ADDR_TYPES:
1613 raw_config = {
1614 "r3": {
1615 "raw_config": [
1616 "router bgp {}".format(topo["routers"]["r3"]["bgp"]["local_as"]),
1617 "neighbor {} ebgp-multihop 3".format(
1618 Loopabck_IP["Lo_R1"][addr_type].split("/")[0]
1619 ),
1620 ]
1621 }
1622 }
1623 result = apply_raw_config(tgen, raw_config)
1624 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
1625
1626 step("Verify that BGP neighborship between R1 and R3 comes up")
1627 result = verify_bgp_convergence_from_running_config(tgen)
1628 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1629
1630 step("Remove update-source command from R1")
1631 for addr_type in ADDR_TYPES:
1632 raw_config = {
1633 "r1": {
1634 "raw_config": [
1635 "router bgp {}".format(topo["routers"]["r1"]["bgp"]["local_as"]),
1636 "no neighbor {} update-source lo10".format(
1637 topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
1638 ),
1639 ]
1640 }
1641 }
1642 result = apply_raw_config(tgen, raw_config)
1643 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
1644
1645 step("Verify that BGP session goes down, when update-source is removed")
1646 result = verify_bgp_convergence_from_running_config(tgen, expected=False)
1647 assert (
1648 result is not True
1649 ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format(
1650 tc_name, result
1651 )
1652
1653 step("Add update-source command on R1 again")
1654 for addr_type in ADDR_TYPES:
1655 raw_config = {
1656 "r1": {
1657 "raw_config": [
1658 "router bgp {}".format(topo["routers"]["r1"]["bgp"]["local_as"]),
1659 "neighbor {} update-source lo10".format(
1660 topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
1661 ),
1662 ]
1663 }
1664 }
1665 result = apply_raw_config(tgen, raw_config)
1666 assert result is True, "Testcase {} : Failed Error : {}".format(tc_name, result)
1667
1668 step("Verify that BGP neighborship between R1 and R3 comes up")
1669 result = verify_bgp_convergence_from_running_config(tgen)
1670 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1671
1672 step("Remove static route from R3")
1673 for addr_type in ADDR_TYPES:
1674 input_dict_1 = {
1675 "r3": {
1676 "static_routes": [
1677 {
1678 "network": Loopabck_IP["Lo_R1"][addr_type],
1679 "next_hop": topo["routers"]["r1"]["links"]["r3"][
1680 addr_type
1681 ].split("/")[0],
1682 "delete": True,
1683 }
1684 ]
1685 }
1686 }
1687 result = create_static_routes(tgen, input_dict_1)
1688 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1689 tc_name, result
1690 )
1691 result = verify_rib(
1692 tgen,
1693 addr_type,
1694 "r3",
1695 input_dict_1,
1696 protocol="static",
1697 next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0],
1698 expected=False,
1699 )
1700 assert (
1701 result is not True
1702 ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format(
1703 tc_name, result
1704 )
1705
1706 sleep(3)
1707 step("Verify that BGP session goes down, when static route is removed")
1708 result = verify_bgp_convergence_from_running_config(tgen, expected=False)
1709 assert (
1710 result is not True
1711 ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format(
1712 tc_name, result
1713 )
1714
1715 step("Add static route on R3 again")
1716 for addr_type in ADDR_TYPES:
1717 input_dict_1 = {
1718 "r3": {
1719 "static_routes": [
1720 {
1721 "network": Loopabck_IP["Lo_R1"][addr_type],
1722 "next_hop": topo["routers"]["r1"]["links"]["r3"][
1723 addr_type
1724 ].split("/")[0],
1725 }
1726 ]
1727 }
1728 }
1729 result = create_static_routes(tgen, input_dict_1)
1730 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1731 tc_name, result
1732 )
1733 result = verify_rib(
1734 tgen,
1735 addr_type,
1736 "r3",
1737 input_dict_1,
1738 protocol="static",
1739 next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0],
1740 )
1741 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1742 tc_name, result
1743 )
1744
1745 step("Verify that BGP neighborship between R1 and R3 comes up")
1746 result = verify_bgp_convergence_from_running_config(tgen)
1747 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1748
1749 step("Toggle physical interface on R1")
1750 intf_r1_r3 = topo["routers"]["r1"]["links"]["r3"]["interface"]
1751 shutdown_bringup_interface(tgen, "r1", intf_r1_r3)
1752 sleep(3)
1753 step("Verify that BGP neighborship between R1 and R3 goes down")
1754 result = verify_bgp_convergence_from_running_config(tgen, expected=False)
1755 assert (
1756 result is not True
1757 ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format(
1758 tc_name, result
1759 )
1760
1761 intf_r1_r3 = topo["routers"]["r1"]["links"]["r3"]["interface"]
1762 shutdown_bringup_interface(tgen, "r1", intf_r1_r3, True)
1763
1764 step("Verify that BGP neighborship between R1 and R3 comes up")
1765 result = verify_bgp_convergence_from_running_config(tgen)
1766 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1767
1768 write_test_footer(tc_name)
1769
1770
1771 def test_BGP_active_standby_preemption_and_ecmp_p1(request):
1772 """
1773 Verify that BGP Active/Standby/Pre-emption/ECMP.
1774 """
1775
1776 tc_name = request.node.name
1777 write_test_header(tc_name)
1778 tgen = get_topogen()
1779
1780 # Don"t run this test if we have any failure.
1781 if tgen.routers_have_failure():
1782 pytest.skip(tgen.errors)
1783
1784 step("Initial config :Configure BGP neighborship between R1 and R3.")
1785 reset_config_on_routers(tgen)
1786
1787 step("Change the AS number on R2 as 200")
1788 input_dict = {"r2": {"bgp": {"local_as": 200}}}
1789 result = modify_as_number(tgen, topo, input_dict)
1790 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1791
1792 step("Verify BGP converge after changing the AS number on R2")
1793 result = verify_bgp_convergence_from_running_config(tgen)
1794 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1795
1796 step("Advertise a set of prefixes from R1 to both peers R2 & R3")
1797 for addr_type in ADDR_TYPES:
1798 input_dict_1 = {
1799 "r1": {
1800 "static_routes": [{"network": NETWORK[addr_type], "next_hop": "null0"}]
1801 }
1802 }
1803 result = create_static_routes(tgen, input_dict_1)
1804 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1805 tc_name, result
1806 )
1807
1808 input_dict_2 = {
1809 "r1": {
1810 "bgp": {
1811 "address_family": {
1812 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
1813 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
1814 }
1815 }
1816 }
1817 }
1818
1819 result = create_router_bgp(tgen, topo, input_dict_2)
1820 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1821
1822 step("Verify that R4 receives BGP prefixes via both peer routers R2 & R3")
1823 for addr_type in ADDR_TYPES:
1824 input_dict_3 = {"r4": {"static_routes": [{"network": NETWORK[addr_type]}]}}
1825 result = verify_bgp_rib(
1826 tgen,
1827 addr_type,
1828 "r4",
1829 input_dict_3,
1830 next_hop=[
1831 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
1832 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
1833 ],
1834 )
1835 assert result is True, "Testcase {}: Failed \n Error : {}".format(
1836 tc_name, result
1837 )
1838
1839 step(
1840 "Configure a route-map to set as-path attribute and"
1841 "apply on R3 in an inbound direction:"
1842 )
1843
1844 input_dict_4 = {
1845 "r3": {
1846 "route_maps": {
1847 "Path_Attribue": [
1848 {
1849 "action": "permit",
1850 "set": {"path": {"as_num": 123, "as_action": "prepend"}},
1851 }
1852 ]
1853 }
1854 }
1855 }
1856 result = create_route_maps(tgen, input_dict_4)
1857 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1858
1859 input_dict_5 = {
1860 "r3": {
1861 "bgp": {
1862 "address_family": {
1863 "ipv4": {
1864 "unicast": {
1865 "neighbor": {
1866 "r1": {
1867 "dest_link": {
1868 "r3": {
1869 "route_maps": [
1870 {
1871 "name": "Path_Attribue",
1872 "direction": "in",
1873 }
1874 ]
1875 }
1876 }
1877 }
1878 }
1879 }
1880 },
1881 "ipv6": {
1882 "unicast": {
1883 "neighbor": {
1884 "r1": {
1885 "dest_link": {
1886 "r3": {
1887 "route_maps": [
1888 {
1889 "name": "Path_Attribue",
1890 "direction": "in",
1891 }
1892 ]
1893 }
1894 }
1895 }
1896 }
1897 }
1898 },
1899 }
1900 }
1901 }
1902 }
1903 result = create_router_bgp(tgen, topo, input_dict_5)
1904 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1905
1906 step("Verify on R4, BGP routes with shorter as-path are installed in FIB")
1907 for addr_type in ADDR_TYPES:
1908 dut = "r4"
1909 protocol = "bgp"
1910 input_dict_6 = {"r4": {"static_routes": [{"network": NETWORK[addr_type]}]}}
1911 result = verify_rib(
1912 tgen,
1913 addr_type,
1914 dut,
1915 input_dict_6,
1916 next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
1917 protocol=protocol,
1918 )
1919 assert result is True, "Testcase {} : Failed \n Error : {}".format(
1920 tc_name, result
1921 )
1922
1923 step("Shutdown BGP neighorship between R1-R2")
1924 dut = "r4"
1925 intf_r4_r2 = topo["routers"]["r4"]["links"]["r2"]["interface"]
1926 shutdown_bringup_interface(tgen, dut, intf_r4_r2)
1927
1928 step(
1929 "Verify that prefixes from next-hop via R2 are withdrawn"
1930 "and installed via next-hop as R3"
1931 )
1932 result = verify_rib(
1933 tgen,
1934 addr_type,
1935 dut,
1936 input_dict_2,
1937 next_hop=topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
1938 protocol=protocol,
1939 )
1940 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1941
1942 step("Do a no shut for BGP neighorship between R2-R4")
1943 shutdown_bringup_interface(tgen, dut, intf_r4_r2, ifaceaction=True)
1944
1945 step(
1946 "Verify that prefixes from next-hop via R3 are withdrawn"
1947 "from R4 and installed via next-hop as R2 (preemption)"
1948 )
1949 result = verify_rib(
1950 tgen,
1951 addr_type,
1952 dut,
1953 input_dict_2,
1954 next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
1955 protocol=protocol,
1956 )
1957 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
1958
1959 step("Remove the route-map from R3's neighbor statement")
1960 input_dict_5 = {
1961 "r3": {
1962 "bgp": {
1963 "address_family": {
1964 "ipv4": {
1965 "unicast": {
1966 "neighbor": {
1967 "r1": {
1968 "dest_link": {
1969 "r3": {
1970 "route_maps": [
1971 {
1972 "name": "Path_Attribue",
1973 "direction": "in",
1974 "delete": True,
1975 }
1976 ]
1977 }
1978 }
1979 }
1980 }
1981 }
1982 },
1983 "ipv6": {
1984 "unicast": {
1985 "neighbor": {
1986 "r1": {
1987 "dest_link": {
1988 "r3": {
1989 "route_maps": [
1990 {
1991 "name": "Path_Attribue",
1992 "direction": "in",
1993 "delete": True,
1994 }
1995 ]
1996 }
1997 }
1998 }
1999 }
2000 }
2001 },
2002 }
2003 }
2004 }
2005 }
2006 result = create_router_bgp(tgen, topo, input_dict_5)
2007 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2008
2009 step("Configure multipath-relax and maximum-paths 2 on R4 for ECMP")
2010 input_dict_8 = {
2011 "r4": {
2012 "bgp": {
2013 "address_family": {
2014 "ipv4": {"unicast": {"maximum_paths": {"ebgp": 2}}},
2015 "ipv6": {"unicast": {"maximum_paths": {"ebgp": 2}}},
2016 }
2017 }
2018 }
2019 }
2020 result = create_router_bgp(tgen, topo, input_dict_8)
2021 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2022
2023 maxpath_relax = {
2024 "r4": {"bgp": {"local_as": "400", "bestpath": {"aspath": "multipath-relax"}}}
2025 }
2026
2027 result = create_router_bgp(tgen, topo, maxpath_relax)
2028 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2029
2030 step("Verify FIB of R4, BGP prefixes with ECMP next-hop via R2 and R3")
2031 for addr_type in ADDR_TYPES:
2032 input_dict = {"r4": {"static_routes": [{"network": NETWORK[addr_type]}]}}
2033 result = verify_rib(
2034 tgen,
2035 addr_type,
2036 "r4",
2037 input_dict,
2038 next_hop=[
2039 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
2040 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
2041 ],
2042 )
2043 assert result is True, "Testcase {} : Failed \n Error : {}".format(
2044 tc_name, result
2045 )
2046
2047 step("Remove multipath-relax command from R4")
2048
2049 del_maxpath_relax = {
2050 "r4": {
2051 "bgp": {
2052 "local_as": "400",
2053 "bestpath": {"aspath": "multipath-relax", "delete": True},
2054 }
2055 }
2056 }
2057
2058 result = create_router_bgp(tgen, topo, del_maxpath_relax)
2059 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2060
2061 step("Verify that ECMP is no longer happening on R4.")
2062 for addr_type in ADDR_TYPES:
2063 input_dict = {"r4": {"static_routes": [{"network": NETWORK[addr_type]}]}}
2064 result = verify_rib(
2065 tgen,
2066 addr_type,
2067 "r4",
2068 input_dict,
2069 next_hop=[
2070 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
2071 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
2072 ],
2073 expected=False,
2074 )
2075 assert (
2076 result is not True
2077 ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format(
2078 tc_name, result
2079 )
2080
2081 step("Reconfigure multipath-relax command on R4")
2082 result = create_router_bgp(tgen, topo, maxpath_relax)
2083 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2084
2085 step("Verify FIB of R4, BGP prefixes with ECMP next-hop via R2 and R3")
2086 result = verify_rib(
2087 tgen,
2088 addr_type,
2089 "r4",
2090 input_dict,
2091 next_hop=[
2092 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
2093 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
2094 ],
2095 )
2096 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2097
2098 step("Remove maximum-path 2 command from R4")
2099 input_dict_8 = {
2100 "r4": {
2101 "bgp": {
2102 "address_family": {
2103 "ipv4": {
2104 "unicast": {
2105 "maximum_paths": {
2106 "ebgp": 1,
2107 }
2108 }
2109 },
2110 "ipv6": {
2111 "unicast": {
2112 "maximum_paths": {
2113 "ebgp": 1,
2114 }
2115 }
2116 },
2117 }
2118 }
2119 }
2120 }
2121 result = create_router_bgp(tgen, topo, input_dict_8)
2122 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2123
2124 step("Verify that ECMP is no longer happening on R4")
2125 result = verify_rib(
2126 tgen,
2127 addr_type,
2128 "r4",
2129 input_dict,
2130 next_hop=[
2131 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
2132 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
2133 ],
2134 expected=False,
2135 )
2136 assert (
2137 result is not True
2138 ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format(
2139 tc_name, result
2140 )
2141
2142 step("Re-configure maximum-path 2 command on R4")
2143 input_dict_8 = {
2144 "r4": {
2145 "bgp": {
2146 "address_family": {
2147 "ipv4": {
2148 "unicast": {
2149 "maximum_paths": {
2150 "ebgp": 2,
2151 }
2152 }
2153 },
2154 "ipv6": {
2155 "unicast": {
2156 "maximum_paths": {
2157 "ebgp": 2,
2158 }
2159 }
2160 },
2161 }
2162 }
2163 }
2164 }
2165 result = create_router_bgp(tgen, topo, input_dict_8)
2166 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2167
2168 step("Verify FIB of R4, BGP prefixes with ECMP next-hop via R2 and R3")
2169 result = verify_rib(
2170 tgen,
2171 addr_type,
2172 "r4",
2173 input_dict,
2174 next_hop=[
2175 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
2176 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
2177 ],
2178 )
2179 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2180
2181 write_test_footer(tc_name)
2182
2183
2184 def test_password_authentication_for_eBGP_and_iBGP_peers_p1(request):
2185 """
2186 Verify password authentication for eBGP and iBGP peers.
2187 """
2188
2189 tc_name = request.node.name
2190 write_test_header(tc_name)
2191 tgen = get_topogen()
2192
2193 # Don"t run this test if we have any failure.
2194 if tgen.routers_have_failure():
2195 pytest.skip(tgen.errors)
2196
2197 step("Initial config :Configure BGP neighborship between R1 and R3.")
2198 reset_config_on_routers(tgen)
2199
2200 step(
2201 "Add a static route on R1 for loopbacks IP's reachability of R2, R3"
2202 "and on R2 and R3 for loopback IP of R1"
2203 )
2204 for addr_type in ADDR_TYPES:
2205 nh1 = topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0]
2206 nh2 = topo["routers"]["r1"]["links"]["r2"][addr_type].split("/")[0]
2207 nh3 = topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0]
2208 nh4 = topo["routers"]["r2"]["links"]["r1"][addr_type].split("/")[0]
2209 input_dict_1 = {
2210 "r1": {
2211 "static_routes": [
2212 {
2213 "network": topo["routers"]["r3"]["links"]["lo"][addr_type],
2214 "next_hop": nh1,
2215 }
2216 ]
2217 }
2218 }
2219 input_dict_2 = {
2220 "r2": {
2221 "static_routes": [
2222 {
2223 "network": topo["routers"]["r1"]["links"]["lo"][addr_type],
2224 "next_hop": nh2,
2225 }
2226 ]
2227 }
2228 }
2229 input_dict_3 = {
2230 "r3": {
2231 "static_routes": [
2232 {
2233 "network": topo["routers"]["r1"]["links"]["lo"][addr_type],
2234 "next_hop": nh3,
2235 }
2236 ]
2237 }
2238 }
2239 input_dict_4 = {
2240 "r1": {
2241 "static_routes": [
2242 {
2243 "network": topo["routers"]["r2"]["links"]["lo"][addr_type],
2244 "next_hop": nh4,
2245 }
2246 ]
2247 }
2248 }
2249 dut_list = ["r1", "r2", "r3", "r1"]
2250 nexthop_list = [nh1, nh2, nh3, nh4]
2251 input_dict_list = [input_dict_1, input_dict_2, input_dict_3, input_dict_4]
2252 for dut, next_hop, input_dict in zip(dut_list, nexthop_list, input_dict_list):
2253 result = create_static_routes(tgen, input_dict)
2254 assert result is True, "Testcase {} : Failed \n Error : {}".format(
2255 tc_name, result
2256 )
2257
2258 step("Verify that static routes are installed in FIB of routers")
2259 result = verify_rib(
2260 tgen, addr_type, dut, input_dict, next_hop=next_hop, protocol="static"
2261 )
2262 assert result is True, "Testcase {} : Failed \n Error : {}".format(
2263 tc_name, result
2264 )
2265
2266 step("Configure BGP sessions between R1-R2 and R1-R3 over loopback IPs")
2267 for routerN in ["r1", "r3"]:
2268 for addr_type in ADDR_TYPES:
2269 if routerN == "r1":
2270 bgp_neighbor = "r3"
2271 elif routerN == "r3":
2272 bgp_neighbor = "r1"
2273 topo["routers"][routerN]["bgp"]["address_family"][addr_type]["unicast"][
2274 "neighbor"
2275 ][bgp_neighbor]["dest_link"] = {
2276 "lo": {"ebgp_multihop": 2, "source_link": "lo"}
2277 }
2278 build_config_from_json(tgen, topo, save_bkup=False)
2279
2280 for routerN in ["r1", "r2"]:
2281 for addr_type in ADDR_TYPES:
2282 if routerN == "r1":
2283 bgp_neighbor = "r2"
2284 elif routerN == "r2":
2285 bgp_neighbor = "r1"
2286 topo["routers"][routerN]["bgp"]["address_family"][addr_type]["unicast"][
2287 "neighbor"
2288 ][bgp_neighbor]["dest_link"] = {"lo": {"source_link": "lo"}}
2289 build_config_from_json(tgen, topo, save_bkup=False)
2290
2291 for routerN in ["r1", "r2", "r3"]:
2292 for addr_type in ADDR_TYPES:
2293 for bgp_neighbor in topo["routers"][routerN]["bgp"]["address_family"][
2294 addr_type
2295 ]["unicast"]["neighbor"].keys():
2296 if routerN in ["r1", "r2", "r3"] and bgp_neighbor == "r4":
2297 continue
2298 if addr_type == "ipv4":
2299 topo["routers"][routerN]["bgp"]["address_family"][addr_type][
2300 "unicast"
2301 ]["neighbor"][bgp_neighbor]["dest_link"] = {
2302 "lo": {"deactivate": "ipv6"}
2303 }
2304 elif addr_type == "ipv6":
2305 topo["routers"][routerN]["bgp"]["address_family"][addr_type][
2306 "unicast"
2307 ]["neighbor"][bgp_neighbor]["dest_link"] = {
2308 "lo": {"deactivate": "ipv4"}
2309 }
2310 build_config_from_json(tgen, topo, save_bkup=False)
2311
2312 result = verify_bgp_convergence(tgen, topo)
2313 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2314
2315 step("Configure authentication password on R1 for neighbor statements")
2316 for bgp_neighbor in ["r2", "r3"]:
2317 for addr_type in ADDR_TYPES:
2318 topo["routers"]["r1"]["bgp"]["address_family"][addr_type]["unicast"][
2319 "neighbor"
2320 ][bgp_neighbor]["dest_link"] = {"lo": {"password": "vmware"}}
2321 build_config_from_json(tgen, topo, save_bkup=False)
2322
2323 step(
2324 "Verify that both sessions go down as only R1 has password"
2325 "configured but not peer routers"
2326 )
2327 result = verify_bgp_convergence(tgen, topo, expected=False)
2328 assert (
2329 result is not True
2330 ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format(
2331 tc_name, result
2332 )
2333
2334 step("configure same password on R2 and R3")
2335 for routerN in ["r2", "r3"]:
2336 for addr_type in ADDR_TYPES:
2337 topo["routers"][routerN]["bgp"]["address_family"][addr_type]["unicast"][
2338 "neighbor"
2339 ]["r1"]["dest_link"] = {"lo": {"password": "vmware"}}
2340 build_config_from_json(tgen, topo, save_bkup=False)
2341
2342 step("Verify that all BGP sessions come up due to identical passwords")
2343 result = verify_bgp_convergence(tgen, topo)
2344 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2345
2346 step("Configure same password on R2 and R3, but in CAPs.")
2347 for routerN in ["r2", "r3"]:
2348 for addr_type in ADDR_TYPES:
2349 topo["routers"][routerN]["bgp"]["address_family"][addr_type]["unicast"][
2350 "neighbor"
2351 ]["r1"]["dest_link"] = {"lo": {"password": "VMWARE"}}
2352 build_config_from_json(tgen, topo, save_bkup=False)
2353
2354 step(
2355 "Verify that BGP sessions do not come up as password"
2356 "strings are in CAPs on R2 and R3"
2357 )
2358 result = verify_bgp_convergence(tgen, topo, expected=False)
2359 assert (
2360 result is not True
2361 ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format(
2362 tc_name, result
2363 )
2364
2365 step("Configure same password on R2 and R3 without CAPs")
2366 for routerN in ["r2", "r3"]:
2367 for addr_type in ADDR_TYPES:
2368 topo["routers"][routerN]["bgp"]["address_family"][addr_type]["unicast"][
2369 "neighbor"
2370 ]["r1"]["dest_link"] = {"lo": {"password": "vmware"}}
2371 build_config_from_json(tgen, topo, save_bkup=False)
2372
2373 step("Verify all BGP sessions come up again due to identical passwords")
2374 result = verify_bgp_convergence(tgen, topo)
2375 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2376
2377 step("Remove password from R1")
2378 for bgp_neighbor in ["r2", "r3"]:
2379 for addr_type in ADDR_TYPES:
2380 topo["routers"]["r1"]["bgp"]["address_family"][addr_type]["unicast"][
2381 "neighbor"
2382 ][bgp_neighbor]["dest_link"] = {"lo": {"no_password": "vmware"}}
2383 build_config_from_json(tgen, topo, save_bkup=False)
2384
2385 step("Verify if password is removed from R1, both sessions go down again")
2386 result = verify_bgp_convergence(tgen, topo, expected=False)
2387 assert (
2388 result is not True
2389 ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format(
2390 tc_name, result
2391 )
2392
2393 step("Configure alphanumeric password on R1 and peer routers R2,R3")
2394 for bgp_neighbor in ["r2", "r3"]:
2395 for addr_type in ADDR_TYPES:
2396 topo["routers"]["r1"]["bgp"]["address_family"][addr_type]["unicast"][
2397 "neighbor"
2398 ][bgp_neighbor]["dest_link"] = {"lo": {"password": "Vmware@123"}}
2399 build_config_from_json(tgen, topo, save_bkup=False)
2400
2401 for routerN in ["r2", "r3"]:
2402 for addr_type in ADDR_TYPES:
2403 topo["routers"][routerN]["bgp"]["address_family"][addr_type]["unicast"][
2404 "neighbor"
2405 ]["r1"]["dest_link"] = {"lo": {"password": "Vmware@123"}}
2406 build_config_from_json(tgen, topo, save_bkup=False)
2407
2408 step(
2409 "Verify that sessions Come up irrespective of characters"
2410 "used in password string"
2411 )
2412 result = verify_bgp_convergence(tgen, topo)
2413 assert result is True, "Testcase {} : Failed \n Error : {}".format(tc_name, result)
2414
2415 write_test_footer(tc_name)
2416
2417
2418 if __name__ == "__main__":
2419 args = ["-s"] + sys.argv[1:]
2420 sys.exit(pytest.main(args))