]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_communities_topo1/test_bgp_communities.py
Merge pull request #9596 from LabNConsulting/ziemba/printfrr-nexthop
[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")
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 deamons 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, "Testcase {} : Failed \n ".format(
321 tc_name
322 ) + " Routes still present in R3 router. Error: {}".format(result)
323
324 result = verify_rib(
325 tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
326 )
327 assert (
328 result is not True
329 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
330 tc_name, result
331 )
332
333 step("Remove and Add no advertise community")
334 # Configure neighbor for route map
335 input_dict_4 = {
336 "r2": {
337 "bgp": {
338 "address_family": {
339 addr_type: {
340 "unicast": {
341 "neighbor": {
342 "r1": {
343 "dest_link": {
344 "r2": {
345 "route_maps": [
346 {
347 "name": "rmap_match_pf_1_"
348 + addr_type,
349 "direction": "in",
350 "delete": True,
351 }
352 ]
353 }
354 }
355 }
356 }
357 }
358 }
359 }
360 }
361 }
362 }
363 result = create_router_bgp(tgen, topo, input_dict_4)
364 assert result is True, "Testcase {} : Failed \n Error: {}".format(
365 tc_name, result
366 )
367
368 step(
369 "After removing no advertise community from BGP neighbor "
370 "static and connected router got advertised to R3 and "
371 "removing route-map, verify route using show ip bgp"
372 " and show ip route"
373 )
374
375 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
376 assert (
377 result is True
378 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
379 tc_name, result
380 )
381
382 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
383 assert (
384 result is True
385 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
386 tc_name, result
387 )
388
389 step("Repeat above steps when IBGP nbr configured between R1, R2 & R2, R3")
390 topo1 = deepcopy(topo)
391
392 topo1["routers"]["r1"]["bgp"]["local_as"] = "100"
393 topo1["routers"]["r2"]["bgp"]["local_as"] = "100"
394 topo1["routers"]["r3"]["bgp"]["local_as"] = "100"
395
396 for rtr in ["r1", "r2", "r3"]:
397 if "bgp" in topo1["routers"][rtr].keys():
398 delete_bgp = {rtr: {"bgp": {"delete": True}}}
399 result = create_router_bgp(tgen, topo1, delete_bgp)
400 assert result is True, "Testcase {} : Failed \n Error: {}".format(
401 tc_name, result
402 )
403 config_bgp = {
404 rtr: {"bgp": {"local_as": topo1["routers"][rtr]["bgp"]["local_as"]}}
405 }
406 result = create_router_bgp(tgen, topo1, config_bgp)
407 assert result is True, "Testcase {} : Failed \n Error: {}".format(
408 tc_name, result
409 )
410
411 build_config_from_json(tgen, topo1, save_bkup=False)
412
413 step("verify bgp convergence before starting test case")
414
415 bgp_convergence = verify_bgp_convergence(tgen, topo1)
416 assert bgp_convergence is True, "Testcase {} : Failed \n Error: {}".format(
417 tc_name, bgp_convergence
418 )
419
420 # configure static routes
421 dut = "r3"
422 protocol = "bgp"
423
424 for addr_type in ADDR_TYPES:
425 # Enable static routes
426 input_dict = {
427 "r1": {
428 "static_routes": [
429 {"network": NETWORK[addr_type], "next_hop": NEXT_HOP_IP[addr_type]}
430 ]
431 }
432 }
433
434 logger.info("Configure static routes")
435 result = create_static_routes(tgen, input_dict)
436 assert result is True, "Testcase {} : Failed \n Error: {}".format(
437 tc_name, result
438 )
439
440 step("configure redistribute static and connected in Router " "BGP in R1")
441
442 input_dict_2 = {
443 "r1": {
444 "bgp": {
445 "address_family": {
446 addr_type: {
447 "unicast": {
448 "redistribute": [
449 {"redist_type": "static"},
450 {"redist_type": "connected"},
451 ]
452 }
453 }
454 }
455 }
456 }
457 }
458 result = create_router_bgp(tgen, topo, input_dict_2)
459 assert result is True, "Testcase {} : Failed \n Error: {}".format(
460 tc_name, result
461 )
462
463 step(
464 "BGP neighbors are up, static and connected route advertised from"
465 " R1 are present on R2 BGP table and RIB using show ip bgp and "
466 " show ip route"
467 )
468 step(
469 "Static and connected route advertised from R1 are present on R3"
470 " BGP table and RIB using show ip bgp and show ip route"
471 )
472
473 dut = "r2"
474 protocol = "bgp"
475 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
476 assert result is True, "Testcase {} : Failed \n Error: {}".format(
477 tc_name, result
478 )
479
480 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
481 assert result is True, "Testcase {} : Failed \n Error: {}".format(
482 tc_name, result
483 )
484
485 step("Configure prefix list P1 on R2 to permit route coming from R1")
486 # Create ip prefix list
487 input_dict_2 = {
488 "r2": {
489 "prefix_lists": {
490 addr_type: {
491 "pf_list_1_{}".format(addr_type): [
492 {"seqid": 10, "network": "any", "action": "permit"}
493 ]
494 }
495 }
496 }
497 }
498 result = create_prefix_lists(tgen, input_dict_2)
499 assert result is True, "Testcase {} : Failed \n Error: {}".format(
500 tc_name, result
501 )
502
503 # Create route map
504 input_dict_3 = {
505 "r2": {
506 "route_maps": {
507 "rmap_match_pf_1_{}".format(addr_type): [
508 {
509 "action": "permit",
510 "seq_id": "5",
511 "match": {
512 addr_type: {"prefix_lists": "pf_list_1_" + addr_type}
513 },
514 "set": {"community": {"num": "no-advertise"}},
515 }
516 ]
517 }
518 }
519 }
520 result = create_route_maps(tgen, input_dict_3)
521 assert result is True, "Testcase {} : Failed \n Error: {}".format(
522 tc_name, result
523 )
524 step(
525 "Apply route-map RM1 on R2, R2 to R3 BGP neighbor with no"
526 " advertise community"
527 )
528
529 # Configure neighbor for route map
530 input_dict_4 = {
531 "r2": {
532 "bgp": {
533 "address_family": {
534 addr_type: {
535 "unicast": {
536 "neighbor": {
537 "r1": {
538 "dest_link": {
539 "r2": {
540 "route_maps": [
541 {
542 "name": "rmap_match_pf_1_"
543 + addr_type,
544 "direction": "in",
545 }
546 ]
547 }
548 }
549 }
550 }
551 }
552 }
553 }
554 }
555 }
556 }
557 result = create_router_bgp(tgen, topo, input_dict_4)
558 assert result is True, "Testcase {} : Failed \n Error: {}".format(
559 tc_name, result
560 )
561
562 step(
563 "After advertising no advertise community to BGP neighbor "
564 "static and connected router got removed from R3 verify using "
565 "show ip bgp & show ip route"
566 )
567
568 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
569 assert (
570 result is True
571 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
572 tc_name, result
573 )
574
575 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
576 assert (
577 result is True
578 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
579 tc_name, result
580 )
581
582 step("Remove and Add no advertise community")
583 # Configure neighbor for route map
584 input_dict_4 = {
585 "r2": {
586 "bgp": {
587 "address_family": {
588 addr_type: {
589 "unicast": {
590 "neighbor": {
591 "r1": {
592 "dest_link": {
593 "r2": {
594 "route_maps": [
595 {
596 "name": "rmap_match_pf_1_"
597 + addr_type,
598 "direction": "in",
599 "delete": True,
600 }
601 ]
602 }
603 }
604 }
605 }
606 }
607 }
608 }
609 }
610 }
611 }
612 result = create_router_bgp(tgen, topo, input_dict_4)
613 assert result is True, "Testcase {} : Failed \n Error: {}".format(
614 tc_name, result
615 )
616
617 step(
618 "After removing no advertise community from BGP neighbor "
619 "static and connected router got advertised to R3 and "
620 "removing route verify using show ip bgp and "
621 " show ip route"
622 )
623
624 result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
625 assert (
626 result is True
627 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
628 tc_name, result
629 )
630
631 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
632 assert (
633 result is True
634 ), "Testcase {} : Failed \n Routes still present in R3 router. Error: {}".format(
635 tc_name, result
636 )
637
638 write_test_footer(tc_name)
639
640
641 if __name__ == "__main__":
642 args = ["-s"] + sys.argv[1:]
643 sys.exit(pytest.main(args))