]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_communities_topo1/test_bgp_communities.py
Merge pull request #12059 from achernavin22/fix-max-med-on-startup
[mirror_frr.git] / tests / topotests / bgp_communities_topo1 / test_bgp_communities.py
1 #!/usr/bin/python
2
3 #
4 # Copyright (c) 2020 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 """
24 Following tests are covered to test bgp community functionality:
25 - Verify routes are not advertised when NO-ADVERTISE Community is applied
26
27 """
28
29 import os
30 import sys
31 import time
32 import pytest
33
34 # Save the Current Working Directory to find configuration files.
35 CWD = os.path.dirname(os.path.realpath(__file__))
36 sys.path.append(os.path.join(CWD, "../"))
37
38 # pylint: disable=C0413
39 # Import topogen and topotest helpers
40 from lib.topogen import Topogen, get_topogen
41
42 # Import topoJson from lib, to create topology and initial configuration
43 from lib.common_config import (
44 start_topology,
45 write_test_header,
46 write_test_footer,
47 reset_config_on_routers,
48 verify_rib,
49 create_static_routes,
50 check_address_types,
51 step,
52 create_route_maps,
53 create_prefix_lists,
54 create_route_maps,
55 required_linux_kernel_version,
56 )
57 from lib.topolog import logger
58 from lib.bgp import (
59 verify_bgp_convergence,
60 create_router_bgp,
61 verify_bgp_rib,
62 )
63 from lib.topojson import build_config_from_json
64 from copy import deepcopy
65
66 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
67
68
69 # Global variables
70 BGP_CONVERGENCE = False
71 ADDR_TYPES = check_address_types()
72 NETWORK = {"ipv4": "2.2.2.2/32", "ipv6": "22:22::2/128"}
73 NEXT_HOP_IP = {}
74
75
76 def setup_module(mod):
77 """
78 Sets up the pytest environment
79
80 * `mod`: module name
81 """
82
83 # Required linux kernel version for this suite to run.
84 result = required_linux_kernel_version("4.15")
85 if result is not True:
86 pytest.skip("Kernel requirements are not met, kernel version should be >= 4.15")
87
88 testsuite_run_time = time.asctime(time.localtime(time.time()))
89 logger.info("Testsuite start time: {}".format(testsuite_run_time))
90 logger.info("=" * 40)
91
92 logger.info("Running setup_module to create topology")
93
94 # This function initiates the topology build with Topogen...
95 json_file = "{}/bgp_communities.json".format(CWD)
96 tgen = Topogen(json_file, mod.__name__)
97 global topo
98 topo = tgen.json_topo
99 # ... and here it calls Mininet initialization functions.
100
101 # Starting topology, create tmp files which are loaded to routers
102 # to start daemons and then start routers
103 start_topology(tgen)
104
105 # Creating configuration from JSON
106 build_config_from_json(tgen, topo)
107
108 # Checking BGP convergence
109 global BGP_CONVERGENCE
110 global ADDR_TYPES
111
112 # Don't run this test if we have any failure.
113 if tgen.routers_have_failure():
114 pytest.skip(tgen.errors)
115
116 # Api call verify whether BGP is converged
117 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
118 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format(
119 BGP_CONVERGENCE
120 )
121
122 logger.info("Running setup_module() done")
123
124
125 def teardown_module(mod):
126 """
127 Teardown the pytest environment
128
129 * `mod`: module name
130 """
131
132 logger.info("Running teardown_module to delete topology")
133
134 tgen = get_topogen()
135
136 # Stop toplogy and Remove tmp files
137 tgen.stop_topology()
138
139 logger.info(
140 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
141 )
142 logger.info("=" * 40)
143
144
145 #####################################################
146 #
147 # Tests starting
148 #
149 #####################################################
150
151
152 def test_bgp_no_advertise_community_p0(request):
153 """
154 Verify routes are not advertised when NO-ADVERTISE Community is applied
155
156 """
157
158 tc_name = request.node.name
159 write_test_header(tc_name)
160 tgen = get_topogen()
161 reset_config_on_routers(tgen)
162
163 # Don't run this test if we have any failure.
164 if tgen.routers_have_failure():
165 pytest.skip(tgen.errors)
166
167 NEXT_HOP_IP = {
168 "ipv4": topo["routers"]["r0"]["links"]["r1"]["ipv4"].split("/")[0],
169 "ipv6": topo["routers"]["r0"]["links"]["r1"]["ipv6"].split("/")[0],
170 }
171
172 # configure static routes
173 dut = "r3"
174 protocol = "bgp"
175
176 for addr_type in ADDR_TYPES:
177 # Enable static routes
178 input_dict = {
179 "r1": {
180 "static_routes": [
181 {"network": NETWORK[addr_type], "next_hop": NEXT_HOP_IP[addr_type]}
182 ]
183 }
184 }
185
186 logger.info("Configure static routes")
187 result = create_static_routes(tgen, input_dict)
188 assert result is True, "Testcase {} : Failed \n Error: {}".format(
189 tc_name, result
190 )
191
192 step("configure redistribute static and connected in Router BGP " "in R1")
193
194 input_dict_2 = {
195 "r1": {
196 "bgp": {
197 "address_family": {
198 addr_type: {
199 "unicast": {
200 "redistribute": [
201 {"redist_type": "static"},
202 {"redist_type": "connected"},
203 ]
204 }
205 }
206 }
207 }
208 }
209 }
210 result = create_router_bgp(tgen, topo, input_dict_2)
211 assert result is True, "Testcase {} : Failed \n Error: {}".format(
212 tc_name, result
213 )
214
215 step(
216 "BGP neighbors are up, static and connected route advertised from"
217 " R1 are present on R2 BGP table and RIB using show ip bgp and "
218 " show ip route"
219 )
220 step(
221 "Static and connected route advertised from R1 are present on R3"
222 " BGP table and RIB using show ip bgp and show ip route"
223 )
224
225 dut = "r3"
226 protocol = "bgp"
227 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
228 assert result is True, "Testcase {} : Failed \n Error: {}".format(
229 tc_name, result
230 )
231
232 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
233 assert result is True, "Testcase {} : Failed \n Error: {}".format(
234 tc_name, result
235 )
236
237 step("Configure prefix list P1 on R2 to permit route coming from R1")
238 # Create ip prefix list
239 input_dict_2 = {
240 "r2": {
241 "prefix_lists": {
242 addr_type: {
243 "pf_list_1_{}".format(addr_type): [
244 {"seqid": 10, "network": "any", "action": "permit"}
245 ]
246 }
247 }
248 }
249 }
250 result = create_prefix_lists(tgen, input_dict_2)
251 assert result is True, "Testcase {} : Failed \n Error: {}".format(
252 tc_name, result
253 )
254
255 # Create route map
256 input_dict_3 = {
257 "r2": {
258 "route_maps": {
259 "rmap_match_pf_1_{}".format(addr_type): [
260 {
261 "action": "permit",
262 "seq_id": "5",
263 "match": {
264 addr_type: {"prefix_lists": "pf_list_1_" + addr_type}
265 },
266 "set": {"community": {"num": "no-advertise"}},
267 }
268 ]
269 }
270 }
271 }
272 result = create_route_maps(tgen, input_dict_3)
273 assert result is True, "Testcase {} : Failed \n Error: {}".format(
274 tc_name, result
275 )
276 step(
277 "Apply route-map RM1 on R2, R2 to R3 BGP neighbor with no"
278 " advertise community"
279 )
280 # Configure neighbor for route map
281 input_dict_4 = {
282 "r2": {
283 "bgp": {
284 "address_family": {
285 addr_type: {
286 "unicast": {
287 "neighbor": {
288 "r1": {
289 "dest_link": {
290 "r2": {
291 "route_maps": [
292 {
293 "name": "rmap_match_pf_1_"
294 + addr_type,
295 "direction": "in",
296 }
297 ]
298 }
299 }
300 }
301 }
302 }
303 }
304 }
305 }
306 }
307 }
308 result = create_router_bgp(tgen, topo, input_dict_4)
309 assert result is True, "Testcase {} : Failed \n Error: {}".format(
310 tc_name, result
311 )
312
313 step(
314 "After advertising no advertise community to BGP neighbor "
315 "static and connected router got removed from R3 verify using "
316 "show ip bgp & show ip route"
317 )
318
319 result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
320 assert result is not True, (
321 "Testcase {} : Failed \n Expected: "
322 "Routes still present in {} router. Found: {}".format(tc_name, dut, result)
323 )
324
325 result = verify_rib(
326 tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
327 )
328 assert (
329 result is not True
330 ), "Testcase {} : Failed \n Expected: Routes still present in {} router. Found: {}".format(
331 tc_name, dut, result
332 )
333
334 step("Remove and Add no advertise community")
335 # Configure neighbor for route map
336 input_dict_4 = {
337 "r2": {
338 "bgp": {
339 "address_family": {
340 addr_type: {
341 "unicast": {
342 "neighbor": {
343 "r1": {
344 "dest_link": {
345 "r2": {
346 "route_maps": [
347 {
348 "name": "rmap_match_pf_1_"
349 + addr_type,
350 "direction": "in",
351 "delete": True,
352 }
353 ]
354 }
355 }
356 }
357 }
358 }
359 }
360 }
361 }
362 }
363 }
364 result = create_router_bgp(tgen, topo, input_dict_4)
365 assert result is True, "Testcase {} : Failed \n Error: {}".format(
366 tc_name, result
367 )
368
369 step(
370 "After removing no advertise community from BGP neighbor "
371 "static and connected router got advertised to R3 and "
372 "removing route-map, verify route using show ip bgp"
373 " and show ip route"
374 )
375
376 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
377 assert (
378 result is True
379 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
380 tc_name, result
381 )
382
383 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
384 assert (
385 result is True
386 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
387 tc_name, result
388 )
389
390 step("Repeat above steps when IBGP nbr configured between R1, R2 & R2, R3")
391 topo1 = deepcopy(topo)
392
393 topo1["routers"]["r1"]["bgp"]["local_as"] = "100"
394 topo1["routers"]["r2"]["bgp"]["local_as"] = "100"
395 topo1["routers"]["r3"]["bgp"]["local_as"] = "100"
396
397 for rtr in ["r1", "r2", "r3"]:
398 if "bgp" in topo1["routers"][rtr].keys():
399 delete_bgp = {rtr: {"bgp": {"delete": True}}}
400 result = create_router_bgp(tgen, topo1, delete_bgp)
401 assert result is True, "Testcase {} : Failed \n Error: {}".format(
402 tc_name, result
403 )
404 config_bgp = {
405 rtr: {"bgp": {"local_as": topo1["routers"][rtr]["bgp"]["local_as"]}}
406 }
407 result = create_router_bgp(tgen, topo1, config_bgp)
408 assert result is True, "Testcase {} : Failed \n Error: {}".format(
409 tc_name, result
410 )
411
412 build_config_from_json(tgen, topo1, save_bkup=False)
413
414 step("verify bgp convergence before starting test case")
415
416 bgp_convergence = verify_bgp_convergence(tgen, topo1)
417 assert bgp_convergence is True, "Testcase {} : Failed \n Error: {}".format(
418 tc_name, bgp_convergence
419 )
420
421 # configure static routes
422 dut = "r3"
423 protocol = "bgp"
424
425 for addr_type in ADDR_TYPES:
426 # Enable static routes
427 input_dict = {
428 "r1": {
429 "static_routes": [
430 {"network": NETWORK[addr_type], "next_hop": NEXT_HOP_IP[addr_type]}
431 ]
432 }
433 }
434
435 logger.info("Configure static routes")
436 result = create_static_routes(tgen, input_dict)
437 assert result is True, "Testcase {} : Failed \n Error: {}".format(
438 tc_name, result
439 )
440
441 step("configure redistribute static and connected in Router " "BGP in R1")
442
443 input_dict_2 = {
444 "r1": {
445 "bgp": {
446 "address_family": {
447 addr_type: {
448 "unicast": {
449 "redistribute": [
450 {"redist_type": "static"},
451 {"redist_type": "connected"},
452 ]
453 }
454 }
455 }
456 }
457 }
458 }
459 result = create_router_bgp(tgen, topo, input_dict_2)
460 assert result is True, "Testcase {} : Failed \n Error: {}".format(
461 tc_name, result
462 )
463
464 step(
465 "BGP neighbors are up, static and connected route advertised from"
466 " R1 are present on R2 BGP table and RIB using show ip bgp and "
467 " show ip route"
468 )
469 step(
470 "Static and connected route advertised from R1 are present on R3"
471 " BGP table and RIB using show ip bgp and show ip route"
472 )
473
474 dut = "r2"
475 protocol = "bgp"
476 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
477 assert result is True, "Testcase {} : Failed \n Error: {}".format(
478 tc_name, result
479 )
480
481 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
482 assert result is True, "Testcase {} : Failed \n Error: {}".format(
483 tc_name, result
484 )
485
486 step("Configure prefix list P1 on R2 to permit route coming from R1")
487 # Create ip prefix list
488 input_dict_2 = {
489 "r2": {
490 "prefix_lists": {
491 addr_type: {
492 "pf_list_1_{}".format(addr_type): [
493 {"seqid": 10, "network": "any", "action": "permit"}
494 ]
495 }
496 }
497 }
498 }
499 result = create_prefix_lists(tgen, input_dict_2)
500 assert result is True, "Testcase {} : Failed \n Error: {}".format(
501 tc_name, result
502 )
503
504 # Create route map
505 input_dict_3 = {
506 "r2": {
507 "route_maps": {
508 "rmap_match_pf_1_{}".format(addr_type): [
509 {
510 "action": "permit",
511 "seq_id": "5",
512 "match": {
513 addr_type: {"prefix_lists": "pf_list_1_" + addr_type}
514 },
515 "set": {"community": {"num": "no-advertise"}},
516 }
517 ]
518 }
519 }
520 }
521 result = create_route_maps(tgen, input_dict_3)
522 assert result is True, "Testcase {} : Failed \n Error: {}".format(
523 tc_name, result
524 )
525 step(
526 "Apply route-map RM1 on R2, R2 to R3 BGP neighbor with no"
527 " advertise community"
528 )
529
530 # Configure neighbor for route map
531 input_dict_4 = {
532 "r2": {
533 "bgp": {
534 "address_family": {
535 addr_type: {
536 "unicast": {
537 "neighbor": {
538 "r1": {
539 "dest_link": {
540 "r2": {
541 "route_maps": [
542 {
543 "name": "rmap_match_pf_1_"
544 + addr_type,
545 "direction": "in",
546 }
547 ]
548 }
549 }
550 }
551 }
552 }
553 }
554 }
555 }
556 }
557 }
558 result = create_router_bgp(tgen, topo, input_dict_4)
559 assert result is True, "Testcase {} : Failed \n Error: {}".format(
560 tc_name, result
561 )
562
563 step(
564 "After advertising no advertise community to BGP neighbor "
565 "static and connected router got removed from R3 verify using "
566 "show ip bgp & show ip route"
567 )
568
569 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
570 assert (
571 result is True
572 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
573 tc_name, result
574 )
575
576 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
577 assert (
578 result is True
579 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
580 tc_name, result
581 )
582
583 step("Remove and Add no advertise community")
584 # Configure neighbor for route map
585 input_dict_4 = {
586 "r2": {
587 "bgp": {
588 "address_family": {
589 addr_type: {
590 "unicast": {
591 "neighbor": {
592 "r1": {
593 "dest_link": {
594 "r2": {
595 "route_maps": [
596 {
597 "name": "rmap_match_pf_1_"
598 + addr_type,
599 "direction": "in",
600 "delete": True,
601 }
602 ]
603 }
604 }
605 }
606 }
607 }
608 }
609 }
610 }
611 }
612 }
613 result = create_router_bgp(tgen, topo, input_dict_4)
614 assert result is True, "Testcase {} : Failed \n Error: {}".format(
615 tc_name, result
616 )
617
618 step(
619 "After removing no advertise community from BGP neighbor "
620 "static and connected router got advertised to R3 and "
621 "removing route verify using show ip bgp and "
622 " show ip route"
623 )
624
625 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
626 assert (
627 result is True
628 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
629 tc_name, result
630 )
631
632 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
633 assert (
634 result is True
635 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
636 tc_name, result
637 )
638
639 write_test_footer(tc_name)
640
641
642 if __name__ == "__main__":
643 args = ["-s"] + sys.argv[1:]
644 sys.exit(pytest.main(args))