]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_large_community / test_bgp_large_community_topo_1.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
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 #
9
10
11 """
12 Following tests are covered to test large-community/community functionality:
13 1. Verify if large community attribute can be configured only in correct
14 canonical format.
15 2. Verify that the community attribute value, which we have advertised are
16 received in correct format and values, at the receiving end.
17 3. Verify BGP Large Community attribute"s transitive property attribute.
18 4. Verify that BGP Large Communities attribute are malformed, if the length of
19 the BGP Large Communities Attribute value, expressed in octets,
20 is not a non-zero multiple of 12.
21 5. Verify if overriding large community values works fine.
22 6. Verify that large community values" aggregation works fine.
23 7. Standard community also work fine in conjunction with large-community.
24 8. Matching prefixes based on attributes other than prefix list and make use
25 of set clause (IPV6).
26 9. Matching prefixes based on attributes other than prefix list and make use
27 of set clause (IPV4).
28 10. Verify community and large-community list operations in route-map with all
29 clause (exact, all, any, regex) works.
30 11. Verify that any value in BGP Large communities for boundary values.
31 12. Clear BGP neighbor-ship and check if large community and community
32 attributes are getting re-populated.
33
34 """
35
36 import pytest
37 import time
38 from os import path as os_path
39 import sys
40
41 # Required to instantiate the topology builder class.
42 from lib.topogen import Topogen, get_topogen
43
44 from lib.common_config import (
45 start_topology,
46 write_test_header,
47 write_test_footer,
48 reset_config_on_routers,
49 create_route_maps,
50 create_bgp_community_lists,
51 create_prefix_lists,
52 verify_bgp_community,
53 step,
54 check_address_types,
55 required_linux_kernel_version,
56 )
57 from lib.topolog import logger
58 from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
59 from lib.topojson import build_config_from_json
60
61 pytestmark = [pytest.mark.bgpd]
62
63
64 # Save the Current Working Directory to find configuration files.
65 CWD = os_path.dirname(os_path.realpath(__file__))
66 sys.path.append(os_path.join(CWD, "../"))
67 sys.path.append(os_path.join(CWD, "../lib/"))
68
69
70 # Global variables
71 bgp_convergence = False
72 NETWORK = {
73 "ipv4": ["200.50.2.0", "200.50.2.1", "200.50.2.0"],
74 "ipv6": ["1::1", "1::2", "1::0"],
75 }
76 MASK = {"ipv4": "32", "ipv6": "128"}
77 NET_MASK = {"ipv4": "24", "ipv6": "120"}
78 IPV4_NET = ["200.50.2.0"]
79 IPV6_NET = ["1::0"]
80 CONFIG_ROUTER_R1 = False
81 CONFIG_ROUTER_R2 = False
82 CONFIG_ROUTER_ADDITIVE = False
83 ADDR_TYPES = []
84 LARGE_COMM = {
85 "r1": "1:1:1 1:2:1 1:3:1 1:4:1 1:5:1",
86 "r2": "2:1:1 2:2:1 2:3:1 2:4:1 2:5:1",
87 "mal_1": "1:1 1:2 1:3 1:4 1:5",
88 "pf_list_1": "0:0:1 0:0:10 0:0:100",
89 "pf_list_2": "0:0:2 0:0:20 0:0:200",
90 "agg_1": "0:0:1 0:0:2 0:0:10 0:0:20 0:0:100 0:0:200 2:1:1 "
91 "2:2:1 2:3:1 2:4:1 2:5:1",
92 "agg_2": "0:0:2 0:0:20 0:0:200 2:1:1 " "2:2:1 2:3:1 2:4:1 2:5:1",
93 }
94 STANDARD_COMM = {
95 "r1": "1:1 1:2 1:3 1:4 1:5",
96 "r2": "2:1 2:2 2:3 2:4 2:5",
97 "mal_1": "1 2 3 4 5",
98 "pf_list_1": "0:1 0:10 0:100",
99 "pf_list_2": "0:2 0:20 0:200",
100 "agg_1": "0:1 0:2 0:10 0:20 0:100 0:200 2:1 2:2 2:3 2:4 2:5",
101 "agg_2": "0:2 0:20 0:200 2:1 2:2 2:3 2:4 2:5",
102 }
103
104
105 def setup_module(mod):
106 """
107 Sets up the pytest environment
108
109 * `mod`: module name
110 """
111 # Required linux kernel version for this suite to run.
112 result = required_linux_kernel_version("4.15")
113 if result is not True:
114 pytest.skip("Kernel requirements are not met")
115
116 global ADDR_TYPES
117 testsuite_run_time = time.asctime(time.localtime(time.time()))
118 logger.info("Testsuite start time: {}".format(testsuite_run_time))
119 logger.info("=" * 40)
120
121 logger.info("Running setup_module to create topology")
122
123 # This function initiates the topology build with Topogen...
124 json_file = "{}/bgp_large_community_topo_1.json".format(CWD)
125 tgen = Topogen(json_file, mod.__name__)
126 global topo
127 topo = tgen.json_topo
128 # ... and here it calls Mininet initialization functions.
129
130 # Starting topology, create tmp files which are loaded to routers
131 # to start daemons and then start routers
132 start_topology(tgen)
133
134 # Creating configuration from JSON
135 build_config_from_json(tgen, topo)
136
137 # Checking BGP convergence
138 global bgp_convergence
139
140 # Don"t run this test if we have any failure.
141 if tgen.routers_have_failure():
142 pytest.skip(tgen.errors)
143
144 ##tgen.mininet_cli()
145 # Api call verify whether BGP is converged
146 bgp_convergence = verify_bgp_convergence(tgen, topo)
147 assert bgp_convergence is True, "setup_module :Failed \n Error:" " {}".format(
148 bgp_convergence
149 )
150
151 ADDR_TYPES = check_address_types()
152 logger.info("Running setup_module() done")
153
154
155 def teardown_module():
156 """
157 Teardown the pytest environment
158
159 * `mod`: module name
160 """
161
162 logger.info("Running teardown_module to delete topology")
163
164 tgen = get_topogen()
165
166 # Stop toplogy and Remove tmp files
167 tgen.stop_topology()
168
169 logger.info(
170 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
171 )
172 logger.info("=" * 40)
173
174
175 def config_router_r1(tgen, topo, tc_name):
176 global CONFIG_ROUTER_R1
177
178 input_dict_1 = {
179 "r1": {
180 "route_maps": {
181 "LC1": [
182 {
183 "action": "permit",
184 "seq_id": "10",
185 "set": {
186 "large_community": {"num": LARGE_COMM["r1"]},
187 "community": {"num": STANDARD_COMM["r1"]},
188 },
189 }
190 ]
191 }
192 }
193 }
194
195 step("Configuring LC1 on r1")
196 result = create_route_maps(tgen, input_dict_1)
197 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
198
199 # Configure neighbor for route map
200 input_dict_2 = {
201 "r1": {
202 "bgp": {
203 "address_family": {
204 "ipv4": {
205 "unicast": {
206 "advertise_networks": [
207 {
208 "network": "%s/%s"
209 % (NETWORK["ipv4"][0], MASK["ipv4"]),
210 "no_of_network": 4,
211 }
212 ],
213 "neighbor": {
214 "r2": {
215 "dest_link": {
216 "r1-link1": {
217 "route_maps": [
218 {"name": "LC1", "direction": "out"}
219 ]
220 }
221 }
222 },
223 "r3": {
224 "dest_link": {
225 "r1-link1": {
226 "route_maps": [
227 {"name": "LC1", "direction": "out"}
228 ]
229 }
230 }
231 },
232 },
233 }
234 },
235 "ipv6": {
236 "unicast": {
237 "advertise_networks": [
238 {
239 "network": "%s/%s"
240 % (NETWORK["ipv6"][0], MASK["ipv6"]),
241 "no_of_network": 4,
242 }
243 ],
244 "neighbor": {
245 "r2": {
246 "dest_link": {
247 "r1-link1": {
248 "route_maps": [
249 {"name": "LC1", "direction": "out"}
250 ]
251 }
252 }
253 },
254 "r3": {
255 "dest_link": {
256 "r1-link1": {
257 "route_maps": [
258 {"name": "LC1", "direction": "out"}
259 ]
260 }
261 }
262 },
263 },
264 }
265 },
266 }
267 }
268 }
269 }
270
271 step("Applying LC1 on r1 neighbors and advertising networks")
272 result = create_router_bgp(tgen, topo, input_dict_2)
273 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
274
275 CONFIG_ROUTER_R1 = True
276
277
278 def config_router_r2(tgen, topo, tc_name):
279 global CONFIG_ROUTER_R2
280
281 input_dict = {
282 "r2": {
283 "route_maps": {
284 "LC2": [
285 {
286 "action": "permit",
287 "seq_id": "10",
288 "set": {
289 "large_community": {"num": LARGE_COMM["r2"]},
290 "community": {"num": STANDARD_COMM["r2"]},
291 },
292 }
293 ]
294 }
295 }
296 }
297
298 step("Configuring route-maps LC2 on r2")
299 result = create_route_maps(tgen, input_dict)
300 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
301
302 input_dict_1 = {
303 "r2": {
304 "bgp": {
305 "address_family": {
306 "ipv4": {
307 "unicast": {
308 "neighbor": {
309 "r4": {
310 "dest_link": {
311 "r2-link1": {
312 "route_maps": [
313 {"name": "LC2", "direction": "out"}
314 ]
315 }
316 }
317 }
318 }
319 }
320 },
321 "ipv6": {
322 "unicast": {
323 "neighbor": {
324 "r4": {
325 "dest_link": {
326 "r2-link1": {
327 "route_maps": [
328 {"name": "LC2", "direction": "out"}
329 ]
330 }
331 }
332 }
333 }
334 }
335 },
336 }
337 }
338 }
339 }
340
341 step("Applying LC2 on r2 neighbors in out direction")
342 result = create_router_bgp(tgen, topo, input_dict_1)
343 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
344
345 CONFIG_ROUTER_R2 = True
346
347
348 def config_router_additive(tgen, topo, tc_name):
349 global CONFIG_ROUTER_ADDITIVE
350
351 input_dict = {
352 "r2": {
353 "route_maps": {
354 "LC2": [
355 {
356 "action": "permit",
357 "seq_id": "10",
358 "set": {
359 "large_community": {
360 "num": LARGE_COMM["r2"],
361 "action": "additive",
362 },
363 "community": {
364 "num": STANDARD_COMM["r2"],
365 "action": "additive",
366 },
367 },
368 }
369 ]
370 }
371 }
372 }
373
374 step("Configuring LC2 with community attributes as additive")
375 result = create_route_maps(tgen, input_dict)
376 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
377
378 # tgen.mininet_cli()
379 CONFIG_ROUTER_ADDITIVE = True
380
381
382 def config_for_as_path(tgen, topo, tc_name):
383 config_router_r1(tgen, topo, tc_name)
384
385 config_router_r2(tgen, topo, tc_name)
386
387 # Create ipv6 prefix list
388 input_dict_1 = {
389 "r1": {
390 "prefix_lists": {
391 "ipv4": {
392 "pf_list_1": [
393 {
394 "seqid": "10",
395 "network": "%s/%s" % (NETWORK["ipv4"][0], MASK["ipv4"]),
396 "action": "permit",
397 }
398 ],
399 "pf_list_2": [
400 {
401 "seqid": "10",
402 "network": "%s/%s" % (NETWORK["ipv4"][1], MASK["ipv4"]),
403 "action": "permit",
404 }
405 ],
406 },
407 "ipv6": {
408 "pf_list_3": [
409 {
410 "seqid": "10",
411 "network": "%s/%s" % (NETWORK["ipv6"][0], MASK["ipv6"]),
412 "action": "permit",
413 }
414 ],
415 "pf_list_4": [
416 {
417 "seqid": "10",
418 "network": "%s/%s" % (NETWORK["ipv6"][1], MASK["ipv6"]),
419 "action": "permit",
420 }
421 ],
422 },
423 }
424 }
425 }
426
427 step("Configuring prefix-lists on r1 to filter networks")
428 result = create_prefix_lists(tgen, input_dict_1)
429 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
430
431 input_dict_2 = {
432 "r1": {
433 "route_maps": {
434 "LC1": [
435 {
436 "action": "permit",
437 "seq_id": 10,
438 "match": {"ipv4": {"prefix_lists": "pf_list_1"}},
439 "set": {
440 "large_community": {"num": LARGE_COMM["pf_list_1"]},
441 "community": {"num": STANDARD_COMM["pf_list_1"]},
442 },
443 },
444 {
445 "action": "permit",
446 "seq_id": 20,
447 "match": {"ipv6": {"prefix_lists": "pf_list_3"}},
448 "set": {
449 "large_community": {"num": LARGE_COMM["pf_list_1"]},
450 "community": {"num": STANDARD_COMM["pf_list_1"]},
451 },
452 },
453 {
454 "action": "permit",
455 "seq_id": 30,
456 "match": {"ipv4": {"prefix_lists": "pf_list_2"}},
457 "set": {
458 "large_community": {"num": LARGE_COMM["pf_list_2"]},
459 "community": {"num": STANDARD_COMM["pf_list_2"]},
460 },
461 },
462 {
463 "action": "permit",
464 "seq_id": 40,
465 "match": {"ipv6": {"prefix_lists": "pf_list_4"}},
466 "set": {
467 "large_community": {"num": LARGE_COMM["pf_list_2"]},
468 "community": {"num": STANDARD_COMM["pf_list_2"]},
469 },
470 },
471 ]
472 }
473 }
474 }
475
476 step(
477 "Applying prefix-lists match in route-map LC1 on r1. Setting"
478 " community attritbute for filtered networks"
479 )
480 result = create_route_maps(tgen, input_dict_2)
481 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
482
483 config_router_additive(tgen, topo, tc_name)
484
485 input_dict_3 = {
486 "r4": {
487 "bgp_community_lists": [
488 {
489 "community_type": "standard",
490 "action": "permit",
491 "name": "ANY",
492 "value": LARGE_COMM["pf_list_1"],
493 "large": True,
494 },
495 {
496 "community_type": "standard",
497 "action": "permit",
498 "name": "ANY",
499 "value": STANDARD_COMM["pf_list_1"],
500 },
501 ]
502 }
503 }
504
505 step("Configuring bgp community lists on r4")
506 result = create_bgp_community_lists(tgen, input_dict_3)
507 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
508
509 input_dict_4 = {
510 "r4": {
511 "route_maps": {
512 "LC4": [
513 {
514 "action": "permit",
515 "seq_id": "10",
516 "match": {
517 "large_community_list": {"id": "ANY"},
518 "community_list": {"id": "ANY"},
519 },
520 "set": {"path": {"as_num": "4000000", "as_action": "prepend"}},
521 }
522 ]
523 }
524 }
525 }
526
527 step("Applying community list on route-map on r4")
528 result = create_route_maps(tgen, input_dict_4)
529 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
530
531 input_dict_5 = {
532 "r4": {
533 "bgp": {
534 "address_family": {
535 "ipv4": {
536 "unicast": {
537 "neighbor": {
538 "r5": {
539 "dest_link": {
540 "r4-link1": {
541 "route_maps": [
542 {"name": "LC4", "direction": "out"}
543 ]
544 }
545 }
546 }
547 }
548 }
549 },
550 "ipv6": {
551 "unicast": {
552 "neighbor": {
553 "r5": {
554 "dest_link": {
555 "r4-link1": {
556 "route_maps": [
557 {"name": "LC4", "direction": "out"}
558 ]
559 }
560 }
561 }
562 }
563 }
564 },
565 }
566 }
567 }
568 }
569
570 step("Applying route-map LC4 out from r4 to r5 ")
571 result = create_router_bgp(tgen, topo, input_dict_5)
572 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
573
574
575 #####################################################
576 #
577 # Test cases
578 #
579 #####################################################
580 def test_large_community_set(request):
581 """
582 Verify if large community attribute can be configured only in correct
583 canonical format.
584 """
585 tc_name = request.node.name
586 write_test_header(tc_name)
587 tgen = get_topogen()
588
589 # Don"t run this test if we have any failure.
590 if tgen.routers_have_failure():
591 pytest.skip(tgen.errors)
592
593 # API call to modify router id
594 # input_dict dictionary to be provided to configure route_map
595 input_dict = {
596 "r1": {
597 "route_maps": {
598 "LC1": [
599 {
600 "action": "permit",
601 "seq_id": "10",
602 "set": {
603 "large_community": {"num": LARGE_COMM["r1"]},
604 "community": {"num": STANDARD_COMM["r1"]},
605 },
606 }
607 ]
608 }
609 }
610 }
611
612 step("Trying to set bgp communities")
613 result = create_route_maps(tgen, input_dict)
614 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
615
616 write_test_footer(tc_name)
617
618
619 def test_large_community_advertise(request):
620 """
621 Verify that the community attribute value, which we have advertised are
622 received in correct format and values, at the receiving end.
623 """
624 tc_name = request.node.name
625 write_test_header(tc_name)
626 tgen = get_topogen()
627
628 # Don"t run this test if we have any failure.
629 if tgen.routers_have_failure():
630 pytest.skip(tgen.errors)
631
632 reset_config_on_routers(tgen)
633 config_router_r1(tgen, topo, tc_name)
634
635 input_dict = {
636 "largeCommunity": LARGE_COMM["r1"],
637 "community": STANDARD_COMM["r1"],
638 }
639
640 for adt in ADDR_TYPES:
641 result = verify_bgp_community(tgen, adt, "r2", [NETWORK[adt][0]], input_dict)
642 assert result is True, "Test case {} : Failed \n Error: {}".format(
643 tc_name, result
644 )
645
646 result = verify_bgp_community(tgen, adt, "r3", [NETWORK[adt][0]], input_dict)
647 assert result is True, "Test case {} : Failed \n Error: {}".format(
648 tc_name, result
649 )
650
651 write_test_footer(tc_name)
652
653
654 def test_large_community_transitive(request):
655 """
656 Verify BGP Large Community attribute"s transitive property attribute.
657 """
658 tc_name = request.node.name
659 write_test_header(tc_name)
660 tgen = get_topogen()
661
662 # Don"t run this test if we have any failure.
663 if tgen.routers_have_failure():
664 pytest.skip(tgen.errors)
665
666 reset_config_on_routers(tgen)
667
668 config_router_r1(tgen, topo, tc_name)
669
670 input_dict_1 = {
671 "largeCommunity": LARGE_COMM["r1"],
672 "community": STANDARD_COMM["r1"],
673 }
674
675 for adt in ADDR_TYPES:
676 result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][0]], input_dict_1)
677 assert result is True, "Test case {} : Failed \n Error: {}".format(
678 tc_name, result
679 )
680
681 write_test_footer(tc_name)
682
683
684 def test_large_community_override(request):
685 """
686 Verify if overriding large community values works fine.
687 """
688 tc_name = request.node.name
689 write_test_header(tc_name)
690 tgen = get_topogen()
691
692 # Don"t run this test if we have any failure.
693 if tgen.routers_have_failure():
694 pytest.skip(tgen.errors)
695
696 reset_config_on_routers(tgen)
697 config_router_r1(tgen, topo, tc_name)
698
699 config_router_r2(tgen, topo, tc_name)
700
701 input_dict_3 = {
702 "largeCommunity": LARGE_COMM["r2"],
703 "community": STANDARD_COMM["r2"],
704 }
705
706 for adt in ADDR_TYPES:
707 result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][1]], input_dict_3)
708 assert result is True, "Test case {} : Failed \n Error: {}".format(
709 tc_name, result
710 )
711
712 write_test_footer(tc_name)
713
714
715 def test_large_community_additive(request):
716 """
717 Verify that large community values" aggregation works fine.
718 """
719 tc_name = request.node.name
720 write_test_header(tc_name)
721 tgen = get_topogen()
722
723 # Don"t run this test if we have any failure.
724 if tgen.routers_have_failure():
725 pytest.skip(tgen.errors)
726
727 reset_config_on_routers(tgen)
728 config_router_r1(tgen, topo, tc_name)
729
730 config_router_r2(tgen, topo, tc_name)
731
732 config_router_additive(tgen, topo, tc_name)
733
734 input_dict_1 = {
735 "largeCommunity": "%s %s" % (LARGE_COMM["r1"], LARGE_COMM["r2"]),
736 "community": "%s %s" % (STANDARD_COMM["r1"], STANDARD_COMM["r2"]),
737 }
738
739 for adt in ADDR_TYPES:
740 result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][0]], input_dict_1)
741 assert result is True, "Test case {} : Failed \n Error: {}".format(
742 tc_name, result
743 )
744
745 write_test_footer(tc_name)
746
747
748 def test_large_community_match_as_path(request):
749 """
750 Matching prefixes based on attributes other than prefix list and make use
751 of set clause.
752 """
753
754 tc_name = request.node.name
755 write_test_header(tc_name)
756 tgen = get_topogen()
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 reset_config_on_routers(tgen)
763 config_for_as_path(tgen, topo, tc_name)
764
765 input_dict = {
766 "largeCommunity": "%s %s" % (LARGE_COMM["pf_list_1"], LARGE_COMM["r2"]),
767 "community": "%s %s" % (STANDARD_COMM["pf_list_1"], STANDARD_COMM["r2"]),
768 }
769
770 input_dict_1 = {
771 "largeCommunity": "%s %s" % (LARGE_COMM["pf_list_2"], LARGE_COMM["r2"]),
772 "community": "%s %s" % (STANDARD_COMM["pf_list_2"], STANDARD_COMM["r2"]),
773 }
774
775 for adt in ADDR_TYPES:
776 result = verify_bgp_community(tgen, adt, "r5", [NETWORK[adt][0]], input_dict)
777 assert result is True, "Test case {} : Failed \n Error: {}".format(
778 tc_name, result
779 )
780
781 result = verify_bgp_community(
782 tgen, adt, "r5", [NETWORK[adt][1]], input_dict_1, expected=False
783 )
784
785 assert result is not True, "Test case {} : Should fail \n Error: {}".format(
786 tc_name, result
787 )
788
789 write_test_footer(tc_name)
790
791
792 def test_large_community_match_all(request):
793 """
794 Verify community and large-community list operations in route-map with all
795 clause (exact, all, any, regex) works.
796 """
797 tc_name = request.node.name
798 write_test_header(tc_name)
799 tgen = get_topogen()
800
801 # Don"t run this test if we have any failure.
802 if tgen.routers_have_failure():
803 pytest.skip(tgen.errors)
804
805 reset_config_on_routers(tgen)
806 config_router_r1(tgen, topo, tc_name)
807
808 config_router_r2(tgen, topo, tc_name)
809
810 config_router_additive(tgen, topo, tc_name)
811
812 input_dict_1 = {
813 "r4": {
814 "bgp_community_lists": [
815 {
816 "community_type": "standard",
817 "action": "permit",
818 "name": "ANY",
819 "value": "1:1:1",
820 "large": True,
821 },
822 {
823 "community_type": "standard",
824 "action": "permit",
825 "name": "ALL",
826 "value": "1:1:1 1:2:1 1:3:1 1:4:1 1:5:1 2:1:1 2:2:1",
827 "large": True,
828 },
829 {
830 "community_type": "expanded",
831 "action": "permit",
832 "name": "EXP_ALL",
833 "value": "1:1:1 1:2:1 1:3:1 1:4:1 1:5:1 2:[1-5]:1",
834 "large": True,
835 },
836 ]
837 }
838 }
839
840 step("Create bgp community lists for ANY, EXACT and EXP_ALL match")
841
842 result = create_bgp_community_lists(tgen, input_dict_1)
843 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
844
845 input_dict_2 = {
846 "r4": {
847 "route_maps": {
848 "LC4": [
849 {
850 "action": "permit",
851 "seq_id": "10",
852 "match": {"large-community-list": {"id": "ANY"}},
853 },
854 {
855 "action": "permit",
856 "seq_id": "20",
857 "match": {"large-community-list": {"id": "EXACT"}},
858 },
859 {
860 "action": "permit",
861 "seq_id": "30",
862 "match": {"large-community-list": {"id": "EXP_ALL"}},
863 },
864 ]
865 }
866 }
867 }
868
869 step("Applying bgp community lits on LC4 route-map")
870 result = create_route_maps(tgen, input_dict_2)
871 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
872
873 input_dict_3 = {
874 "r4": {
875 "bgp": {
876 "address_family": {
877 "ipv4": {
878 "unicast": {
879 "neighbor": {
880 "r5": {
881 "dest_link": {
882 "r4-link1": {
883 "route_maps": [
884 {"name": "LC4", "direction": "in"}
885 ]
886 }
887 }
888 }
889 }
890 }
891 },
892 "ipv6": {
893 "unicast": {
894 "neighbor": {
895 "r5": {
896 "dest_link": {
897 "r4-link1": {
898 "route_maps": [
899 {"name": "LC4", "direction": "in"}
900 ]
901 }
902 }
903 }
904 }
905 }
906 },
907 }
908 }
909 }
910 }
911
912 step("Apply route-mpa LC4 on r4 for r2 neighbor, direction 'in'")
913
914 result = create_router_bgp(tgen, topo, input_dict_3)
915 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
916
917 input_dict_4 = {
918 "largeCommunity": "1:1:1 1:2:1 1:3:1 1:4:1 1:5:1 2:1:1 2:2:1 2:3:1 "
919 "2:4:1 2:5:1"
920 }
921
922 for adt in ADDR_TYPES:
923 result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][0]], input_dict_4)
924 assert result is True, "Test case {} : Should fail \n Error: {}".format(
925 tc_name, result
926 )
927
928 write_test_footer(tc_name)
929
930
931 # @pytest.mark.skip(reason="as-set not working for ipv6")
932 def test_large_community_aggregate_network(request):
933 """
934 Restart router and check if large community and community
935 attributes are getting re-populated.
936 """
937
938 tc_name = request.node.name
939 write_test_header(tc_name)
940
941 tgen = get_topogen()
942
943 # Don"t run this test if we have any failure.
944 if tgen.routers_have_failure():
945 pytest.skip(tgen.errors)
946
947 reset_config_on_routers(tgen)
948
949 config_for_as_path(tgen, topo, tc_name)
950
951 input_dict = {
952 "community": STANDARD_COMM["agg_1"],
953 "largeCommunity": LARGE_COMM["agg_1"],
954 }
955
956 input_dict_1 = {
957 "r2": {
958 "bgp": {
959 "address_family": {
960 "ipv4": {
961 "unicast": {
962 "aggregate_address": [
963 {
964 "network": "%s/%s"
965 % (NETWORK["ipv4"][2], NET_MASK["ipv4"]),
966 "as_set": True,
967 }
968 ]
969 }
970 },
971 "ipv6": {
972 "unicast": {
973 "aggregate_address": [
974 {
975 "network": "%s/%s"
976 % (NETWORK["ipv6"][2], NET_MASK["ipv6"]),
977 "as_set": True,
978 }
979 ]
980 }
981 },
982 }
983 }
984 }
985 }
986
987 step("Configuring aggregate address as-set on r2")
988 result = create_router_bgp(tgen, topo, input_dict_1)
989 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
990
991 for adt in ADDR_TYPES:
992 result = verify_bgp_community(
993 tgen, adt, "r4", ["%s/%s" % (NETWORK[adt][2], NET_MASK[adt])], input_dict
994 )
995 assert result is True, "Test case {} : Failed \n Error: {}".format(
996 tc_name, result
997 )
998
999 input_dict_2 = {
1000 "r1": {
1001 "bgp": {
1002 "address_family": {
1003 "ipv4": {
1004 "unicast": {
1005 "advertise_networks": [
1006 {
1007 "network": "%s/%s"
1008 % (NETWORK["ipv4"][0], MASK["ipv4"]),
1009 "no_of_network": 1,
1010 "delete": True,
1011 }
1012 ]
1013 }
1014 },
1015 "ipv6": {
1016 "unicast": {
1017 "advertise_networks": [
1018 {
1019 "network": "%s/%s"
1020 % (NETWORK["ipv6"][0], MASK["ipv6"]),
1021 "no_of_network": 1,
1022 "delete": True,
1023 }
1024 ]
1025 }
1026 },
1027 }
1028 }
1029 }
1030 }
1031
1032 step("Stop advertising one of the networks")
1033 result = create_router_bgp(tgen, topo, input_dict_2)
1034 assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
1035
1036 input_dict_3 = {
1037 "community": STANDARD_COMM["agg_2"],
1038 "largeCommunity": LARGE_COMM["agg_2"],
1039 }
1040
1041 for adt in ADDR_TYPES:
1042 step("Verifying bgp community values on r5 is also modified")
1043 result = verify_bgp_community(
1044 tgen, adt, "r4", ["%s/%s" % (NETWORK[adt][2], NET_MASK[adt])], input_dict_3
1045 )
1046 assert result is True, "Test case {} : Failed \n Error: {}".format(
1047 tc_name, result
1048 )
1049
1050 write_test_footer(tc_name)
1051
1052
1053 def test_large_community_boundary_values(request):
1054 """
1055 Verify that any value in BGP Large communities for boundary values.
1056 """
1057 tc_name = request.node.name
1058 write_test_header(tc_name)
1059 tgen = get_topogen()
1060
1061 # Don"t run this test if we have any failure.
1062 if tgen.routers_have_failure():
1063 pytest.skip(tgen.errors)
1064
1065 input_dict = {
1066 "r4": {
1067 "bgp_community_lists": [
1068 {
1069 "community_type": "standard",
1070 "action": "permit",
1071 "name": "ANY",
1072 "value": "0:-1",
1073 }
1074 ]
1075 }
1076 }
1077
1078 step("Checking boundary value for community 0:-1")
1079 result = create_bgp_community_lists(tgen, input_dict)
1080 assert result is not True, "Test case {} : Failed \n Error: {}".format(
1081 tc_name, result
1082 )
1083
1084 step("Checking community attribute 0:65536")
1085 input_dict_2 = {
1086 "r4": {
1087 "bgp_community_lists": [
1088 {
1089 "community_type": "standard",
1090 "action": "permit",
1091 "name": "ANY",
1092 "value": "0:65536",
1093 }
1094 ]
1095 }
1096 }
1097
1098 step("Checking boundary value for community 0:65536")
1099 result = create_bgp_community_lists(tgen, input_dict_2)
1100 assert result is not True, "Test case {} : Failed \n Error: {}".format(
1101 tc_name, result
1102 )
1103
1104 step("Checking boundary value for community 0:4294967296")
1105 input_dict_3 = {
1106 "r4": {
1107 "bgp_community_lists": [
1108 {
1109 "community_type": "standard",
1110 "action": "permit",
1111 "name": "ANY",
1112 "value": "0:4294967296",
1113 "large": True,
1114 }
1115 ]
1116 }
1117 }
1118
1119 result = create_bgp_community_lists(tgen, input_dict_3)
1120 assert result is not True, "Test case {} : Failed \n Error: {}".format(
1121 tc_name, result
1122 )
1123 step("Checking boundary value for community 0:-1:1")
1124
1125 input_dict_4 = {
1126 "r4": {
1127 "bgp_community_lists": [
1128 {
1129 "community_type": "standard",
1130 "action": "permit",
1131 "name": "ANY",
1132 "value": "0:-1:1",
1133 "large": True,
1134 }
1135 ]
1136 }
1137 }
1138
1139 result = create_bgp_community_lists(tgen, input_dict_4)
1140 assert result is not True, "Test case {} : Failed \n Error: {}".format(
1141 tc_name, result
1142 )
1143
1144
1145 def test_large_community_invalid_chars(request):
1146 """
1147 BGP canonical lcommunities must only be digits
1148 """
1149 tc_name = request.node.name
1150 write_test_header(tc_name)
1151 tgen = get_topogen()
1152
1153 # Don"t run this test if we have any failure.
1154 if tgen.routers_have_failure():
1155 pytest.skip(tgen.errors)
1156
1157 input_dict = {
1158 "r4": {
1159 "bgp_community_lists": [
1160 {
1161 "community_type": "standard",
1162 "action": "permit",
1163 "name": "ANY",
1164 "value": "1:a:2",
1165 "large": True,
1166 }
1167 ]
1168 }
1169 }
1170
1171 step("Checking boundary value for community 1:a:2")
1172 result = create_bgp_community_lists(tgen, input_dict)
1173 assert result is not True, "Test case {} : Failed \n Error: {}".format(
1174 tc_name, result
1175 )
1176
1177
1178 def test_large_community_after_clear_bgp(request):
1179 """
1180 Clear BGP neighbor-ship and check if large community and community
1181 attributes are getting re-populated.
1182 """
1183 tc_name = request.node.name
1184 write_test_header(tc_name)
1185 tgen = get_topogen()
1186
1187 # Don"t run this test if we have any failure.
1188 if tgen.routers_have_failure():
1189 pytest.skip(tgen.errors)
1190
1191 reset_config_on_routers(tgen)
1192 config_router_r1(tgen, topo, tc_name)
1193
1194 input_dict = {"largeCommunity": LARGE_COMM["r1"], "community": STANDARD_COMM["r1"]}
1195
1196 for adt in ADDR_TYPES:
1197 result = verify_bgp_community(tgen, adt, "r2", [NETWORK[adt][0]], input_dict)
1198 assert result is True, "Test case {} : Failed \n Error: {}".format(
1199 tc_name, result
1200 )
1201
1202 step("Clearing BGP on r1")
1203 clear_bgp_and_verify(tgen, topo, "r1")
1204
1205 for adt in ADDR_TYPES:
1206 result = verify_bgp_community(tgen, adt, "r2", [NETWORK[adt][0]], input_dict)
1207 assert result is True, "Test case {} : Failed \n Error: {}".format(
1208 tc_name, result
1209 )
1210
1211 write_test_footer(tc_name)
1212
1213
1214 if __name__ == "__main__":
1215 args = ["-s"] + sys.argv[1:]
1216 sys.exit(pytest.main(args))