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