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