]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/bgp_basic_functionality_topo1/test_bgp_basic_functionality.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_basic_functionality_topo1 / test_bgp_basic_functionality.py
CommitLineData
7fa2079a 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
7fa2079a
AP
3
4#
5# Copyright (c) 2019 by VMware, Inc. ("VMware")
6# Used Copyright (c) 2018 by Network Device Education Foundation,
7# Inc. ("NetDEF") in this file.
8#
7fa2079a
AP
9
10"""
11Following tests are covered to test BGP basic functionality:
12
13Test steps
14- Create topology (setup module)
15 Creating 4 routers topology, r1, r2, r3 are in IBGP and
16 r3, r4 are in EBGP
17- Bring up topology
18- Verify for bgp to converge
19- Modify/Delete and verify router-id
81e3d609
AP
20- Modify and verify bgp timers
21- Create and verify static routes
22- Modify and verify admin distance for existing static routes
23- Test advertise network using network command
24- Verify clear bgp
25- Test bgp convergence with loopback interface
26- Test advertise network using network command
19f4da0b
KK
27- Verify routes not installed in zebra when /32 routes received
28 with loopback BGP session subnet
7fa2079a 29"""
d7d21c3a
CH
30# XXX clean up in later commit to avoid conflict on rebase
31# pylint: disable=C0413
7fa2079a
AP
32
33import os
34import sys
7fa2079a
AP
35import time
36import pytest
37from copy import deepcopy
3dfd384e 38
7fa2079a
AP
39# Save the Current Working Directory to find configuration files.
40CWD = os.path.dirname(os.path.realpath(__file__))
787e7624 41sys.path.append(os.path.join(CWD, "../"))
42sys.path.append(os.path.join(CWD, "../lib/"))
7fa2079a
AP
43
44# Required to instantiate the topology builder class.
45
a53c08bc
CH
46from lib.bgp import (
47 clear_bgp_and_verify,
48 create_router_bgp,
49 modify_as_number,
50 verify_as_numbers,
51 verify_bgp_convergence,
52 verify_bgp_rib,
53 verify_bgp_timers_and_functionality,
54 verify_router_id,
55)
56from lib.common_config import (
57 addKernelRoute,
58 apply_raw_config,
59 check_address_types,
60 create_prefix_lists,
61 create_route_maps,
62 create_static_routes,
63 required_linux_kernel_version,
64 reset_config_on_routers,
65 start_topology,
66 step,
67 verify_admin_distance_for_static_routes,
68 verify_bgp_community,
69 verify_fib_routes,
70 verify_rib,
71 write_test_footer,
72 write_test_header,
73)
74
7fa2079a
AP
75# pylint: disable=C0413
76# Import topogen and topotest helpers
77from lib.topogen import Topogen, get_topogen
4953ca97 78from lib.topojson import build_config_from_json
7fa2079a 79from lib.topolog import logger
7fa2079a 80
5ad1fd54
DS
81pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
82
83
787e7624 84# Global Variable
af9c65d4
KK
85KEEPALIVETIMER = 2
86HOLDDOWNTIMER = 6
19f4da0b
KK
87r1_ipv4_loopback = "1.0.1.0/24"
88r2_ipv4_loopback = "1.0.2.0/24"
89r3_ipv4_loopback = "1.0.3.0/24"
90r4_ipv4_loopback = "1.0.4.0/24"
91r1_ipv6_loopback = "2001:db8:f::1:0/120"
92r2_ipv6_loopback = "2001:db8:f::2:0/120"
93r3_ipv6_loopback = "2001:db8:f::3:0/120"
94r4_ipv6_loopback = "2001:db8:f::4:0/120"
95NETWORK = {
96 "ipv4": ["100.1.1.1/32", "100.1.1.2/32"],
97 "ipv6": ["100::1/128", "100::2/128"],
98}
7fa2079a 99
787e7624 100
7fa2079a
AP
101def setup_module(mod):
102 """
103 Sets up the pytest environment
104
105 * `mod`: module name
106 """
107
3dfd384e 108 # Required linux kernel version for this suite to run.
701a0192 109 result = required_linux_kernel_version("4.15")
955212d9 110 if result is not True:
d63c7094 111 pytest.skip("Kernel requirements are not met, kernel version should be >=4.15")
3dfd384e 112
7fa2079a
AP
113 testsuite_run_time = time.asctime(time.localtime(time.time()))
114 logger.info("Testsuite start time: {}".format(testsuite_run_time))
115 logger.info("=" * 40)
116
117 logger.info("Running setup_module to create topology")
118
119 # This function initiates the topology build with Topogen...
e82b531d
CH
120 json_file = "{}/bgp_basic_functionality.json".format(CWD)
121 tgen = Topogen(json_file, mod.__name__)
122 global topo
123 topo = tgen.json_topo
7fa2079a
AP
124 # ... and here it calls Mininet initialization functions.
125
126 # Starting topology, create tmp files which are loaded to routers
d60a3f0e 127 # to start daemons and then start routers
7fa2079a
AP
128 start_topology(tgen)
129
130 # Creating configuration from JSON
131 build_config_from_json(tgen, topo)
132
19f4da0b 133 global ADDR_TYPES
7fa2079a 134 global BGP_CONVERGENCE
19f4da0b 135 ADDR_TYPES = check_address_types()
7fa2079a 136 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
787e7624 137 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
138 BGP_CONVERGENCE
139 )
7fa2079a
AP
140
141 logger.info("Running setup_module() done")
142
143
144def teardown_module():
145 """Teardown the pytest environment"""
146
147 logger.info("Running teardown_module to delete topology")
148
149 tgen = get_topogen()
150
151 # Stop toplogy and Remove tmp files
6bb29e5e 152 tgen.stop_topology()
7fa2079a 153
787e7624 154 logger.info(
155 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
156 )
7fa2079a
AP
157 logger.info("=" * 40)
158
159
160#####################################################
161#
162# Testcases
163#
164#####################################################
165
166
167def test_modify_and_delete_router_id(request):
a53c08bc 168 """Test to modify, delete and verify router-id."""
7fa2079a
AP
169
170 tgen = get_topogen()
171 if BGP_CONVERGENCE is not True:
787e7624 172 pytest.skip("skipped because of BGP Convergence failure")
7fa2079a
AP
173
174 # test case name
175 tc_name = request.node.name
176 write_test_header(tc_name)
177
b86955a6
CH
178 # Creating configuration from JSON
179 reset_config_on_routers(tgen)
180
7fa2079a
AP
181 # Modify router id
182 input_dict = {
787e7624 183 "r1": {"bgp": {"router_id": "12.12.12.12"}},
184 "r2": {"bgp": {"router_id": "22.22.22.22"}},
185 "r3": {"bgp": {"router_id": "33.33.33.33"}},
7fa2079a
AP
186 }
187 result = create_router_bgp(tgen, topo, input_dict)
787e7624 188 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
189
190 # Verifying router id once modified
191 result = verify_router_id(tgen, topo, input_dict)
787e7624 192 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
193
194 # Delete router id
195 input_dict = {
787e7624 196 "r1": {"bgp": {"del_router_id": True}},
197 "r2": {"bgp": {"del_router_id": True}},
198 "r3": {"bgp": {"del_router_id": True}},
7fa2079a
AP
199 }
200 result = create_router_bgp(tgen, topo, input_dict)
787e7624 201 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
202
203 # Verifying router id once deleted
204 # Once router-id is deleted, highest interface ip should become
205 # router-id
206 result = verify_router_id(tgen, topo, input_dict)
787e7624 207 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
7fa2079a
AP
208
209 write_test_footer(tc_name)
210
211
77ef1af6
AP
212def test_bgp_config_with_4byte_as_number(request):
213 """
214 Configure BGP with 4 byte ASN and verify it works fine
215 """
216
217 tgen = get_topogen()
218 if BGP_CONVERGENCE is not True:
787e7624 219 pytest.skip("skipped because of BGP Convergence failure")
77ef1af6
AP
220
221 # test case name
222 tc_name = request.node.name
223 write_test_header(tc_name)
224
b86955a6
CH
225 # Creating configuration from JSON
226 reset_config_on_routers(tgen)
227
77ef1af6 228 input_dict = {
787e7624 229 "r1": {"bgp": {"local_as": 131079}},
230 "r2": {"bgp": {"local_as": 131079}},
231 "r3": {"bgp": {"local_as": 131079}},
232 "r4": {"bgp": {"local_as": 131080}},
77ef1af6
AP
233 }
234 result = modify_as_number(tgen, topo, input_dict)
787e7624 235 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
236
237 result = verify_as_numbers(tgen, topo, input_dict)
787e7624 238 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
239
240 write_test_footer(tc_name)
241
242
b7250ecf
KK
243def test_BGP_config_with_invalid_ASN_p2(request):
244 """
245 Configure BGP with invalid ASN(ex - 0, reserved ASN) and verify test case
246 ended up with error
247 """
248
249 tgen = get_topogen()
250 global BGP_CONVERGENCE
251
252 if BGP_CONVERGENCE != True:
afee014e 253 pytest.skip("skipped because of BGP Convergence failure")
b7250ecf
KK
254
255 # test case name
256 tc_name = request.node.name
257 write_test_header(tc_name)
258
b86955a6
CH
259 # Creating configuration from JSON
260 reset_config_on_routers(tgen)
261
b7250ecf
KK
262 # Api call to modify AS number
263 input_dict = {
9fa6ec14 264 "r1": {
265 "bgp": {
266 "local_as": 0,
267 }
268 },
269 "r2": {
270 "bgp": {
271 "local_as": 0,
272 }
273 },
274 "r3": {
275 "bgp": {
276 "local_as": 0,
277 }
278 },
279 "r4": {
280 "bgp": {
281 "local_as": 64000,
282 }
283 },
b7250ecf
KK
284 }
285 result = modify_as_number(tgen, topo, input_dict)
a53c08bc
CH
286 assert (
287 result is not True
288 ), "Expected BGP config is not created because of invalid ASNs: {}".format(result)
b86955a6
CH
289
290 # Creating configuration from JSON
291 reset_config_on_routers(tgen)
292
293 result = verify_bgp_convergence(tgen, topo)
294 if result != True:
295 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
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
b86955a6
CH
315 # Creating configuration from JSON
316 reset_config_on_routers(tgen)
317
318 result = verify_bgp_convergence(tgen, topo)
319 if result != True:
320 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
321
b7250ecf
KK
322 # Api call to modify AS number
323 input_dict = {
afee014e
KK
324 "r1": {"bgp": {"local_as": 131079}},
325 "r2": {"bgp": {"local_as": 131079}},
326 "r3": {"bgp": {"local_as": 131079}},
327 "r4": {"bgp": {"local_as": 111}},
b7250ecf
KK
328 }
329 result = modify_as_number(tgen, topo, input_dict)
330 if result != True:
afee014e 331 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
332
333 result = verify_as_numbers(tgen, topo, input_dict)
334 if result != True:
afee014e 335 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
336
337 # Api call verify whether BGP is converged
338 result = verify_bgp_convergence(tgen, topo)
339 if result != True:
afee014e 340 assert False, "Testcase " + tc_name + " :Failed \n Error: {}".format(result)
b7250ecf
KK
341
342 write_test_footer(tc_name)
343
344
77ef1af6
AP
345def test_bgp_timers_functionality(request):
346 """
347 Test to modify bgp timers and verify timers functionality.
348 """
349
350 tgen = get_topogen()
351 if BGP_CONVERGENCE is not True:
787e7624 352 pytest.skip("skipped because of BGP Convergence failure")
77ef1af6
AP
353
354 # test case name
355 tc_name = request.node.name
356 write_test_header(tc_name)
357
358 # Creating configuration from JSON
359 reset_config_on_routers(tgen)
360
e3fde768 361 # Api call to modify BGP timerse
77ef1af6
AP
362 input_dict = {
363 "r1": {
364 "bgp": {
365 "address_family": {
366 "ipv4": {
367 "unicast": {
368 "neighbor": {
369 "r2": {
787e7624 370 "dest_link": {
77ef1af6 371 "r1": {
af9c65d4 372 "keepalivetimer": KEEPALIVETIMER,
787e7624 373 "holddowntimer": HOLDDOWNTIMER,
77ef1af6
AP
374 }
375 }
376 }
377 }
378 }
379 }
380 }
381 }
382 }
383 }
384 result = create_router_bgp(tgen, topo, deepcopy(input_dict))
787e7624 385 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
386
387 # Api call to clear bgp, so timer modification would take place
787e7624 388 clear_bgp_and_verify(tgen, topo, "r1")
77ef1af6
AP
389
390 # Verifying bgp timers functionality
391 result = verify_bgp_timers_and_functionality(tgen, topo, input_dict)
787e7624 392 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
77ef1af6
AP
393
394 write_test_footer(tc_name)
395
396
cb6b1d90 397def test_static_routes(request):
a53c08bc 398 """Test to create and verify static routes."""
cb6b1d90
AP
399
400 tgen = get_topogen()
401 if BGP_CONVERGENCE is not True:
787e7624 402 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
403
404 # test case name
405 tc_name = request.node.name
406 write_test_header(tc_name)
407
408 # Creating configuration from JSON
409 reset_config_on_routers(tgen)
410
411 # Api call to create static routes
412 input_dict = {
413 "r1": {
787e7624 414 "static_routes": [
415 {
416 "network": "10.0.20.1/32",
417 "no_of_ip": 9,
418 "admin_distance": 100,
419 "next_hop": "10.0.0.2",
420 }
421 ]
cb6b1d90
AP
422 }
423 }
424 result = create_static_routes(tgen, input_dict)
787e7624 425 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
426
427 # Api call to redistribute static routes
428 input_dict_1 = {
429 "r1": {
430 "bgp": {
431 "address_family": {
432 "ipv4": {
433 "unicast": {
434 "redistribute": [
435 {"redist_type": "static"},
787e7624 436 {"redist_type": "connected"},
cb6b1d90
AP
437 ]
438 }
439 }
440 }
441 }
442 }
443 }
444
445 result = create_router_bgp(tgen, topo, input_dict_1)
787e7624 446 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
447
448 # Verifying RIB routes
787e7624 449 dut = "r3"
450 protocol = "bgp"
451 next_hop = ["10.0.0.2", "10.0.0.5"]
452 result = verify_rib(
453 tgen, "ipv4", dut, input_dict, next_hop=next_hop, protocol=protocol
454 )
455 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
456
457 write_test_footer(tc_name)
458
459
460def test_admin_distance_for_existing_static_routes(request):
a53c08bc 461 """Test to modify and verify admin distance for existing static routes."""
cb6b1d90
AP
462
463 tgen = get_topogen()
464 if BGP_CONVERGENCE is not True:
787e7624 465 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
466
467 # test case name
468 tc_name = request.node.name
469 write_test_header(tc_name)
470
471 # Creating configuration from JSON
472 reset_config_on_routers(tgen)
473
474 input_dict = {
475 "r1": {
787e7624 476 "static_routes": [
477 {
478 "network": "10.0.20.1/32",
479 "admin_distance": 10,
480 "next_hop": "10.0.0.2",
481 }
482 ]
cb6b1d90
AP
483 }
484 }
485 result = create_static_routes(tgen, input_dict)
787e7624 486 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
487
488 # Verifying admin distance once modified
489 result = verify_admin_distance_for_static_routes(tgen, input_dict)
787e7624 490 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
491
492 write_test_footer(tc_name)
493
494
495def test_advertise_network_using_network_command(request):
a53c08bc 496 """Test advertise networks using network command."""
cb6b1d90
AP
497
498 tgen = get_topogen()
499 if BGP_CONVERGENCE is not True:
787e7624 500 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
501
502 # test case name
503 tc_name = request.node.name
504 write_test_header(tc_name)
505
506 # Creating configuration from JSON
507 reset_config_on_routers(tgen)
508
509 # Api call to advertise networks
510 input_dict = {
511 "r1": {
512 "bgp": {
513 "address_family": {
514 "ipv4": {
515 "unicast": {
516 "advertise_networks": [
787e7624 517 {"network": "20.0.0.0/32", "no_of_network": 10},
518 {"network": "30.0.0.0/32", "no_of_network": 10},
cb6b1d90
AP
519 ]
520 }
521 }
522 }
523 }
524 }
525 }
526
527 result = create_router_bgp(tgen, topo, input_dict)
787e7624 528 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
529
530 # Verifying RIB routes
787e7624 531 dut = "r2"
cb6b1d90 532 protocol = "bgp"
787e7624 533 result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol)
534 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
535
536 write_test_footer(tc_name)
537
538
539def test_clear_bgp_and_verify(request):
540 """
541 Created few static routes and verified all routes are learned via BGP
542 cleared BGP and verified all routes are intact
543 """
544
545 tgen = get_topogen()
546 if BGP_CONVERGENCE is not True:
787e7624 547 pytest.skip("skipped because of BGP Convergence failure")
cb6b1d90
AP
548
549 # test case name
550 tc_name = request.node.name
551 write_test_header(tc_name)
552
553 # Creating configuration from JSON
554 reset_config_on_routers(tgen)
555
556 # clear ip bgp
787e7624 557 result = clear_bgp_and_verify(tgen, topo, "r1")
558 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
cb6b1d90
AP
559
560 write_test_footer(tc_name)
561
562
19f4da0b
KK
563def test_BGP_attributes_with_vrf_default_keyword_p0(request):
564 """
565 TC_9:
566 Verify BGP functionality for default vrf with
567 "vrf default" keyword.
568 """
569
570 tc_name = request.node.name
571 write_test_header(tc_name)
572 tgen = get_topogen()
573
574 if tgen.routers_have_failure():
575 pytest.skip(tgen.errors)
576
b86955a6
CH
577 # Creating configuration from JSON
578 reset_config_on_routers(tgen)
19f4da0b
KK
579
580 step("Configure static routes and redistribute in BGP on R3")
581 for addr_type in ADDR_TYPES:
582 input_dict = {
583 "r3": {
584 "static_routes": [
585 {
586 "network": NETWORK[addr_type][0],
587 "no_of_ip": 4,
588 "next_hop": "Null0",
589 }
590 ]
591 }
592 }
593
594 result = create_static_routes(tgen, input_dict)
595 assert result is True, "Testcase {} : Failed \n Error: {}".format(
596 tc_name, result
597 )
598
599 input_dict_2 = {
600 "r3": {
601 "bgp": {
602 "address_family": {
603 "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
604 "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
605 }
606 }
607 }
608 }
609 result = create_router_bgp(tgen, topo, input_dict_2)
610 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
611
612 step(
613 "Create a route-map to match a specific prefix and modify"
614 "BGP attributes for matched prefix"
615 )
616 input_dict_2 = {
617 "r3": {
618 "prefix_lists": {
619 "ipv4": {
620 "ABC": [
621 {
622 "seqid": 10,
623 "action": "permit",
624 "network": NETWORK["ipv4"][0],
625 }
626 ]
627 },
628 "ipv6": {
629 "XYZ": [
630 {
631 "seqid": 100,
632 "action": "permit",
633 "network": NETWORK["ipv6"][0],
634 }
635 ]
636 },
637 }
638 }
639 }
640 result = create_prefix_lists(tgen, input_dict_2)
641 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
642
643 for addr_type in ADDR_TYPES:
644 if addr_type == "ipv4":
645 pf_list = "ABC"
646 else:
647 pf_list = "XYZ"
648
649 input_dict_6 = {
650 "r3": {
651 "route_maps": {
652 "BGP_ATTR_{}".format(addr_type): [
653 {
654 "action": "permit",
655 "seq_id": 10,
656 "match": {addr_type: {"prefix_lists": pf_list}},
657 "set": {
658 "aspath": {"as_num": 500, "as_action": "prepend"},
659 "localpref": 500,
660 "origin": "egp",
661 "community": {"num": "500:500", "action": "additive"},
662 "large_community": {
663 "num": "500:500:500",
664 "action": "additive",
665 },
666 },
667 },
668 {"action": "permit", "seq_id": 20},
669 ]
670 },
671 "BGP_ATTR_{}".format(addr_type): [
672 {
673 "action": "permit",
674 "seq_id": 100,
675 "match": {addr_type: {"prefix_lists": pf_list}},
676 "set": {
677 "aspath": {"as_num": 500, "as_action": "prepend"},
678 "localpref": 500,
679 "origin": "egp",
680 "community": {"num": "500:500", "action": "additive"},
681 "large_community": {
682 "num": "500:500:500",
683 "action": "additive",
684 },
685 },
686 },
687 {"action": "permit", "seq_id": 200},
688 ],
689 }
690 }
691
692 result = create_route_maps(tgen, input_dict_6)
693 assert result is True, "Testcase {} : Failed \n Error: {}".format(
694 tc_name, result
695 )
696
697 step("Apply the route-map on R3 in outbound direction for peer R4")
698
699 input_dict_7 = {
700 "r3": {
701 "bgp": {
702 "address_family": {
703 "ipv4": {
704 "unicast": {
705 "neighbor": {
706 "r4": {
707 "dest_link": {
708 "r3": {
709 "route_maps": [
710 {
711 "name": "BGP_ATTR_ipv4",
712 "direction": "out",
713 }
714 ]
715 }
716 }
717 }
718 }
719 }
720 },
721 "ipv6": {
722 "unicast": {
723 "neighbor": {
724 "r4": {
725 "dest_link": {
726 "r3": {
727 "route_maps": [
728 {
729 "name": "BGP_ATTR_ipv6",
730 "direction": "out",
731 }
732 ]
733 }
734 }
735 }
736 }
737 }
738 },
739 }
740 }
741 }
742 }
743
744 result = create_router_bgp(tgen, topo, input_dict_7)
745 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
746
747 step(
748 "verify modified attributes for specific prefix with 'vrf default'"
749 "keyword on R4"
750 )
751 for addr_type in ADDR_TYPES:
752 dut = "r4"
753 input_dict = {
754 "r3": {
755 "static_routes": [
756 {
757 "network": NETWORK[addr_type][0],
758 "vrf": "default",
759 "largeCommunity": "500:500:500",
760 }
761 ]
762 }
763 }
764
765 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
a53c08bc
CH
766 assert result is True, "Testcase {} : Failed \n Error: {}".format(
767 tc_name, result
768 )
19f4da0b 769 result = verify_rib(tgen, addr_type, dut, input_dict)
a53c08bc
CH
770 assert result is True, "Testcase {} : Failed \n Error: {}".format(
771 tc_name, result
772 )
19f4da0b
KK
773
774 for addr_type in ADDR_TYPES:
775 dut = "r4"
776 input_dict = {
777 "r3": {
778 "static_routes": [
779 {
780 "network": NETWORK[addr_type][0],
781 "vrf": "default",
782 "community": "500:500",
783 }
784 ]
785 }
786 }
787
788 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
a53c08bc
CH
789 assert result is True, "Testcase {} : Failed \n Error: {}".format(
790 tc_name, result
791 )
19f4da0b 792 result = verify_rib(tgen, addr_type, dut, input_dict)
a53c08bc
CH
793 assert result is True, "Testcase {} : Failed \n Error: {}".format(
794 tc_name, result
795 )
19f4da0b
KK
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:
a53c08bc
CH
1134 result = verify_fib_routes(
1135 tgen, addr_type, dut, input_dict_r1, expected=False
1136 ) # pylint: disable=E1123
8db751b8 1137 assert result is not True, (
d63c7094
KK
1138 "Testcase {} : Failed \n "
1139 "Expected: Routes should not be present in {} FIB \n "
1140 "Found: {}".format(tc_name, dut, result)
8db751b8 1141 )
19f4da0b
KK
1142
1143 step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
1144 input_dict_r3 = {
1145 "r3": {
1146 "static_routes": [
1147 {"network": "1.0.4.17/32"},
1148 {"network": "2001:db8:f::4:17/128"},
1149 ]
1150 }
1151 }
1152 dut = "r3"
1153 protocol = "bgp"
1154 for addr_type in ADDR_TYPES:
a53c08bc
CH
1155 result = verify_fib_routes(
1156 tgen, addr_type, dut, input_dict_r1, expected=False
1157 ) # pylint: disable=E1123
8db751b8 1158 assert result is not True, (
d63c7094
KK
1159 "Testcase {} : Failed \n "
1160 "Expected: Routes should not be present in {} FIB \n "
1161 "Found: {}".format(tc_name, dut, result)
8db751b8 1162 )
19f4da0b
KK
1163
1164 write_test_footer(tc_name)
1165
1166
787e7624 1167if __name__ == "__main__":
7fa2079a
AP
1168 args = ["-s"] + sys.argv[1:]
1169 sys.exit(pytest.main(args))