]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py
Merge pull request #8164 from opensourcerouting/isisd-ti-lfa-fixes
[mirror_frr.git] / tests / topotests / bgp-basic-functionality-topo1 / test_bgp_basic_functionality.py
CommitLineData
7fa2079a
AP
1#!/usr/bin/env python
2
3#
4# Copyright (c) 2019 by VMware, Inc. ("VMware")
5# Used Copyright (c) 2018 by Network Device Education Foundation,
6# Inc. ("NetDEF") in this file.
7#
8# Permission to use, copy, modify, and/or distribute this software
9# for any purpose with or without fee is hereby granted, provided
10# that the above copyright notice and this permission notice appear
11# in all copies.
12#
13# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20# OF THIS SOFTWARE.
21#
22
23"""
24Following tests are covered to test BGP basic functionality:
25
26Test steps
27- Create topology (setup module)
28 Creating 4 routers topology, r1, r2, r3 are in IBGP and
29 r3, r4 are in EBGP
30- Bring up topology
31- Verify for bgp to converge
32- Modify/Delete and verify router-id
81e3d609
AP
33- Modify and verify bgp timers
34- Create and verify static routes
35- Modify and verify admin distance for existing static routes
36- Test advertise network using network command
37- Verify clear bgp
38- Test bgp convergence with loopback interface
39- Test advertise network using network command
19f4da0b
KK
40- Verify routes not installed in zebra when /32 routes received
41 with loopback BGP session subnet
7fa2079a
AP
42"""
43
44import os
45import sys
46import json
47import time
48import pytest
49from copy import deepcopy
3dfd384e 50
7fa2079a
AP
51# Save the Current Working Directory to find configuration files.
52CWD = os.path.dirname(os.path.realpath(__file__))
787e7624 53sys.path.append(os.path.join(CWD, "../"))
54sys.path.append(os.path.join(CWD, "../lib/"))
7fa2079a
AP
55
56# Required to instantiate the topology builder class.
57
58# pylint: disable=C0413
59# Import topogen and topotest helpers
60from lib.topogen import Topogen, get_topogen
61from mininet.topo import Topo
62
63from lib.common_config import (
19f4da0b 64 step,
787e7624 65 start_topology,
66 write_test_header,
67 write_test_footer,
68 reset_config_on_routers,
69 create_static_routes,
70 verify_rib,
71 verify_admin_distance_for_static_routes,
19f4da0b
KK
72 check_address_types,
73 apply_raw_config,
74 addKernelRoute,
75 verify_fib_routes,
76 create_prefix_lists,
77 create_route_maps,
78 verify_bgp_community,
701a0192 79 required_linux_kernel_version,
7fa2079a
AP
80)
81from lib.topolog import logger
82from lib.bgp import (
787e7624 83 verify_bgp_convergence,
84 create_router_bgp,
85 verify_router_id,
86 modify_as_number,
87 verify_as_numbers,
88 clear_bgp_and_verify,
89 verify_bgp_timers_and_functionality,
19f4da0b 90 verify_bgp_rib,
7fa2079a
AP
91)
92from lib.topojson import build_topo_from_json, build_config_from_json
93
94# Reading the data from JSON File for topology creation
95jsonFile = "{}/bgp_basic_functionality.json".format(CWD)
96try:
787e7624 97 with open(jsonFile, "r") as topoJson:
7fa2079a
AP
98 topo = json.load(topoJson)
99except IOError:
100 assert False, "Could not read file {}".format(jsonFile)
101
787e7624 102# Global Variable
af9c65d4
KK
103KEEPALIVETIMER = 2
104HOLDDOWNTIMER = 6
19f4da0b
KK
105r1_ipv4_loopback = "1.0.1.0/24"
106r2_ipv4_loopback = "1.0.2.0/24"
107r3_ipv4_loopback = "1.0.3.0/24"
108r4_ipv4_loopback = "1.0.4.0/24"
109r1_ipv6_loopback = "2001:db8:f::1:0/120"
110r2_ipv6_loopback = "2001:db8:f::2:0/120"
111r3_ipv6_loopback = "2001:db8:f::3:0/120"
112r4_ipv6_loopback = "2001:db8:f::4:0/120"
113NETWORK = {
114 "ipv4": ["100.1.1.1/32", "100.1.1.2/32"],
115 "ipv6": ["100::1/128", "100::2/128"],
116}
7fa2079a 117
787e7624 118
7fa2079a
AP
119class CreateTopo(Topo):
120 """
121 Test BasicTopo - topology 1
122
123 * `Topo`: Topology object
124 """
125
126 def build(self, *_args, **_opts):
127 """Build function"""
128 tgen = get_topogen(self)
129
130 # Building topology from json file
131 build_topo_from_json(tgen, topo)
132
133
134def setup_module(mod):
135 """
136 Sets up the pytest environment
137
138 * `mod`: module name
139 """
140
3dfd384e 141 # Required linux kernel version for this suite to run.
701a0192 142 result = required_linux_kernel_version("4.15")
955212d9 143 if result is not True:
144 pytest.skip("Kernel requirements are not met")
3dfd384e 145
7fa2079a
AP
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
19f4da0b 163 global ADDR_TYPES
7fa2079a 164 global BGP_CONVERGENCE
19f4da0b 165 ADDR_TYPES = check_address_types()
7fa2079a 166 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
787e7624 167 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
168 BGP_CONVERGENCE
169 )
7fa2079a
AP
170
171 logger.info("Running setup_module() done")
172
173
174def teardown_module():
175 """Teardown the pytest environment"""
176
177 logger.info("Running teardown_module to delete topology")
178
179 tgen = get_topogen()
180
181 # Stop toplogy and Remove tmp files
6bb29e5e 182 tgen.stop_topology()
7fa2079a 183
787e7624 184 logger.info(
185 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
186 )
7fa2079a
AP
187 logger.info("=" * 40)
188
189
190#####################################################
191#
192# Testcases
193#
194#####################################################
195
196
197def test_modify_and_delete_router_id(request):
198 """ Test to modify, delete and verify router-id. """
199
200 tgen = get_topogen()
201 if BGP_CONVERGENCE is not True:
787e7624 202 pytest.skip("skipped because of BGP Convergence failure")
7fa2079a
AP
203
204 # test case name
205 tc_name = request.node.name
206 write_test_header(tc_name)
207
208 # Modify router id
209 input_dict = {
787e7624 210 "r1": {"bgp": {"router_id": "12.12.12.12"}},
211 "r2": {"bgp": {"router_id": "22.22.22.22"}},
212 "r3": {"bgp": {"router_id": "33.33.33.33"}},
7fa2079a
AP
213 }
214 result = create_router_bgp(tgen, topo, input_dict)
787e7624 215 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
216
217 # Verifying router id once modified
218 result = verify_router_id(tgen, topo, input_dict)
787e7624 219 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
220
221 # Delete router id
222 input_dict = {
787e7624 223 "r1": {"bgp": {"del_router_id": True}},
224 "r2": {"bgp": {"del_router_id": True}},
225 "r3": {"bgp": {"del_router_id": True}},
7fa2079a
AP
226 }
227 result = create_router_bgp(tgen, topo, input_dict)
787e7624 228 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
229
230 # Verifying router id once deleted
231 # Once router-id is deleted, highest interface ip should become
232 # router-id
233 result = verify_router_id(tgen, topo, input_dict)
787e7624 234 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
235
236 write_test_footer(tc_name)
237
238
77ef1af6
AP
239def test_bgp_config_with_4byte_as_number(request):
240 """
241 Configure BGP with 4 byte ASN and verify it works fine
242 """
243
244 tgen = get_topogen()
245 if BGP_CONVERGENCE is not True:
787e7624 246 pytest.skip("skipped because of BGP Convergence failure")
77ef1af6
AP
247
248 # test case name
249 tc_name = request.node.name
250 write_test_header(tc_name)
251
252 input_dict = {
787e7624 253 "r1": {"bgp": {"local_as": 131079}},
254 "r2": {"bgp": {"local_as": 131079}},
255 "r3": {"bgp": {"local_as": 131079}},
256 "r4": {"bgp": {"local_as": 131080}},
77ef1af6
AP
257 }
258 result = modify_as_number(tgen, topo, input_dict)
787e7624 259 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
260
261 result = verify_as_numbers(tgen, topo, input_dict)
787e7624 262 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
263
264 write_test_footer(tc_name)
265
266
b7250ecf
KK
267def test_BGP_config_with_invalid_ASN_p2(request):
268 """
269 Configure BGP with invalid ASN(ex - 0, reserved ASN) and verify test case
270 ended up with error
271 """
272
273 tgen = get_topogen()
274 global BGP_CONVERGENCE
275
276 if BGP_CONVERGENCE != True:
afee014e 277 pytest.skip("skipped because of BGP Convergence failure")
b7250ecf
KK
278
279 # test case name
280 tc_name = request.node.name
281 write_test_header(tc_name)
282
283 # Api call to modify AS number
284 input_dict = {
9fa6ec14 285 "r1": {
286 "bgp": {
287 "local_as": 0,
288 }
289 },
290 "r2": {
291 "bgp": {
292 "local_as": 0,
293 }
294 },
295 "r3": {
296 "bgp": {
297 "local_as": 0,
298 }
299 },
300 "r4": {
301 "bgp": {
302 "local_as": 64000,
303 }
304 },
b7250ecf
KK
305 }
306 result = modify_as_number(tgen, topo, input_dict)
307 try:
308 assert result is True
309 except AssertionError:
310 logger.info("Expected behaviour: {}".format(result))
311 logger.info("BGP config is not created because of invalid ASNs")
312
313 write_test_footer(tc_name)
314
315
316def test_BGP_config_with_2byteAS_and_4byteAS_number_p1(request):
317 """
318 Configure BGP with 4 byte and 2 byte ASN and verify BGP is converged
319 """
320
321 tgen = get_topogen()
322 global BGP_CONVERGENCE
323
324 if BGP_CONVERGENCE != True:
afee014e 325 pytest.skip("skipped because of BGP Convergence failure")
b7250ecf
KK
326
327 # test case name
328 tc_name = request.node.name
329 write_test_header(tc_name)
330
331 # Api call to modify AS number
332 input_dict = {
afee014e
KK
333 "r1": {"bgp": {"local_as": 131079}},
334 "r2": {"bgp": {"local_as": 131079}},
335 "r3": {"bgp": {"local_as": 131079}},
336 "r4": {"bgp": {"local_as": 111}},
b7250ecf
KK
337 }
338 result = modify_as_number(tgen, topo, input_dict)
339 if result != True:
afee014e 340 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
341
342 result = verify_as_numbers(tgen, topo, input_dict)
343 if result != True:
afee014e 344 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
345
346 # Api call verify whether BGP is converged
347 result = verify_bgp_convergence(tgen, topo)
348 if result != True:
afee014e 349 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
350
351 write_test_footer(tc_name)
352
353
77ef1af6
AP
354def test_bgp_timers_functionality(request):
355 """
356 Test to modify bgp timers and verify timers functionality.
357 """
358
359 tgen = get_topogen()
360 if BGP_CONVERGENCE is not True:
787e7624 361 pytest.skip("skipped because of BGP Convergence failure")
77ef1af6
AP
362
363 # test case name
364 tc_name = request.node.name
365 write_test_header(tc_name)
366
367 # Creating configuration from JSON
368 reset_config_on_routers(tgen)
369
370 # Api call to modfiy BGP timerse
371 input_dict = {
372 "r1": {
373 "bgp": {
374 "address_family": {
375 "ipv4": {
376 "unicast": {
377 "neighbor": {
378 "r2": {
787e7624 379 "dest_link": {
77ef1af6 380 "r1": {
af9c65d4 381 "keepalivetimer": KEEPALIVETIMER,
787e7624 382 "holddowntimer": HOLDDOWNTIMER,
77ef1af6
AP
383 }
384 }
385 }
386 }
387 }
388 }
389 }
390 }
391 }
392 }
393 result = create_router_bgp(tgen, topo, deepcopy(input_dict))
787e7624 394 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
395
396 # Api call to clear bgp, so timer modification would take place
787e7624 397 clear_bgp_and_verify(tgen, topo, "r1")
77ef1af6
AP
398
399 # Verifying bgp timers functionality
400 result = verify_bgp_timers_and_functionality(tgen, topo, input_dict)
787e7624 401 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
402
403 write_test_footer(tc_name)
404
405
cb6b1d90
AP
406def test_static_routes(request):
407 """ Test to create and verify static routes. """
408
409 tgen = get_topogen()
410 if BGP_CONVERGENCE is not True:
787e7624 411 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
412
413 # test case name
414 tc_name = request.node.name
415 write_test_header(tc_name)
416
417 # Creating configuration from JSON
418 reset_config_on_routers(tgen)
419
420 # Api call to create static routes
421 input_dict = {
422 "r1": {
787e7624 423 "static_routes": [
424 {
425 "network": "10.0.20.1/32",
426 "no_of_ip": 9,
427 "admin_distance": 100,
428 "next_hop": "10.0.0.2",
429 }
430 ]
cb6b1d90
AP
431 }
432 }
433 result = create_static_routes(tgen, input_dict)
787e7624 434 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
435
436 # Api call to redistribute static routes
437 input_dict_1 = {
438 "r1": {
439 "bgp": {
440 "address_family": {
441 "ipv4": {
442 "unicast": {
443 "redistribute": [
444 {"redist_type": "static"},
787e7624 445 {"redist_type": "connected"},
cb6b1d90
AP
446 ]
447 }
448 }
449 }
450 }
451 }
452 }
453
454 result = create_router_bgp(tgen, topo, input_dict_1)
787e7624 455 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
456
457 # Verifying RIB routes
787e7624 458 dut = "r3"
459 protocol = "bgp"
460 next_hop = ["10.0.0.2", "10.0.0.5"]
461 result = verify_rib(
462 tgen, "ipv4", dut, input_dict, next_hop=next_hop, protocol=protocol
463 )
464 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
465
466 write_test_footer(tc_name)
467
468
469def test_admin_distance_for_existing_static_routes(request):
470 """ Test to modify and verify admin distance for existing static routes."""
471
472 tgen = get_topogen()
473 if BGP_CONVERGENCE is not True:
787e7624 474 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
475
476 # test case name
477 tc_name = request.node.name
478 write_test_header(tc_name)
479
480 # Creating configuration from JSON
481 reset_config_on_routers(tgen)
482
483 input_dict = {
484 "r1": {
787e7624 485 "static_routes": [
486 {
487 "network": "10.0.20.1/32",
488 "admin_distance": 10,
489 "next_hop": "10.0.0.2",
490 }
491 ]
cb6b1d90
AP
492 }
493 }
494 result = create_static_routes(tgen, input_dict)
787e7624 495 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
496
497 # Verifying admin distance once modified
498 result = verify_admin_distance_for_static_routes(tgen, input_dict)
787e7624 499 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
500
501 write_test_footer(tc_name)
502
503
504def test_advertise_network_using_network_command(request):
505 """ Test advertise networks using network command."""
506
507 tgen = get_topogen()
508 if BGP_CONVERGENCE is not True:
787e7624 509 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
510
511 # test case name
512 tc_name = request.node.name
513 write_test_header(tc_name)
514
515 # Creating configuration from JSON
516 reset_config_on_routers(tgen)
517
518 # Api call to advertise networks
519 input_dict = {
520 "r1": {
521 "bgp": {
522 "address_family": {
523 "ipv4": {
524 "unicast": {
525 "advertise_networks": [
787e7624 526 {"network": "20.0.0.0/32", "no_of_network": 10},
527 {"network": "30.0.0.0/32", "no_of_network": 10},
cb6b1d90
AP
528 ]
529 }
530 }
531 }
532 }
533 }
534 }
535
536 result = create_router_bgp(tgen, topo, input_dict)
787e7624 537 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
538
539 # Verifying RIB routes
787e7624 540 dut = "r2"
cb6b1d90 541 protocol = "bgp"
787e7624 542 result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol)
543 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
544
545 write_test_footer(tc_name)
546
547
548def test_clear_bgp_and_verify(request):
549 """
550 Created few static routes and verified all routes are learned via BGP
551 cleared BGP and verified all routes are intact
552 """
553
554 tgen = get_topogen()
555 if BGP_CONVERGENCE is not True:
787e7624 556 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
557
558 # test case name
559 tc_name = request.node.name
560 write_test_header(tc_name)
561
562 # Creating configuration from JSON
563 reset_config_on_routers(tgen)
564
565 # clear ip bgp
787e7624 566 result = clear_bgp_and_verify(tgen, topo, "r1")
567 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
568
569 write_test_footer(tc_name)
570
571
19f4da0b
KK
572def test_BGP_attributes_with_vrf_default_keyword_p0(request):
573 """
574 TC_9:
575 Verify BGP functionality for default vrf with
576 "vrf default" keyword.
577 """
578
579 tc_name = request.node.name
580 write_test_header(tc_name)
581 tgen = get_topogen()
582
583 if tgen.routers_have_failure():
584 pytest.skip(tgen.errors)
585
701a0192 586 # reset_config_on_routers(tgen)
19f4da0b
KK
587
588 step("Configure static routes and redistribute in BGP on R3")
589 for addr_type in ADDR_TYPES:
590 input_dict = {
591 "r3": {
592 "static_routes": [
593 {
594 "network": NETWORK[addr_type][0],
595 "no_of_ip": 4,
596 "next_hop": "Null0",
597 }
598 ]
599 }
600 }
601
602 result = create_static_routes(tgen, input_dict)
603 assert result is True, "Testcase {} : Failed \n Error: {}".format(
604 tc_name, result
605 )
606
607 input_dict_2 = {
608 "r3": {
609 "bgp": {
610 "address_family": {
611 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
612 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
613 }
614 }
615 }
616 }
617 result = create_router_bgp(tgen, topo, input_dict_2)
618 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
619
620 step(
621 "Create a route-map to match a specific prefix and modify"
622 "BGP attributes for matched prefix"
623 )
624 input_dict_2 = {
625 "r3": {
626 "prefix_lists": {
627 "ipv4": {
628 "ABC": [
629 {
630 "seqid": 10,
631 "action": "permit",
632 "network": NETWORK["ipv4"][0],
633 }
634 ]
635 },
636 "ipv6": {
637 "XYZ": [
638 {
639 "seqid": 100,
640 "action": "permit",
641 "network": NETWORK["ipv6"][0],
642 }
643 ]
644 },
645 }
646 }
647 }
648 result = create_prefix_lists(tgen, input_dict_2)
649 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
650
651 for addr_type in ADDR_TYPES:
652 if addr_type == "ipv4":
653 pf_list = "ABC"
654 else:
655 pf_list = "XYZ"
656
657 input_dict_6 = {
658 "r3": {
659 "route_maps": {
660 "BGP_ATTR_{}".format(addr_type): [
661 {
662 "action": "permit",
663 "seq_id": 10,
664 "match": {addr_type: {"prefix_lists": pf_list}},
665 "set": {
666 "aspath": {"as_num": 500, "as_action": "prepend"},
667 "localpref": 500,
668 "origin": "egp",
669 "community": {"num": "500:500", "action": "additive"},
670 "large_community": {
671 "num": "500:500:500",
672 "action": "additive",
673 },
674 },
675 },
676 {"action": "permit", "seq_id": 20},
677 ]
678 },
679 "BGP_ATTR_{}".format(addr_type): [
680 {
681 "action": "permit",
682 "seq_id": 100,
683 "match": {addr_type: {"prefix_lists": pf_list}},
684 "set": {
685 "aspath": {"as_num": 500, "as_action": "prepend"},
686 "localpref": 500,
687 "origin": "egp",
688 "community": {"num": "500:500", "action": "additive"},
689 "large_community": {
690 "num": "500:500:500",
691 "action": "additive",
692 },
693 },
694 },
695 {"action": "permit", "seq_id": 200},
696 ],
697 }
698 }
699
700 result = create_route_maps(tgen, input_dict_6)
701 assert result is True, "Testcase {} : Failed \n Error: {}".format(
702 tc_name, result
703 )
704
705 step("Apply the route-map on R3 in outbound direction for peer R4")
706
707 input_dict_7 = {
708 "r3": {
709 "bgp": {
710 "address_family": {
711 "ipv4": {
712 "unicast": {
713 "neighbor": {
714 "r4": {
715 "dest_link": {
716 "r3": {
717 "route_maps": [
718 {
719 "name": "BGP_ATTR_ipv4",
720 "direction": "out",
721 }
722 ]
723 }
724 }
725 }
726 }
727 }
728 },
729 "ipv6": {
730 "unicast": {
731 "neighbor": {
732 "r4": {
733 "dest_link": {
734 "r3": {
735 "route_maps": [
736 {
737 "name": "BGP_ATTR_ipv6",
738 "direction": "out",
739 }
740 ]
741 }
742 }
743 }
744 }
745 }
746 },
747 }
748 }
749 }
750 }
751
752 result = create_router_bgp(tgen, topo, input_dict_7)
753 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
754
755 step(
756 "verify modified attributes for specific prefix with 'vrf default'"
757 "keyword on R4"
758 )
759 for addr_type in ADDR_TYPES:
760 dut = "r4"
761 input_dict = {
762 "r3": {
763 "static_routes": [
764 {
765 "network": NETWORK[addr_type][0],
766 "vrf": "default",
767 "largeCommunity": "500:500:500",
768 }
769 ]
770 }
771 }
772
773 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
774 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
775 result = verify_rib(tgen, addr_type, dut, input_dict)
776 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
777
778 for addr_type in ADDR_TYPES:
779 dut = "r4"
780 input_dict = {
781 "r3": {
782 "static_routes": [
783 {
784 "network": NETWORK[addr_type][0],
785 "vrf": "default",
786 "community": "500:500",
787 }
788 ]
789 }
790 }
791
792 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
793 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
794 result = verify_rib(tgen, addr_type, dut, input_dict)
795 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
796
797 input_dict_4 = {"largeCommunity": "500:500:500", "community": "500:500"}
798
799 result = verify_bgp_community(
800 tgen, addr_type, dut, [NETWORK[addr_type][0]], input_dict_4
801 )
802 assert result is True, "Test case {} : Should fail \n Error: {}".format(
803 tc_name, result
804 )
805
806 write_test_footer(tc_name)
807
808
cb6b1d90
AP
809def test_bgp_with_loopback_interface(request):
810 """
811 Test BGP with loopback interface
812
813 Adding keys:value pair "dest_link": "lo" and "source_link": "lo"
814 peer dict of input json file for all router's creating config using
815 loopback interface. Once BGP neighboship is up then verifying BGP
816 convergence
817 """
818
819 tgen = get_topogen()
820 if BGP_CONVERGENCE is not True:
787e7624 821 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
822
823 # test case name
824 tc_name = request.node.name
825 write_test_header(tc_name)
826
827 # Creating configuration from JSON
828 reset_config_on_routers(tgen)
829
787e7624 830 for routerN in sorted(topo["routers"].keys()):
831 for bgp_neighbor in topo["routers"][routerN]["bgp"]["address_family"]["ipv4"][
832 "unicast"
833 ]["neighbor"].keys():
cb6b1d90
AP
834
835 # Adding ['source_link'] = 'lo' key:value pair
787e7624 836 topo["routers"][routerN]["bgp"]["address_family"]["ipv4"]["unicast"][
837 "neighbor"
9fa6ec14 838 ][bgp_neighbor]["dest_link"] = {
839 "lo": {
840 "source_link": "lo",
841 }
842 }
cb6b1d90
AP
843
844 # Creating configuration from JSON
845 build_config_from_json(tgen, topo)
846
847 input_dict = {
848 "r1": {
787e7624 849 "static_routes": [
850 {"network": "1.0.2.17/32", "next_hop": "10.0.0.2"},
851 {"network": "1.0.3.17/32", "next_hop": "10.0.0.6"},
cb6b1d90
AP
852 ]
853 },
854 "r2": {
787e7624 855 "static_routes": [
856 {"network": "1.0.1.17/32", "next_hop": "10.0.0.1"},
857 {"network": "1.0.3.17/32", "next_hop": "10.0.0.10"},
cb6b1d90
AP
858 ]
859 },
860 "r3": {
787e7624 861 "static_routes": [
862 {"network": "1.0.1.17/32", "next_hop": "10.0.0.5"},
863 {"network": "1.0.2.17/32", "next_hop": "10.0.0.9"},
864 {"network": "1.0.4.17/32", "next_hop": "10.0.0.14"},
cb6b1d90
AP
865 ]
866 },
787e7624 867 "r4": {"static_routes": [{"network": "1.0.3.17/32", "next_hop": "10.0.0.13"}]},
cb6b1d90
AP
868 }
869 result = create_static_routes(tgen, input_dict)
787e7624 870 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
871
872 # Api call verify whether BGP is converged
873 result = verify_bgp_convergence(tgen, topo)
787e7624 874 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
875
876 write_test_footer(tc_name)
877
878
19f4da0b
KK
879def test_bgp_with_loopback_with_same_subnet_p1(request):
880 """
881 Verify routes not installed in zebra when /32 routes received
882 with loopback BGP session subnet
883 """
884
885 tgen = get_topogen()
886 if BGP_CONVERGENCE is not True:
887 pytest.skip("skipped because of BGP Convergence failure")
888
889 # test case name
890 tc_name = request.node.name
891 write_test_header(tc_name)
892
893 # Creating configuration from JSON
894 reset_config_on_routers(tgen)
895 step("Delete BGP seesion created initially")
896 input_dict_r1 = {
897 "r1": {"bgp": {"delete": True}},
898 "r2": {"bgp": {"delete": True}},
899 "r3": {"bgp": {"delete": True}},
900 "r4": {"bgp": {"delete": True}},
901 }
902 result = create_router_bgp(tgen, topo, input_dict_r1)
903 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
904
905 step("Create BGP session over loop address")
906 topo_modify = deepcopy(topo)
907
908 for routerN in sorted(topo["routers"].keys()):
909 for addr_type in ADDR_TYPES:
910 for bgp_neighbor in topo_modify["routers"][routerN]["bgp"][
911 "address_family"
912 ][addr_type]["unicast"]["neighbor"].keys():
913
914 # Adding ['source_link'] = 'lo' key:value pair
915 topo_modify["routers"][routerN]["bgp"]["address_family"][addr_type][
916 "unicast"
917 ]["neighbor"][bgp_neighbor]["dest_link"] = {
918 "lo": {"source_link": "lo", "ebgp_multihop": 2}
919 }
920
921 result = create_router_bgp(tgen, topo_modify["routers"])
922 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
923
924 step("Disable IPv6 BGP nbr from ipv4 address family")
925 raw_config = {
926 "r1": {
927 "raw_config": [
928 "router bgp {}".format(topo["routers"]["r1"]["bgp"]["local_as"]),
929 "address-family ipv4 unicast",
930 "no neighbor {} activate".format(
931 topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
932 ),
933 "no neighbor {} activate".format(
934 topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
935 ),
936 ]
937 },
938 "r2": {
939 "raw_config": [
940 "router bgp {}".format(topo["routers"]["r2"]["bgp"]["local_as"]),
941 "address-family ipv4 unicast",
942 "no neighbor {} activate".format(
943 topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
944 ),
945 "no neighbor {} activate".format(
946 topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
947 ),
948 ]
949 },
950 "r3": {
951 "raw_config": [
952 "router bgp {}".format(topo["routers"]["r3"]["bgp"]["local_as"]),
953 "address-family ipv4 unicast",
954 "no neighbor {} activate".format(
955 topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
956 ),
957 "no neighbor {} activate".format(
958 topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
959 ),
960 "no neighbor {} activate".format(
961 topo["routers"]["r4"]["links"]["lo"]["ipv6"].split("/")[0]
962 ),
963 ]
964 },
965 "r4": {
966 "raw_config": [
967 "router bgp {}".format(topo["routers"]["r4"]["bgp"]["local_as"]),
968 "address-family ipv4 unicast",
969 "no neighbor {} activate".format(
970 topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
971 ),
972 ]
973 },
974 }
975
976 step("Configure kernel routes")
977 result = apply_raw_config(tgen, raw_config)
978 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
979
980 r1_ipv4_lo = topo["routers"]["r1"]["links"]["lo"]["ipv4"]
981 r1_ipv6_lo = topo["routers"]["r1"]["links"]["lo"]["ipv6"]
982 r2_ipv4_lo = topo["routers"]["r2"]["links"]["lo"]["ipv4"]
983 r2_ipv6_lo = topo["routers"]["r2"]["links"]["lo"]["ipv6"]
984 r3_ipv4_lo = topo["routers"]["r3"]["links"]["lo"]["ipv4"]
985 r3_ipv6_lo = topo["routers"]["r3"]["links"]["lo"]["ipv6"]
986 r4_ipv4_lo = topo["routers"]["r4"]["links"]["lo"]["ipv4"]
987 r4_ipv6_lo = topo["routers"]["r4"]["links"]["lo"]["ipv6"]
988
989 r1_r2 = topo["routers"]["r1"]["links"]["r2"]["ipv6"].split("/")[0]
990 r2_r1 = topo["routers"]["r2"]["links"]["r1"]["ipv6"].split("/")[0]
991 r1_r3 = topo["routers"]["r1"]["links"]["r3"]["ipv6"].split("/")[0]
992 r3_r1 = topo["routers"]["r3"]["links"]["r1"]["ipv6"].split("/")[0]
993 r2_r3 = topo["routers"]["r2"]["links"]["r3"]["ipv6"].split("/")[0]
994 r3_r2 = topo["routers"]["r3"]["links"]["r2"]["ipv6"].split("/")[0]
995 r3_r4 = topo["routers"]["r3"]["links"]["r4"]["ipv6"].split("/")[0]
996 r4_r3 = topo["routers"]["r4"]["links"]["r3"]["ipv6"].split("/")[0]
997
998 r1_r2_ipv4 = topo["routers"]["r1"]["links"]["r2"]["ipv4"].split("/")[0]
999 r2_r1_ipv4 = topo["routers"]["r2"]["links"]["r1"]["ipv4"].split("/")[0]
1000 r1_r3_ipv4 = topo["routers"]["r1"]["links"]["r3"]["ipv4"].split("/")[0]
1001 r3_r1_ipv4 = topo["routers"]["r3"]["links"]["r1"]["ipv4"].split("/")[0]
1002 r2_r3_ipv4 = topo["routers"]["r2"]["links"]["r3"]["ipv4"].split("/")[0]
1003 r3_r2_ipv4 = topo["routers"]["r3"]["links"]["r2"]["ipv4"].split("/")[0]
1004 r3_r4_ipv4 = topo["routers"]["r3"]["links"]["r4"]["ipv4"].split("/")[0]
1005 r4_r3_ipv4 = topo["routers"]["r4"]["links"]["r3"]["ipv4"].split("/")[0]
1006
1007 r1_r2_intf = topo["routers"]["r1"]["links"]["r2"]["interface"]
1008 r2_r1_intf = topo["routers"]["r2"]["links"]["r1"]["interface"]
1009 r1_r3_intf = topo["routers"]["r1"]["links"]["r3"]["interface"]
1010 r3_r1_intf = topo["routers"]["r3"]["links"]["r1"]["interface"]
1011 r2_r3_intf = topo["routers"]["r2"]["links"]["r3"]["interface"]
1012 r3_r2_intf = topo["routers"]["r3"]["links"]["r2"]["interface"]
1013 r3_r4_intf = topo["routers"]["r3"]["links"]["r4"]["interface"]
1014 r4_r3_intf = topo["routers"]["r4"]["links"]["r3"]["interface"]
1015
1016 ipv4_list = [
1017 ("r1", r1_r2_intf, r2_ipv4_loopback),
1018 ("r1", r1_r3_intf, r3_ipv4_loopback),
1019 ("r2", r2_r1_intf, r1_ipv4_loopback),
1020 ("r2", r2_r3_intf, r3_ipv4_loopback),
1021 ("r3", r3_r1_intf, r1_ipv4_loopback),
1022 ("r3", r3_r2_intf, r2_ipv4_loopback),
1023 ("r3", r3_r4_intf, r4_ipv4_loopback),
1024 ("r4", r4_r3_intf, r3_ipv4_loopback),
1025 ]
1026
1027 ipv6_list = [
1028 ("r1", r1_r2_intf, r2_ipv6_loopback, r2_r1),
1029 ("r1", r1_r3_intf, r3_ipv6_loopback, r3_r1),
1030 ("r2", r2_r1_intf, r1_ipv6_loopback, r1_r2),
1031 ("r2", r2_r3_intf, r3_ipv6_loopback, r3_r2),
1032 ("r3", r3_r1_intf, r1_ipv6_loopback, r1_r3),
1033 ("r3", r3_r2_intf, r2_ipv6_loopback, r2_r3),
1034 ("r3", r3_r4_intf, r4_ipv6_loopback, r4_r3),
1035 ("r4", r4_r3_intf, r3_ipv6_loopback, r3_r4),
1036 ]
1037
1038 for dut, intf, loop_addr in ipv4_list:
1039 result = addKernelRoute(tgen, dut, intf, loop_addr)
1040 assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
1041
1042 for dut, intf, loop_addr, next_hop in ipv6_list:
1043 result = addKernelRoute(tgen, dut, intf, loop_addr, next_hop)
1044 assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
1045
1046 step("Configure static routes")
1047
1048 input_dict = {
1049 "r1": {
1050 "static_routes": [
1051 {"network": r2_ipv4_loopback, "next_hop": r2_r1_ipv4},
1052 {"network": r3_ipv4_loopback, "next_hop": r3_r1_ipv4},
1053 {"network": r2_ipv6_loopback, "next_hop": r2_r1},
1054 {"network": r3_ipv6_loopback, "next_hop": r3_r1},
1055 ]
1056 },
1057 "r2": {
1058 "static_routes": [
1059 {"network": r1_ipv4_loopback, "next_hop": r1_r2_ipv4},
1060 {"network": r3_ipv4_loopback, "next_hop": r3_r2_ipv4},
1061 {"network": r1_ipv6_loopback, "next_hop": r1_r2},
1062 {"network": r3_ipv6_loopback, "next_hop": r3_r2},
1063 ]
1064 },
1065 "r3": {
1066 "static_routes": [
1067 {"network": r1_ipv4_loopback, "next_hop": r1_r3_ipv4},
1068 {"network": r2_ipv4_loopback, "next_hop": r2_r3_ipv4},
1069 {"network": r4_ipv4_loopback, "next_hop": r4_r3_ipv4},
1070 {"network": r1_ipv6_loopback, "next_hop": r1_r3},
1071 {"network": r2_ipv6_loopback, "next_hop": r2_r3},
1072 {"network": r4_ipv6_loopback, "next_hop": r4_r3},
1073 ]
1074 },
1075 "r4": {
1076 "static_routes": [
1077 {"network": r3_ipv4_loopback, "next_hop": r3_r4_ipv4},
1078 {"network": r3_ipv6_loopback, "next_hop": r3_r4},
1079 ]
1080 },
1081 }
1082 result = create_static_routes(tgen, input_dict)
1083 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1084
1085 step("Verify BGP session convergence")
1086
1087 result = verify_bgp_convergence(tgen, topo_modify)
1088 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1089
1090 step("Configure redistribute connected on R2 and R4")
1091 input_dict_1 = {
1092 "r2": {
1093 "bgp": {
1094 "address_family": {
1095 "ipv4": {
1096 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1097 },
1098 "ipv6": {
1099 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1100 },
1101 }
1102 }
1103 },
1104 "r4": {
1105 "bgp": {
1106 "address_family": {
1107 "ipv4": {
1108 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1109 },
1110 "ipv6": {
1111 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1112 },
1113 }
1114 }
1115 },
1116 }
1117
1118 result = create_router_bgp(tgen, topo, input_dict_1)
1119 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1120
1121 step("Verify Ipv4 and Ipv6 network installed in R1 RIB but not in FIB")
1122 input_dict_r1 = {
1123 "r1": {
1124 "static_routes": [
1125 {"network": "1.0.2.17/32"},
1126 {"network": "2001:db8:f::2:17/128"},
1127 ]
1128 }
1129 }
1130
1131 dut = "r1"
1132 protocol = "bgp"
1133 for addr_type in ADDR_TYPES:
1134 result = verify_rib(tgen, addr_type, dut, input_dict_r1, protocol=protocol)
1135 assert result is True, "Testcase {} :Failed \n Error: {}".format(
1136 tc_name, result
1137 )
1138
1139 result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
1140 assert result is not True, "Testcase {} : Failed \n"
1141 "Expected behavior: routes should not present in fib \n"
1142 "Error: {}".format(tc_name, result)
1143
1144 step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
1145 input_dict_r3 = {
1146 "r3": {
1147 "static_routes": [
1148 {"network": "1.0.4.17/32"},
1149 {"network": "2001:db8:f::4:17/128"},
1150 ]
1151 }
1152 }
1153 dut = "r3"
1154 protocol = "bgp"
1155 for addr_type in ADDR_TYPES:
1156 result = verify_rib(
1157 tgen, addr_type, dut, input_dict_r3, protocol=protocol, fib=None
1158 )
1159 assert result is True, "Testcase {} :Failed \n Error: {}".format(
1160 tc_name, result
1161 )
1162
1163 result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
1164 assert result is not True, "Testcase {} : Failed \n"
1165 "Expected behavior: routes should not present in fib \n"
1166 "Error: {}".format(tc_name, result)
1167
1168 write_test_footer(tc_name)
1169
1170
787e7624 1171if __name__ == "__main__":
7fa2079a
AP
1172 args = ["-s"] + sys.argv[1:]
1173 sys.exit(pytest.main(args))