]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py
tests: micronet: adapt tests
[mirror_frr.git] / tests / topotests / bgp_route_aggregation / test_bgp_aggregation.py
1 #!/usr/bin/python
2 #
3 # Copyright (c) 2020 by VMware, Inc. ("VMware")
4 # Used Copyright (c) 2018 by Network Device Education Foundation,
5 # Inc. ("NetDEF") in this file.
6 #
7 # Permission to use, copy, modify, and/or distribute this software
8 # for any purpose with or without fee is hereby granted, provided
9 # that the above copyright notice and this permission notice appear
10 # in all copies.
11 #
12 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
15 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
16 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
18 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
19 # OF THIS SOFTWARE.
20 #
21
22 """
23 Following tests are covered to test bgp aggregation functionality:
24
25 1. Verify route summarisation with summary-only for redistributed as well as
26 locally generated routes.
27 2. Verify route summarisation with as-set for redistributed routes.
28
29 """
30
31 import os
32 import sys
33 import time
34 import json
35 import pytest
36 from time import sleep
37 from copy import deepcopy
38
39 # Save the Current Working Directory to find configuration files.
40 CWD = os.path.dirname(os.path.realpath(__file__))
41 sys.path.append(os.path.join(CWD, "../"))
42
43 # pylint: disable=C0413
44 # Import topogen and topotest helpers
45 from lib import topotest
46 from lib.micronet_compat import Topo
47 from lib.topogen import Topogen, get_topogen
48
49 # Import topoJson from lib, to create topology and initial configuration
50 from lib.common_config import (
51 start_topology,
52 write_test_header,
53 apply_raw_config,
54 write_test_footer,
55 reset_config_on_routers,
56 verify_rib,
57 create_static_routes,
58 check_address_types,
59 step,
60 create_route_maps,
61 create_prefix_lists,
62 )
63 from lib.topolog import logger
64 from lib.bgp import (
65 verify_bgp_convergence,
66 create_router_bgp,
67 verify_bgp_rib,
68 verify_bgp_community,
69 verify_bgp_timers_and_functionality,
70 )
71 from lib.topojson import build_topo_from_json, build_config_from_json
72
73 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
74
75
76 # Reading the data from JSON File for topology and configuration creation
77 jsonFile = "{}/bgp_aggregation.json".format(CWD)
78 try:
79 with open(jsonFile, "r") as topoJson:
80 topo = json.load(topoJson)
81 except IOError:
82 logger.info("Could not read file:", jsonFile)
83
84 # Global variables
85 BGP_CONVERGENCE = False
86 ADDR_TYPES = check_address_types()
87
88 NETWORK_1_1 = {"ipv4": "10.1.1.0/24", "ipv6": "10:1::1:0/120"}
89 NETWORK_1_2 = {"ipv4": "10.1.2.0/24", "ipv6": "10:1::2:0/120"}
90 NETWORK_1_3 = {"ipv4": "10.1.3.0/24", "ipv6": "10:1::3:0/120"}
91 NETWORK_1_4 = {"ipv4": "10.1.4.0/24", "ipv6": "10:1::4:0/120"}
92 NETWORK_1_5 = {"ipv4": "10.1.5.0/24", "ipv6": "10:1::5:0/120"}
93 NETWORK_2_1 = {"ipv4": "10.1.1.100/32", "ipv6": "10:1::1:0/124"}
94 NETWORK_2_2 = {"ipv4": "10.1.5.0/24", "ipv6": "10:1::5:0/120"}
95 NETWORK_2_3 = {"ipv4": "10.1.6.0/24", "ipv6": "10:1::6:0/120"}
96 NETWORK_2_4 = {"ipv4": "10.1.7.0/24", "ipv6": "10:1::7:0/120"}
97 NETWORK_3_1 = {"ipv4": "10.1.8.0/24", "ipv6": "10:1::8:0/120"}
98 NETWORK_4_1 = {"ipv4": "10.2.1.0/24", "ipv6": "10:2::1:0/120"}
99 NEXT_HOP = {"ipv4": "Null0", "ipv6": "Null0"}
100 AGGREGATE_NW = {"ipv4": "10.1.0.0/20", "ipv6": "10:1::/96"}
101
102 COMMUNITY = [
103 "0:1 0:10 0:100",
104 "0:2 0:20 0:200",
105 "0:3 0:30 0:300",
106 "0:4 0:40 0:400",
107 "0:5 0:50 0:500",
108 "0:1 0:2 0:3 0:4 0:5 0:10 0:20 0:30 0:40 0:50 0:100 0:200 0:300 0:400 0:500",
109 "0:3 0:4 0:5 0:30 0:40 0:50 0:300 0:400 0:500",
110 "0:6 0:60 0:600",
111 "0:7 0:70 0:700",
112 "0:3 0:4 0:5 0:6 0:30 0:40 0:50 0:60 0:300 0:400 0:500 0:600",
113 ]
114
115
116 class CreateTopo(Topo):
117 """
118 Test BasicTopo - topology 1
119
120 * `Topo`: Topology object
121 """
122
123 def build(self, *_args, **_opts):
124 """Build function"""
125 tgen = get_topogen(self)
126
127 # Building topology from json file
128 build_topo_from_json(tgen, topo)
129
130
131 def setup_module(mod):
132 """
133 Sets up the pytest environment
134
135 * `mod`: module name
136 """
137
138 testsuite_run_time = time.asctime(time.localtime(time.time()))
139 logger.info("Testsuite start time: {}".format(testsuite_run_time))
140 logger.info("=" * 40)
141
142 logger.info("Running setup_module to create topology")
143
144 # This function initiates the topology build with Topogen...
145 tgen = Topogen(CreateTopo, mod.__name__)
146 # ... and here it calls Mininet initialization functions.
147
148 # Starting topology, create tmp files which are loaded to routers
149 # to start deamons and then start routers
150 start_topology(tgen)
151
152 # Creating configuration from JSON
153 build_config_from_json(tgen, topo)
154
155 # Don't run this test if we have any failure.
156 if tgen.routers_have_failure():
157 pytest.skip(tgen.errors)
158
159 # Api call verify whether BGP is converged
160 ADDR_TYPES = check_address_types()
161
162 for addr_type in ADDR_TYPES:
163 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
164 assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format(
165 BGP_CONVERGENCE
166 )
167
168 logger.info("Running setup_module() done")
169
170
171 def teardown_module(mod):
172 """
173 Teardown the pytest environment
174
175 * `mod`: module name
176 """
177
178 logger.info("Running teardown_module to delete topology")
179
180 tgen = get_topogen()
181
182 # Stop toplogy and Remove tmp files
183 tgen.stop_topology()
184
185 logger.info(
186 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
187 )
188 logger.info("=" * 40)
189
190
191 #####################################################
192 #
193 # Tests starting
194 #
195 #####################################################
196
197
198 def test_route_summarisation_with_summary_only_p1(request):
199 """
200 Verify route summarisation with summary-only for redistributed as well as
201 locally generated routes.
202 """
203
204 tgen = get_topogen()
205 tc_name = request.node.name
206 reset_config_on_routers(tgen)
207 write_test_header(tc_name)
208
209 # Don"t run this test if we have any failure.
210 if tgen.routers_have_failure():
211 pytest.skip(tgen.errors)
212
213 step("Configure static routes on router R1 and redistribute in " "BGP process.")
214
215 for addr_type in ADDR_TYPES:
216 input_static = {
217 "r1": {
218 "static_routes": [
219 {
220 "network": [
221 NETWORK_1_1[addr_type],
222 NETWORK_1_2[addr_type],
223 NETWORK_1_3[addr_type],
224 ],
225 "next_hop": NEXT_HOP[addr_type],
226 }
227 ]
228 }
229 }
230 input_redistribute = {
231 "r1": {
232 "bgp": {
233 "address_family": {
234 addr_type: {
235 "unicast": {"redistribute": [{"redist_type": "static"}]}
236 }
237 }
238 }
239 }
240 }
241
242 step("Configuring {} static routes on router R1 ".format(addr_type))
243
244 result = create_static_routes(tgen, input_static)
245 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
246
247 step(
248 "Configuring redistribute static for {} address-family on router R1 ".format(
249 addr_type
250 )
251 )
252
253 result = create_router_bgp(tgen, topo, input_redistribute)
254 assert result is True, "Testcase {} :Failed \n Error: {}".format(
255 tc_name, result
256 )
257
258 step("Verify that Static routes are redistributed in BGP process")
259
260 for addr_type in ADDR_TYPES:
261 input_static = {
262 "r1": {
263 "static_routes": [
264 {
265 "network": [
266 NETWORK_1_1[addr_type],
267 NETWORK_1_2[addr_type],
268 NETWORK_1_3[addr_type],
269 ]
270 }
271 ]
272 }
273 }
274
275 result = verify_rib(tgen, addr_type, "r3", input_static)
276 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
277
278 step("Advertise some prefixes using network command")
279 step(
280 "Additionally advertise 10.1.4.0/24 & 10.1.5.0/24 and "
281 "10:1::4:0/120 & 10:1::5:0/120 from R4 to R1."
282 )
283
284 for addr_type in ADDR_TYPES:
285 input_advertise = {
286 "r1": {
287 "bgp": {
288 "address_family": {
289 addr_type: {
290 "unicast": {
291 "advertise_networks": [
292 {
293 "network": [
294 NETWORK_2_1[addr_type],
295 NETWORK_2_2[addr_type],
296 NETWORK_2_3[addr_type],
297 NETWORK_2_4[addr_type],
298 ]
299 }
300 ]
301 }
302 }
303 }
304 }
305 },
306 "r4": {
307 "bgp": {
308 "address_family": {
309 addr_type: {
310 "unicast": {
311 "advertise_networks": [
312 {
313 "network": [
314 NETWORK_1_4[addr_type],
315 NETWORK_1_5[addr_type],
316 ]
317 }
318 ]
319 }
320 }
321 }
322 }
323 },
324 }
325
326 result = create_router_bgp(tgen, topo, input_advertise)
327 assert result is True, "Testcase {} :Failed \n Error: {}".format(
328 tc_name, result
329 )
330
331 step(
332 "Verify that advertised prefixes using network command are being "
333 "advertised in BGP process"
334 )
335
336 for addr_type in ADDR_TYPES:
337 input_advertise = {
338 "r1": {
339 "bgp": {
340 "address_family": {
341 addr_type: {
342 "unicast": {
343 "advertise_networks": [
344 {
345 "network": [
346 NETWORK_2_1[addr_type],
347 NETWORK_2_2[addr_type],
348 NETWORK_2_3[addr_type],
349 NETWORK_2_4[addr_type],
350 ]
351 }
352 ]
353 }
354 }
355 }
356 }
357 }
358 }
359
360 result = verify_rib(tgen, addr_type, "r3", input_advertise)
361 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
362
363 step("Configure aggregate-address to summarise all the advertised routes.")
364
365 for addr_type in ADDR_TYPES:
366 route_aggregate = {
367 "r1": {
368 "bgp": {
369 "address_family": {
370 addr_type: {
371 "unicast": {
372 "aggregate_address": [
373 {
374 "network": AGGREGATE_NW[addr_type],
375 "summary": True,
376 }
377 ]
378 }
379 }
380 }
381 }
382 }
383 }
384
385 result = create_router_bgp(tgen, topo, route_aggregate)
386 assert result is True, "Testcase {} :Failed \n Error: {}".format(
387 tc_name, result
388 )
389
390 step(
391 "Verify that we see 1 summarised route and remaining suppressed "
392 "routes on advertising router R1 and only 1 summarised route on "
393 "receiving router R3 for both AFIs."
394 )
395
396 for addr_type in ADDR_TYPES:
397 input_static_agg = {
398 "r1": {"static_routes": [{"network": AGGREGATE_NW[addr_type]}]}
399 }
400
401 input_static = {
402 "r1": {
403 "static_routes": [
404 {
405 "network": [
406 NETWORK_1_1[addr_type],
407 NETWORK_1_2[addr_type],
408 NETWORK_1_3[addr_type],
409 ]
410 }
411 ]
412 }
413 }
414
415 result = verify_rib(tgen, addr_type, "r3", input_static_agg, protocol="bgp")
416 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
417
418 result = verify_rib(
419 tgen, addr_type, "r3", input_static, protocol="bgp", expected=False
420 )
421 assert (
422 result is not True
423 ), "Testcase : Failed \n " "Routes are still present \n Error: {}".format(
424 tc_name, result
425 )
426
427 result = verify_rib(tgen, addr_type, "r1", input_static_agg, protocol="bgp")
428 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
429
430 result = verify_rib(tgen, addr_type, "r1", input_static)
431 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
432
433 for action, value in zip(["removed", "add"], [True, False]):
434
435 step(
436 "{} static routes as below: "
437 "(no) ip route 10.1.1.0/24 and (no) ip route 10.1.2.0/24"
438 "(no) ipv6 route 10:1::1:0/120 and (no) ip route 10:1::2:0/120".format(
439 action
440 )
441 )
442
443 for addr_type in ADDR_TYPES:
444 input_static = {
445 "r1": {
446 "static_routes": [
447 {
448 "network": [NETWORK_1_1[addr_type], NETWORK_1_2[addr_type]],
449 "next_hop": NEXT_HOP[addr_type],
450 "delete": value,
451 }
452 ]
453 }
454 }
455
456 result = create_static_routes(tgen, input_static)
457 assert result is True, "Testcase : Failed \n Error: {}".format(
458 tc_name, result
459 )
460
461 step(
462 "Verify that there is no impact on R3, as summarised route remains "
463 "intact. However suppressed routes on R1 disappear and re-appear "
464 "based on {} static routes.".format(action)
465 )
466
467 for addr_type in ADDR_TYPES:
468 input_static_1 = {
469 "r1": {
470 "static_routes": [
471 {"network": [NETWORK_1_1[addr_type], NETWORK_1_2[addr_type]]}
472 ]
473 }
474 }
475
476 input_static_2 = {
477 "r1": {"static_routes": [{"network": AGGREGATE_NW[addr_type]}]}
478 }
479
480 if value:
481 result = verify_rib(
482 tgen, addr_type, "r1", input_static_1, expected=False
483 )
484 assert result is not True, (
485 "Testcase : Failed \n "
486 "Routes are still present \n Error: {}".format(tc_name, result)
487 )
488 else:
489 result = verify_rib(tgen, addr_type, "r1", input_static_1)
490 assert result is True, "Testcase : Failed \n Error: {}".format(
491 tc_name, result
492 )
493
494 result = verify_rib(tgen, addr_type, "r3", input_static_2, protocol="bgp")
495 assert result is True, "Testcase : Failed \n Error: {}".format(
496 tc_name, result
497 )
498
499 step(
500 "{} prefixes using network command as below:"
501 "(no) network 10.1.6.1/24 and (no) network 10.1.7.1/24"
502 "(no) network 10:1::6:0/120 and (no) network 10:1::7:0/120".format(action)
503 )
504
505 for addr_type in ADDR_TYPES:
506 input_advertise = {
507 "r1": {
508 "bgp": {
509 "address_family": {
510 addr_type: {
511 "unicast": {
512 "advertise_networks": [
513 {
514 "network": [
515 NETWORK_2_3[addr_type],
516 NETWORK_2_4[addr_type],
517 ],
518 "delete": value,
519 }
520 ]
521 }
522 }
523 }
524 }
525 }
526 }
527
528 result = create_router_bgp(tgen, topo, input_advertise)
529 assert result is True, "Testcase {} :Failed \n Error: {}".format(
530 tc_name, result
531 )
532
533 step(
534 "Verify that there is no impact on R3, as summarised route remains "
535 "intact. However suppressed routes on R1 disappear and re-appear "
536 "based on {} of network command.".format(action)
537 )
538
539 for addr_type in ADDR_TYPES:
540 input_advertise_1 = {
541 "r1": {
542 "bgp": {
543 "address_family": {
544 addr_type: {
545 "unicast": {
546 "advertise_networks": [
547 {
548 "network": [
549 NETWORK_2_3[addr_type],
550 NETWORK_2_4[addr_type],
551 ]
552 }
553 ]
554 }
555 }
556 }
557 }
558 }
559 }
560
561 input_advertise_2 = {
562 "r1": {
563 "bgp": {
564 "address_family": {
565 addr_type: {
566 "unicast": {
567 "advertise_networks": [
568 {"network": AGGREGATE_NW[addr_type]}
569 ]
570 }
571 }
572 }
573 }
574 }
575 }
576
577 if value:
578 result = verify_bgp_rib(
579 tgen, addr_type, "r1", input_advertise_1, expected=False
580 )
581 assert result is not True, (
582 "Testcase : Failed \n "
583 "Routes are still present \n Error: {}".format(tc_name, result)
584 )
585 else:
586 result = verify_bgp_rib(tgen, addr_type, "r1", input_advertise_1)
587 assert result is True, "Testcase : Failed \n Error: {}".format(
588 tc_name, result
589 )
590
591 result = verify_rib(tgen, addr_type, "r3", input_advertise_2)
592 assert result is True, "Testcase : Failed \n Error: {}".format(
593 tc_name, result
594 )
595
596 step(
597 "Add a new network each one from out of aggregation range and "
598 "other within aggregation range. "
599 )
600
601 for addr_type in ADDR_TYPES:
602 input_static = {
603 "r1": {
604 "static_routes": [
605 {"network": NETWORK_3_1[addr_type], "next_hop": NEXT_HOP[addr_type]}
606 ]
607 }
608 }
609
610 result = create_static_routes(tgen, input_static)
611 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
612
613 for addr_type in ADDR_TYPES:
614 input_advertise = {
615 "r1": {
616 "bgp": {
617 "address_family": {
618 addr_type: {
619 "unicast": {
620 "advertise_networks": [
621 {
622 "network": NETWORK_4_1[addr_type],
623 }
624 ]
625 }
626 }
627 }
628 }
629 }
630 }
631
632 result = create_router_bgp(tgen, topo, input_advertise)
633 assert result is True, "Testcase {} :Failed \n Error: {}".format(
634 tc_name, result
635 )
636
637 step(
638 "Verify that when a network within aggregation range is added, "
639 "there is no impact on receiving router. However if a network "
640 "outside aggregation range is added/removed, R3 receives and "
641 "withdraws it accordingly."
642 )
643
644 for addr_type in ADDR_TYPES:
645 input_static = {"r1": {"static_routes": [{"network": AGGREGATE_NW[addr_type]}]}}
646
647 result = verify_rib(tgen, addr_type, "r3", input_static, protocol="bgp")
648 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
649
650 input_advertise_2 = {
651 "r1": {
652 "bgp": {
653 "address_family": {
654 addr_type: {
655 "unicast": {
656 "advertise_networks": [
657 {
658 "network": [
659 NETWORK_4_1[addr_type],
660 AGGREGATE_NW[addr_type],
661 ]
662 }
663 ]
664 }
665 }
666 }
667 }
668 }
669 }
670
671 result = verify_rib(tgen, addr_type, "r3", input_advertise_2, protocol="bgp")
672 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
673
674 for action, value in zip(["Delete", "Re-add"], [True, False]):
675 step("{} aggregation command from R1.".format(action))
676
677 for addr_type in ADDR_TYPES:
678 route_aggregate = {
679 "r1": {
680 "bgp": {
681 "address_family": {
682 addr_type: {
683 "unicast": {
684 "aggregate_address": [
685 {
686 "network": AGGREGATE_NW[addr_type],
687 "summary": True,
688 "delete": value,
689 }
690 ]
691 }
692 }
693 }
694 }
695 }
696 }
697
698 result = create_router_bgp(tgen, topo, route_aggregate)
699 assert result is True, "Testcase {} :Failed \n Error: {}".format(
700 tc_name, result
701 )
702
703 step(
704 "Verify on both routers that summarised route is withdrawn from R1 "
705 "and R3 when aggregate-address command is removed and appears again "
706 "when aggregate-address command is re-added. Check for both AFIs."
707 )
708
709 for addr_type in ADDR_TYPES:
710 input_static_agg = {
711 "r1": {"static_routes": [{"network": AGGREGATE_NW[addr_type]}]}
712 }
713
714 if value:
715 result = verify_rib(
716 tgen, addr_type, "r1", input_static_agg, expected=False
717 )
718 assert result is not True, (
719 "Testcase : Failed \n "
720 "Aggregated route is still present \n Error: {}".format(
721 tc_name, result
722 )
723 )
724
725 result = verify_rib(
726 tgen, addr_type, "r3", input_static_agg, expected=False
727 )
728 assert result is not True, (
729 "Testcase : Failed \n "
730 "Aggregated route is still present \n Error: {}".format(
731 tc_name, result
732 )
733 )
734 else:
735 result = verify_rib(tgen, addr_type, "r1", input_static_agg)
736 assert result is True, "Testcase : Failed \n Error: {}".format(
737 tc_name, result
738 )
739
740 result = verify_rib(tgen, addr_type, "r3", input_static_agg)
741 assert result is True, "Testcase : Failed \n Error: {}".format(
742 tc_name, result
743 )
744
745 write_test_footer(tc_name)
746
747
748 def test_route_summarisation_with_as_set_p1(request):
749 """
750 Verify route summarisation with as-set for redistributed routes.
751 """
752
753 tgen = get_topogen()
754 tc_name = request.node.name
755 reset_config_on_routers(tgen)
756 write_test_header(tc_name)
757
758 # Don"t run this test if we have any failure.
759 if tgen.routers_have_failure():
760 pytest.skip(tgen.errors)
761
762 step("Configure static routes on router R1 and redistribute in " "BGP process.")
763
764 for addr_type in ADDR_TYPES:
765 input_static = {
766 "r1": {
767 "static_routes": [
768 {
769 "network": [
770 NETWORK_1_1[addr_type],
771 NETWORK_1_2[addr_type],
772 NETWORK_1_3[addr_type],
773 NETWORK_1_4[addr_type],
774 NETWORK_1_5[addr_type],
775 ],
776 "next_hop": NEXT_HOP[addr_type],
777 }
778 ]
779 }
780 }
781 input_redistribute = {
782 "r1": {
783 "bgp": {
784 "address_family": {
785 addr_type: {
786 "unicast": {"redistribute": [{"redist_type": "static"}]}
787 }
788 }
789 }
790 }
791 }
792
793 step("Configuring {} static routes on router R1 ".format(addr_type))
794
795 result = create_static_routes(tgen, input_static)
796 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
797
798 step(
799 "Configuring redistribute static for {} address-family on router R1 ".format(
800 addr_type
801 )
802 )
803
804 result = create_router_bgp(tgen, topo, input_redistribute)
805 assert result is True, "Testcase {} :Failed \n Error: {}".format(
806 tc_name, result
807 )
808
809 step("Verify that Static routes are redistributed in BGP process")
810
811 for addr_type in ADDR_TYPES:
812 input_static = {
813 "r1": {
814 "static_routes": [
815 {
816 "network": [
817 NETWORK_1_1[addr_type],
818 NETWORK_1_2[addr_type],
819 NETWORK_1_3[addr_type],
820 NETWORK_1_4[addr_type],
821 NETWORK_1_5[addr_type],
822 ]
823 }
824 ]
825 }
826 }
827
828 result = verify_rib(tgen, addr_type, "r3", input_static)
829 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
830
831 step(
832 "Configure a route-map to attach a unique community attribute value "
833 "to each of these prefixes, while re-distributing static."
834 )
835
836 for addr_type in ADDR_TYPES:
837 for pfx, seq_id, network, in zip(
838 [1, 2, 3, 4, 5],
839 [10, 20, 30, 40, 50],
840 [NETWORK_1_1, NETWORK_1_2, NETWORK_1_3, NETWORK_1_4, NETWORK_1_5],
841 ):
842 prefix_list = {
843 "r1": {
844 "prefix_lists": {
845 addr_type: {
846 "pf_list_{}_{}".format(addr_type, pfx): [
847 {
848 "seqid": seq_id,
849 "network": network[addr_type],
850 "action": "permit",
851 }
852 ]
853 }
854 }
855 }
856 }
857 result = create_prefix_lists(tgen, prefix_list)
858 assert result is True, "Test case {} : Failed \n Error: {}".format(
859 tc_name, result
860 )
861
862 step("Create route-map for applying prefix-list on r1")
863
864 for addr_type in ADDR_TYPES:
865 for pfx, comm_id in zip([1, 2, 3, 4, 5], [0, 1, 2, 3, 4]):
866 route_map = {
867 "r1": {
868 "route_maps": {
869 "rmap_{}".format(addr_type): [
870 {
871 "action": "permit",
872 "match": {
873 addr_type: {
874 "prefix_lists": "pf_list_{}_{}".format(
875 addr_type, pfx
876 )
877 }
878 },
879 "set": {"community": {"num": COMMUNITY[comm_id]}},
880 }
881 ]
882 }
883 }
884 }
885
886 result = create_route_maps(tgen, route_map)
887 assert result is True, "Testcase {} :Failed \n Error: {}".format(
888 tc_name, result
889 )
890
891 step("Re-configure redistribute static with route-map")
892
893 for addr_type in ADDR_TYPES:
894 input_redistribute = {
895 "r1": {
896 "bgp": {
897 "address_family": {
898 addr_type: {
899 "unicast": {
900 "redistribute": [
901 {
902 "redist_type": "static",
903 "attribute": {
904 "route-map": "rmap_{}".format(addr_type)
905 },
906 }
907 ]
908 }
909 }
910 }
911 }
912 }
913 }
914
915 result = create_router_bgp(tgen, topo, input_redistribute)
916 assert result is True, "Testcase {} :Failed \n Error: {}".format(
917 tc_name, result
918 )
919
920 step("Configure aggregate-address to summarise all the advertised routes.")
921
922 for addr_type in ADDR_TYPES:
923 route_aggregate = {
924 "r1": {
925 "bgp": {
926 "address_family": {
927 addr_type: {
928 "unicast": {
929 "aggregate_address": [
930 {"network": AGGREGATE_NW[addr_type], "as_set": True}
931 ]
932 }
933 }
934 }
935 }
936 }
937 }
938
939 result = create_router_bgp(tgen, topo, route_aggregate)
940 assert result is True, "Testcase {} :Failed \n Error: {}".format(
941 tc_name, result
942 )
943
944 step(
945 "Verify that we see summarised route on router R3 with all the "
946 "community attribute values combined with that aggregate route."
947 )
948
949 for addr_type in ADDR_TYPES:
950 input_dict = {"community": COMMUNITY[5]}
951 result = verify_bgp_community(
952 tgen, addr_type, "r3", [AGGREGATE_NW[addr_type]], input_dict
953 )
954 assert result is True, "Test case {} : Failed \n Error: {}".format(
955 tc_name, result
956 )
957
958 step(
959 "Remove static routes as below: "
960 "(no) ip route 10.1.1.0/24 blackhole "
961 "(no) ip route 10.1.2.0/24 blackhole "
962 "(no) ipv6 route 10:1::1:0/120 blackhole "
963 "(no) ipv6 route 10:1::2:0/120 blackhole "
964 )
965
966 for addr_type in ADDR_TYPES:
967 input_static = {
968 "r1": {
969 "static_routes": [
970 {
971 "network": [NETWORK_1_1[addr_type], NETWORK_1_2[addr_type]],
972 "next_hop": NEXT_HOP[addr_type],
973 "delete": True,
974 }
975 ]
976 }
977 }
978
979 result = create_static_routes(tgen, input_static)
980 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
981
982 step(
983 "Verify on R3 that whenever we remove the static routes, we still"
984 " see aggregated route however the corresponding community attribute"
985 "values are withdrawn."
986 )
987
988 for addr_type in ADDR_TYPES:
989 input_dict = {"community": COMMUNITY[6]}
990 result = verify_bgp_community(
991 tgen, addr_type, "r3", [AGGREGATE_NW[addr_type]], input_dict
992 )
993 assert result is True, "Test case {} : Failed \n Error: {}".format(
994 tc_name, result
995 )
996
997 step(
998 "Add/remove a new network with community value, each one from out of "
999 "aggregation range and other within aggregation range. "
1000 )
1001
1002 step(
1003 "Add a new network each one from out of aggregation range and "
1004 "other within aggregation range. "
1005 )
1006
1007 for addr_type in ADDR_TYPES:
1008 input_static = {
1009 "r1": {
1010 "static_routes": [
1011 {
1012 "network": [NETWORK_3_1[addr_type], NETWORK_4_1[addr_type]],
1013 "next_hop": NEXT_HOP[addr_type],
1014 }
1015 ]
1016 }
1017 }
1018
1019 result = create_static_routes(tgen, input_static)
1020 assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
1021
1022 for addr_type in ADDR_TYPES:
1023 for (
1024 pfx,
1025 seq_id,
1026 network,
1027 ) in zip([6, 7], [60, 70], [NETWORK_3_1, NETWORK_4_1]):
1028 prefix_list = {
1029 "r1": {
1030 "prefix_lists": {
1031 addr_type: {
1032 "pf_list_{}_{}".format(addr_type, pfx): [
1033 {
1034 "seqid": seq_id,
1035 "network": network[addr_type],
1036 "action": "permit",
1037 }
1038 ]
1039 }
1040 }
1041 }
1042 }
1043 result = create_prefix_lists(tgen, prefix_list)
1044 assert result is True, "Test case {} : Failed \n Error: {}".format(
1045 tc_name, result
1046 )
1047
1048 step("Create route-map for applying prefix-list on r1")
1049
1050 for addr_type in ADDR_TYPES:
1051 for pfx, comm_id in zip([6, 7], [7, 8]):
1052 route_map = {
1053 "r1": {
1054 "route_maps": {
1055 "rmap_{}".format(addr_type): [
1056 {
1057 "action": "permit",
1058 "match": {
1059 addr_type: {
1060 "prefix_lists": "pf_list_{}_{}".format(
1061 addr_type, pfx
1062 )
1063 }
1064 },
1065 "set": {"community": {"num": COMMUNITY[comm_id]}},
1066 }
1067 ]
1068 }
1069 }
1070 }
1071
1072 result = create_route_maps(tgen, route_map)
1073 assert result is True, "Testcase {} :Failed \n Error: {}".format(
1074 tc_name, result
1075 )
1076
1077 step(
1078 "Verify on R3 when route is added within the summary range, aggregated"
1079 " route also has associated community value added. However if the route"
1080 " is beyond the summary range the aggregated route would have no impact"
1081 )
1082
1083 for addr_type in ADDR_TYPES:
1084 input_dict = {"community": COMMUNITY[9]}
1085 result = verify_bgp_community(
1086 tgen, addr_type, "r3", [AGGREGATE_NW[addr_type]], input_dict
1087 )
1088 assert result is True, "Test case {} : Failed \n Error: {}".format(
1089 tc_name, result
1090 )
1091
1092 for action, value in zip(["Delete", "Re-add"], [True, False]):
1093 step("{} aggregation command from R1.".format(action))
1094
1095 for addr_type in ADDR_TYPES:
1096 route_aggregate = {
1097 "r1": {
1098 "bgp": {
1099 "address_family": {
1100 addr_type: {
1101 "unicast": {
1102 "aggregate_address": [
1103 {
1104 "network": AGGREGATE_NW[addr_type],
1105 "as_set": True,
1106 "delete": value,
1107 }
1108 ]
1109 }
1110 }
1111 }
1112 }
1113 }
1114 }
1115
1116 result = create_router_bgp(tgen, topo, route_aggregate)
1117 assert result is True, "Testcase {} :Failed \n Error: {}".format(
1118 tc_name, result
1119 )
1120
1121 step(
1122 "Verify that when as-set command is removed, we do not see community "
1123 "attribute added to summarised route on R3. However when as-set option "
1124 "is re-added, all the community attribute values must appear with "
1125 "summarised route."
1126 )
1127
1128 for addr_type in ADDR_TYPES:
1129 input_static_agg = {
1130 "r1": {"static_routes": [{"network": AGGREGATE_NW[addr_type]}]}
1131 }
1132
1133 if value:
1134 result = verify_rib(
1135 tgen, addr_type, "r1", input_static_agg, expected=False
1136 )
1137 assert result is not True, (
1138 "Testcase : Failed \n "
1139 "Aggregated route is still present \n Error: {}".format(
1140 tc_name, result
1141 )
1142 )
1143
1144 result = verify_rib(
1145 tgen, addr_type, "r3", input_static_agg, expected=False
1146 )
1147 assert result is not True, (
1148 "Testcase : Failed \n "
1149 "Aggregated route is still present \n Error: {}".format(
1150 tc_name, result
1151 )
1152 )
1153 else:
1154 result = verify_rib(tgen, addr_type, "r1", input_static_agg)
1155 assert result is True, "Testcase : Failed \n Error: {}".format(
1156 tc_name, result
1157 )
1158
1159 result = verify_rib(tgen, addr_type, "r3", input_static_agg)
1160 assert result is True, "Testcase : Failed \n Error: {}".format(
1161 tc_name, result
1162 )
1163
1164 input_dict = {"community": COMMUNITY[9]}
1165 result = verify_bgp_community(
1166 tgen, addr_type, "r3", [AGGREGATE_NW[addr_type]], input_dict
1167 )
1168 assert result is True, "Test case {} : Failed \n Error: {}".format(
1169 tc_name, result
1170 )
1171
1172 write_test_footer(tc_name)
1173
1174
1175 if __name__ == "__main__":
1176 args = ["-s"] + sys.argv[1:]
1177 sys.exit(pytest.main(args))