]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py
Merge pull request #7755 from mjstapp/fix_rnh_via_default
[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 = {
afee014e
KK
285 "r1": {"bgp": {"local_as": 0,}},
286 "r2": {"bgp": {"local_as": 0,}},
287 "r3": {"bgp": {"local_as": 0,}},
288 "r4": {"bgp": {"local_as": 64000,}},
b7250ecf
KK
289 }
290 result = modify_as_number(tgen, topo, input_dict)
291 try:
292 assert result is True
293 except AssertionError:
294 logger.info("Expected behaviour: {}".format(result))
295 logger.info("BGP config is not created because of invalid ASNs")
296
297 write_test_footer(tc_name)
298
299
300def test_BGP_config_with_2byteAS_and_4byteAS_number_p1(request):
301 """
302 Configure BGP with 4 byte and 2 byte ASN and verify BGP is converged
303 """
304
305 tgen = get_topogen()
306 global BGP_CONVERGENCE
307
308 if BGP_CONVERGENCE != True:
afee014e 309 pytest.skip("skipped because of BGP Convergence failure")
b7250ecf
KK
310
311 # test case name
312 tc_name = request.node.name
313 write_test_header(tc_name)
314
315 # Api call to modify AS number
316 input_dict = {
afee014e
KK
317 "r1": {"bgp": {"local_as": 131079}},
318 "r2": {"bgp": {"local_as": 131079}},
319 "r3": {"bgp": {"local_as": 131079}},
320 "r4": {"bgp": {"local_as": 111}},
b7250ecf
KK
321 }
322 result = modify_as_number(tgen, topo, input_dict)
323 if result != True:
afee014e 324 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
325
326 result = verify_as_numbers(tgen, topo, input_dict)
327 if result != True:
afee014e 328 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
329
330 # Api call verify whether BGP is converged
331 result = verify_bgp_convergence(tgen, topo)
332 if result != True:
afee014e 333 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
334
335 write_test_footer(tc_name)
336
337
77ef1af6
AP
338def test_bgp_timers_functionality(request):
339 """
340 Test to modify bgp timers and verify timers functionality.
341 """
342
343 tgen = get_topogen()
344 if BGP_CONVERGENCE is not True:
787e7624 345 pytest.skip("skipped because of BGP Convergence failure")
77ef1af6
AP
346
347 # test case name
348 tc_name = request.node.name
349 write_test_header(tc_name)
350
351 # Creating configuration from JSON
352 reset_config_on_routers(tgen)
353
354 # Api call to modfiy BGP timerse
355 input_dict = {
356 "r1": {
357 "bgp": {
358 "address_family": {
359 "ipv4": {
360 "unicast": {
361 "neighbor": {
362 "r2": {
787e7624 363 "dest_link": {
77ef1af6 364 "r1": {
af9c65d4 365 "keepalivetimer": KEEPALIVETIMER,
787e7624 366 "holddowntimer": HOLDDOWNTIMER,
77ef1af6
AP
367 }
368 }
369 }
370 }
371 }
372 }
373 }
374 }
375 }
376 }
377 result = create_router_bgp(tgen, topo, deepcopy(input_dict))
787e7624 378 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
379
380 # Api call to clear bgp, so timer modification would take place
787e7624 381 clear_bgp_and_verify(tgen, topo, "r1")
77ef1af6
AP
382
383 # Verifying bgp timers functionality
384 result = verify_bgp_timers_and_functionality(tgen, topo, input_dict)
787e7624 385 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
386
387 write_test_footer(tc_name)
388
389
cb6b1d90
AP
390def test_static_routes(request):
391 """ Test to create and verify static routes. """
392
393 tgen = get_topogen()
394 if BGP_CONVERGENCE is not True:
787e7624 395 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
396
397 # test case name
398 tc_name = request.node.name
399 write_test_header(tc_name)
400
401 # Creating configuration from JSON
402 reset_config_on_routers(tgen)
403
404 # Api call to create static routes
405 input_dict = {
406 "r1": {
787e7624 407 "static_routes": [
408 {
409 "network": "10.0.20.1/32",
410 "no_of_ip": 9,
411 "admin_distance": 100,
412 "next_hop": "10.0.0.2",
413 }
414 ]
cb6b1d90
AP
415 }
416 }
417 result = create_static_routes(tgen, input_dict)
787e7624 418 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
419
420 # Api call to redistribute static routes
421 input_dict_1 = {
422 "r1": {
423 "bgp": {
424 "address_family": {
425 "ipv4": {
426 "unicast": {
427 "redistribute": [
428 {"redist_type": "static"},
787e7624 429 {"redist_type": "connected"},
cb6b1d90
AP
430 ]
431 }
432 }
433 }
434 }
435 }
436 }
437
438 result = create_router_bgp(tgen, topo, input_dict_1)
787e7624 439 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
440
441 # Verifying RIB routes
787e7624 442 dut = "r3"
443 protocol = "bgp"
444 next_hop = ["10.0.0.2", "10.0.0.5"]
445 result = verify_rib(
446 tgen, "ipv4", dut, input_dict, next_hop=next_hop, protocol=protocol
447 )
448 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
449
450 write_test_footer(tc_name)
451
452
453def test_admin_distance_for_existing_static_routes(request):
454 """ Test to modify and verify admin distance for existing static routes."""
455
456 tgen = get_topogen()
457 if BGP_CONVERGENCE is not True:
787e7624 458 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
459
460 # test case name
461 tc_name = request.node.name
462 write_test_header(tc_name)
463
464 # Creating configuration from JSON
465 reset_config_on_routers(tgen)
466
467 input_dict = {
468 "r1": {
787e7624 469 "static_routes": [
470 {
471 "network": "10.0.20.1/32",
472 "admin_distance": 10,
473 "next_hop": "10.0.0.2",
474 }
475 ]
cb6b1d90
AP
476 }
477 }
478 result = create_static_routes(tgen, input_dict)
787e7624 479 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
480
481 # Verifying admin distance once modified
482 result = verify_admin_distance_for_static_routes(tgen, input_dict)
787e7624 483 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
484
485 write_test_footer(tc_name)
486
487
488def test_advertise_network_using_network_command(request):
489 """ Test advertise networks using network command."""
490
491 tgen = get_topogen()
492 if BGP_CONVERGENCE is not True:
787e7624 493 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
494
495 # test case name
496 tc_name = request.node.name
497 write_test_header(tc_name)
498
499 # Creating configuration from JSON
500 reset_config_on_routers(tgen)
501
502 # Api call to advertise networks
503 input_dict = {
504 "r1": {
505 "bgp": {
506 "address_family": {
507 "ipv4": {
508 "unicast": {
509 "advertise_networks": [
787e7624 510 {"network": "20.0.0.0/32", "no_of_network": 10},
511 {"network": "30.0.0.0/32", "no_of_network": 10},
cb6b1d90
AP
512 ]
513 }
514 }
515 }
516 }
517 }
518 }
519
520 result = create_router_bgp(tgen, topo, input_dict)
787e7624 521 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
522
523 # Verifying RIB routes
787e7624 524 dut = "r2"
cb6b1d90 525 protocol = "bgp"
787e7624 526 result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol)
527 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
528
529 write_test_footer(tc_name)
530
531
532def test_clear_bgp_and_verify(request):
533 """
534 Created few static routes and verified all routes are learned via BGP
535 cleared BGP and verified all routes are intact
536 """
537
538 tgen = get_topogen()
539 if BGP_CONVERGENCE is not True:
787e7624 540 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
541
542 # test case name
543 tc_name = request.node.name
544 write_test_header(tc_name)
545
546 # Creating configuration from JSON
547 reset_config_on_routers(tgen)
548
549 # clear ip bgp
787e7624 550 result = clear_bgp_and_verify(tgen, topo, "r1")
551 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
552
553 write_test_footer(tc_name)
554
555
19f4da0b
KK
556def test_BGP_attributes_with_vrf_default_keyword_p0(request):
557 """
558 TC_9:
559 Verify BGP functionality for default vrf with
560 "vrf default" keyword.
561 """
562
563 tc_name = request.node.name
564 write_test_header(tc_name)
565 tgen = get_topogen()
566
567 if tgen.routers_have_failure():
568 pytest.skip(tgen.errors)
569
701a0192 570 # reset_config_on_routers(tgen)
19f4da0b
KK
571
572 step("Configure static routes and redistribute in BGP on R3")
573 for addr_type in ADDR_TYPES:
574 input_dict = {
575 "r3": {
576 "static_routes": [
577 {
578 "network": NETWORK[addr_type][0],
579 "no_of_ip": 4,
580 "next_hop": "Null0",
581 }
582 ]
583 }
584 }
585
586 result = create_static_routes(tgen, input_dict)
587 assert result is True, "Testcase {} : Failed \n Error: {}".format(
588 tc_name, result
589 )
590
591 input_dict_2 = {
592 "r3": {
593 "bgp": {
594 "address_family": {
595 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
596 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
597 }
598 }
599 }
600 }
601 result = create_router_bgp(tgen, topo, input_dict_2)
602 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
603
604 step(
605 "Create a route-map to match a specific prefix and modify"
606 "BGP attributes for matched prefix"
607 )
608 input_dict_2 = {
609 "r3": {
610 "prefix_lists": {
611 "ipv4": {
612 "ABC": [
613 {
614 "seqid": 10,
615 "action": "permit",
616 "network": NETWORK["ipv4"][0],
617 }
618 ]
619 },
620 "ipv6": {
621 "XYZ": [
622 {
623 "seqid": 100,
624 "action": "permit",
625 "network": NETWORK["ipv6"][0],
626 }
627 ]
628 },
629 }
630 }
631 }
632 result = create_prefix_lists(tgen, input_dict_2)
633 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
634
635 for addr_type in ADDR_TYPES:
636 if addr_type == "ipv4":
637 pf_list = "ABC"
638 else:
639 pf_list = "XYZ"
640
641 input_dict_6 = {
642 "r3": {
643 "route_maps": {
644 "BGP_ATTR_{}".format(addr_type): [
645 {
646 "action": "permit",
647 "seq_id": 10,
648 "match": {addr_type: {"prefix_lists": pf_list}},
649 "set": {
650 "aspath": {"as_num": 500, "as_action": "prepend"},
651 "localpref": 500,
652 "origin": "egp",
653 "community": {"num": "500:500", "action": "additive"},
654 "large_community": {
655 "num": "500:500:500",
656 "action": "additive",
657 },
658 },
659 },
660 {"action": "permit", "seq_id": 20},
661 ]
662 },
663 "BGP_ATTR_{}".format(addr_type): [
664 {
665 "action": "permit",
666 "seq_id": 100,
667 "match": {addr_type: {"prefix_lists": pf_list}},
668 "set": {
669 "aspath": {"as_num": 500, "as_action": "prepend"},
670 "localpref": 500,
671 "origin": "egp",
672 "community": {"num": "500:500", "action": "additive"},
673 "large_community": {
674 "num": "500:500:500",
675 "action": "additive",
676 },
677 },
678 },
679 {"action": "permit", "seq_id": 200},
680 ],
681 }
682 }
683
684 result = create_route_maps(tgen, input_dict_6)
685 assert result is True, "Testcase {} : Failed \n Error: {}".format(
686 tc_name, result
687 )
688
689 step("Apply the route-map on R3 in outbound direction for peer R4")
690
691 input_dict_7 = {
692 "r3": {
693 "bgp": {
694 "address_family": {
695 "ipv4": {
696 "unicast": {
697 "neighbor": {
698 "r4": {
699 "dest_link": {
700 "r3": {
701 "route_maps": [
702 {
703 "name": "BGP_ATTR_ipv4",
704 "direction": "out",
705 }
706 ]
707 }
708 }
709 }
710 }
711 }
712 },
713 "ipv6": {
714 "unicast": {
715 "neighbor": {
716 "r4": {
717 "dest_link": {
718 "r3": {
719 "route_maps": [
720 {
721 "name": "BGP_ATTR_ipv6",
722 "direction": "out",
723 }
724 ]
725 }
726 }
727 }
728 }
729 }
730 },
731 }
732 }
733 }
734 }
735
736 result = create_router_bgp(tgen, topo, input_dict_7)
737 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
738
739 step(
740 "verify modified attributes for specific prefix with 'vrf default'"
741 "keyword on R4"
742 )
743 for addr_type in ADDR_TYPES:
744 dut = "r4"
745 input_dict = {
746 "r3": {
747 "static_routes": [
748 {
749 "network": NETWORK[addr_type][0],
750 "vrf": "default",
751 "largeCommunity": "500:500:500",
752 }
753 ]
754 }
755 }
756
757 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
758 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
759 result = verify_rib(tgen, addr_type, dut, input_dict)
760 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
761
762 for addr_type in ADDR_TYPES:
763 dut = "r4"
764 input_dict = {
765 "r3": {
766 "static_routes": [
767 {
768 "network": NETWORK[addr_type][0],
769 "vrf": "default",
770 "community": "500:500",
771 }
772 ]
773 }
774 }
775
776 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
777 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
778 result = verify_rib(tgen, addr_type, dut, input_dict)
779 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
780
781 input_dict_4 = {"largeCommunity": "500:500:500", "community": "500:500"}
782
783 result = verify_bgp_community(
784 tgen, addr_type, dut, [NETWORK[addr_type][0]], input_dict_4
785 )
786 assert result is True, "Test case {} : Should fail \n Error: {}".format(
787 tc_name, result
788 )
789
790 write_test_footer(tc_name)
791
792
cb6b1d90
AP
793def test_bgp_with_loopback_interface(request):
794 """
795 Test BGP with loopback interface
796
797 Adding keys:value pair "dest_link": "lo" and "source_link": "lo"
798 peer dict of input json file for all router's creating config using
799 loopback interface. Once BGP neighboship is up then verifying BGP
800 convergence
801 """
802
803 tgen = get_topogen()
804 if BGP_CONVERGENCE is not True:
787e7624 805 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
806
807 # test case name
808 tc_name = request.node.name
809 write_test_header(tc_name)
810
811 # Creating configuration from JSON
812 reset_config_on_routers(tgen)
813
787e7624 814 for routerN in sorted(topo["routers"].keys()):
815 for bgp_neighbor in topo["routers"][routerN]["bgp"]["address_family"]["ipv4"][
816 "unicast"
817 ]["neighbor"].keys():
cb6b1d90
AP
818
819 # Adding ['source_link'] = 'lo' key:value pair
787e7624 820 topo["routers"][routerN]["bgp"]["address_family"]["ipv4"]["unicast"][
821 "neighbor"
822 ][bgp_neighbor]["dest_link"] = {"lo": {"source_link": "lo",}}
cb6b1d90
AP
823
824 # Creating configuration from JSON
825 build_config_from_json(tgen, topo)
826
827 input_dict = {
828 "r1": {
787e7624 829 "static_routes": [
830 {"network": "1.0.2.17/32", "next_hop": "10.0.0.2"},
831 {"network": "1.0.3.17/32", "next_hop": "10.0.0.6"},
cb6b1d90
AP
832 ]
833 },
834 "r2": {
787e7624 835 "static_routes": [
836 {"network": "1.0.1.17/32", "next_hop": "10.0.0.1"},
837 {"network": "1.0.3.17/32", "next_hop": "10.0.0.10"},
cb6b1d90
AP
838 ]
839 },
840 "r3": {
787e7624 841 "static_routes": [
842 {"network": "1.0.1.17/32", "next_hop": "10.0.0.5"},
843 {"network": "1.0.2.17/32", "next_hop": "10.0.0.9"},
844 {"network": "1.0.4.17/32", "next_hop": "10.0.0.14"},
cb6b1d90
AP
845 ]
846 },
787e7624 847 "r4": {"static_routes": [{"network": "1.0.3.17/32", "next_hop": "10.0.0.13"}]},
cb6b1d90
AP
848 }
849 result = create_static_routes(tgen, input_dict)
787e7624 850 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
851
852 # Api call verify whether BGP is converged
853 result = verify_bgp_convergence(tgen, topo)
787e7624 854 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
855
856 write_test_footer(tc_name)
857
858
19f4da0b
KK
859def test_bgp_with_loopback_with_same_subnet_p1(request):
860 """
861 Verify routes not installed in zebra when /32 routes received
862 with loopback BGP session subnet
863 """
864
865 tgen = get_topogen()
866 if BGP_CONVERGENCE is not True:
867 pytest.skip("skipped because of BGP Convergence failure")
868
869 # test case name
870 tc_name = request.node.name
871 write_test_header(tc_name)
872
873 # Creating configuration from JSON
874 reset_config_on_routers(tgen)
875 step("Delete BGP seesion created initially")
876 input_dict_r1 = {
877 "r1": {"bgp": {"delete": True}},
878 "r2": {"bgp": {"delete": True}},
879 "r3": {"bgp": {"delete": True}},
880 "r4": {"bgp": {"delete": True}},
881 }
882 result = create_router_bgp(tgen, topo, input_dict_r1)
883 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
884
885 step("Create BGP session over loop address")
886 topo_modify = deepcopy(topo)
887
888 for routerN in sorted(topo["routers"].keys()):
889 for addr_type in ADDR_TYPES:
890 for bgp_neighbor in topo_modify["routers"][routerN]["bgp"][
891 "address_family"
892 ][addr_type]["unicast"]["neighbor"].keys():
893
894 # Adding ['source_link'] = 'lo' key:value pair
895 topo_modify["routers"][routerN]["bgp"]["address_family"][addr_type][
896 "unicast"
897 ]["neighbor"][bgp_neighbor]["dest_link"] = {
898 "lo": {"source_link": "lo", "ebgp_multihop": 2}
899 }
900
901 result = create_router_bgp(tgen, topo_modify["routers"])
902 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
903
904 step("Disable IPv6 BGP nbr from ipv4 address family")
905 raw_config = {
906 "r1": {
907 "raw_config": [
908 "router bgp {}".format(topo["routers"]["r1"]["bgp"]["local_as"]),
909 "address-family ipv4 unicast",
910 "no neighbor {} activate".format(
911 topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
912 ),
913 "no neighbor {} activate".format(
914 topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
915 ),
916 ]
917 },
918 "r2": {
919 "raw_config": [
920 "router bgp {}".format(topo["routers"]["r2"]["bgp"]["local_as"]),
921 "address-family ipv4 unicast",
922 "no neighbor {} activate".format(
923 topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
924 ),
925 "no neighbor {} activate".format(
926 topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
927 ),
928 ]
929 },
930 "r3": {
931 "raw_config": [
932 "router bgp {}".format(topo["routers"]["r3"]["bgp"]["local_as"]),
933 "address-family ipv4 unicast",
934 "no neighbor {} activate".format(
935 topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
936 ),
937 "no neighbor {} activate".format(
938 topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
939 ),
940 "no neighbor {} activate".format(
941 topo["routers"]["r4"]["links"]["lo"]["ipv6"].split("/")[0]
942 ),
943 ]
944 },
945 "r4": {
946 "raw_config": [
947 "router bgp {}".format(topo["routers"]["r4"]["bgp"]["local_as"]),
948 "address-family ipv4 unicast",
949 "no neighbor {} activate".format(
950 topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
951 ),
952 ]
953 },
954 }
955
956 step("Configure kernel routes")
957 result = apply_raw_config(tgen, raw_config)
958 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
959
960 r1_ipv4_lo = topo["routers"]["r1"]["links"]["lo"]["ipv4"]
961 r1_ipv6_lo = topo["routers"]["r1"]["links"]["lo"]["ipv6"]
962 r2_ipv4_lo = topo["routers"]["r2"]["links"]["lo"]["ipv4"]
963 r2_ipv6_lo = topo["routers"]["r2"]["links"]["lo"]["ipv6"]
964 r3_ipv4_lo = topo["routers"]["r3"]["links"]["lo"]["ipv4"]
965 r3_ipv6_lo = topo["routers"]["r3"]["links"]["lo"]["ipv6"]
966 r4_ipv4_lo = topo["routers"]["r4"]["links"]["lo"]["ipv4"]
967 r4_ipv6_lo = topo["routers"]["r4"]["links"]["lo"]["ipv6"]
968
969 r1_r2 = topo["routers"]["r1"]["links"]["r2"]["ipv6"].split("/")[0]
970 r2_r1 = topo["routers"]["r2"]["links"]["r1"]["ipv6"].split("/")[0]
971 r1_r3 = topo["routers"]["r1"]["links"]["r3"]["ipv6"].split("/")[0]
972 r3_r1 = topo["routers"]["r3"]["links"]["r1"]["ipv6"].split("/")[0]
973 r2_r3 = topo["routers"]["r2"]["links"]["r3"]["ipv6"].split("/")[0]
974 r3_r2 = topo["routers"]["r3"]["links"]["r2"]["ipv6"].split("/")[0]
975 r3_r4 = topo["routers"]["r3"]["links"]["r4"]["ipv6"].split("/")[0]
976 r4_r3 = topo["routers"]["r4"]["links"]["r3"]["ipv6"].split("/")[0]
977
978 r1_r2_ipv4 = topo["routers"]["r1"]["links"]["r2"]["ipv4"].split("/")[0]
979 r2_r1_ipv4 = topo["routers"]["r2"]["links"]["r1"]["ipv4"].split("/")[0]
980 r1_r3_ipv4 = topo["routers"]["r1"]["links"]["r3"]["ipv4"].split("/")[0]
981 r3_r1_ipv4 = topo["routers"]["r3"]["links"]["r1"]["ipv4"].split("/")[0]
982 r2_r3_ipv4 = topo["routers"]["r2"]["links"]["r3"]["ipv4"].split("/")[0]
983 r3_r2_ipv4 = topo["routers"]["r3"]["links"]["r2"]["ipv4"].split("/")[0]
984 r3_r4_ipv4 = topo["routers"]["r3"]["links"]["r4"]["ipv4"].split("/")[0]
985 r4_r3_ipv4 = topo["routers"]["r4"]["links"]["r3"]["ipv4"].split("/")[0]
986
987 r1_r2_intf = topo["routers"]["r1"]["links"]["r2"]["interface"]
988 r2_r1_intf = topo["routers"]["r2"]["links"]["r1"]["interface"]
989 r1_r3_intf = topo["routers"]["r1"]["links"]["r3"]["interface"]
990 r3_r1_intf = topo["routers"]["r3"]["links"]["r1"]["interface"]
991 r2_r3_intf = topo["routers"]["r2"]["links"]["r3"]["interface"]
992 r3_r2_intf = topo["routers"]["r3"]["links"]["r2"]["interface"]
993 r3_r4_intf = topo["routers"]["r3"]["links"]["r4"]["interface"]
994 r4_r3_intf = topo["routers"]["r4"]["links"]["r3"]["interface"]
995
996 ipv4_list = [
997 ("r1", r1_r2_intf, r2_ipv4_loopback),
998 ("r1", r1_r3_intf, r3_ipv4_loopback),
999 ("r2", r2_r1_intf, r1_ipv4_loopback),
1000 ("r2", r2_r3_intf, r3_ipv4_loopback),
1001 ("r3", r3_r1_intf, r1_ipv4_loopback),
1002 ("r3", r3_r2_intf, r2_ipv4_loopback),
1003 ("r3", r3_r4_intf, r4_ipv4_loopback),
1004 ("r4", r4_r3_intf, r3_ipv4_loopback),
1005 ]
1006
1007 ipv6_list = [
1008 ("r1", r1_r2_intf, r2_ipv6_loopback, r2_r1),
1009 ("r1", r1_r3_intf, r3_ipv6_loopback, r3_r1),
1010 ("r2", r2_r1_intf, r1_ipv6_loopback, r1_r2),
1011 ("r2", r2_r3_intf, r3_ipv6_loopback, r3_r2),
1012 ("r3", r3_r1_intf, r1_ipv6_loopback, r1_r3),
1013 ("r3", r3_r2_intf, r2_ipv6_loopback, r2_r3),
1014 ("r3", r3_r4_intf, r4_ipv6_loopback, r4_r3),
1015 ("r4", r4_r3_intf, r3_ipv6_loopback, r3_r4),
1016 ]
1017
1018 for dut, intf, loop_addr in ipv4_list:
1019 result = addKernelRoute(tgen, dut, intf, loop_addr)
1020 assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
1021
1022 for dut, intf, loop_addr, next_hop in ipv6_list:
1023 result = addKernelRoute(tgen, dut, intf, loop_addr, next_hop)
1024 assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
1025
1026 step("Configure static routes")
1027
1028 input_dict = {
1029 "r1": {
1030 "static_routes": [
1031 {"network": r2_ipv4_loopback, "next_hop": r2_r1_ipv4},
1032 {"network": r3_ipv4_loopback, "next_hop": r3_r1_ipv4},
1033 {"network": r2_ipv6_loopback, "next_hop": r2_r1},
1034 {"network": r3_ipv6_loopback, "next_hop": r3_r1},
1035 ]
1036 },
1037 "r2": {
1038 "static_routes": [
1039 {"network": r1_ipv4_loopback, "next_hop": r1_r2_ipv4},
1040 {"network": r3_ipv4_loopback, "next_hop": r3_r2_ipv4},
1041 {"network": r1_ipv6_loopback, "next_hop": r1_r2},
1042 {"network": r3_ipv6_loopback, "next_hop": r3_r2},
1043 ]
1044 },
1045 "r3": {
1046 "static_routes": [
1047 {"network": r1_ipv4_loopback, "next_hop": r1_r3_ipv4},
1048 {"network": r2_ipv4_loopback, "next_hop": r2_r3_ipv4},
1049 {"network": r4_ipv4_loopback, "next_hop": r4_r3_ipv4},
1050 {"network": r1_ipv6_loopback, "next_hop": r1_r3},
1051 {"network": r2_ipv6_loopback, "next_hop": r2_r3},
1052 {"network": r4_ipv6_loopback, "next_hop": r4_r3},
1053 ]
1054 },
1055 "r4": {
1056 "static_routes": [
1057 {"network": r3_ipv4_loopback, "next_hop": r3_r4_ipv4},
1058 {"network": r3_ipv6_loopback, "next_hop": r3_r4},
1059 ]
1060 },
1061 }
1062 result = create_static_routes(tgen, input_dict)
1063 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1064
1065 step("Verify BGP session convergence")
1066
1067 result = verify_bgp_convergence(tgen, topo_modify)
1068 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1069
1070 step("Configure redistribute connected on R2 and R4")
1071 input_dict_1 = {
1072 "r2": {
1073 "bgp": {
1074 "address_family": {
1075 "ipv4": {
1076 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1077 },
1078 "ipv6": {
1079 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1080 },
1081 }
1082 }
1083 },
1084 "r4": {
1085 "bgp": {
1086 "address_family": {
1087 "ipv4": {
1088 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1089 },
1090 "ipv6": {
1091 "unicast": {"redistribute": [{"redist_type": "connected"}]}
1092 },
1093 }
1094 }
1095 },
1096 }
1097
1098 result = create_router_bgp(tgen, topo, input_dict_1)
1099 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
1100
1101 step("Verify Ipv4 and Ipv6 network installed in R1 RIB but not in FIB")
1102 input_dict_r1 = {
1103 "r1": {
1104 "static_routes": [
1105 {"network": "1.0.2.17/32"},
1106 {"network": "2001:db8:f::2:17/128"},
1107 ]
1108 }
1109 }
1110
1111 dut = "r1"
1112 protocol = "bgp"
1113 for addr_type in ADDR_TYPES:
1114 result = verify_rib(tgen, addr_type, dut, input_dict_r1, protocol=protocol)
1115 assert result is True, "Testcase {} :Failed \n Error: {}".format(
1116 tc_name, result
1117 )
1118
1119 result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
1120 assert result is not True, "Testcase {} : Failed \n"
1121 "Expected behavior: routes should not present in fib \n"
1122 "Error: {}".format(tc_name, result)
1123
1124 step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
1125 input_dict_r3 = {
1126 "r3": {
1127 "static_routes": [
1128 {"network": "1.0.4.17/32"},
1129 {"network": "2001:db8:f::4:17/128"},
1130 ]
1131 }
1132 }
1133 dut = "r3"
1134 protocol = "bgp"
1135 for addr_type in ADDR_TYPES:
1136 result = verify_rib(
1137 tgen, addr_type, dut, input_dict_r3, protocol=protocol, fib=None
1138 )
1139 assert result is True, "Testcase {} :Failed \n Error: {}".format(
1140 tc_name, result
1141 )
1142
1143 result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
1144 assert result is not True, "Testcase {} : Failed \n"
1145 "Expected behavior: routes should not present in fib \n"
1146 "Error: {}".format(tc_name, result)
1147
1148 write_test_footer(tc_name)
1149
1150
787e7624 1151if __name__ == "__main__":
7fa2079a
AP
1152 args = ["-s"] + sys.argv[1:]
1153 sys.exit(pytest.main(args))