summaryrefslogtreecommitdiffstats
path: root/tests/topotests/bgp_large_community
diff options
context:
space:
mode:
Diffstat (limited to 'tests/topotests/bgp_large_community')
-rw-r--r--tests/topotests/bgp_large_community/__init__.py0
-rw-r--r--tests/topotests/bgp_large_community/bgp_large_community_topo_1.json262
-rw-r--r--tests/topotests/bgp_large_community/bgp_large_community_topo_2.json344
-rw-r--r--tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py1229
-rw-r--r--tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py2233
5 files changed, 4068 insertions, 0 deletions
diff --git a/tests/topotests/bgp_large_community/__init__.py b/tests/topotests/bgp_large_community/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/topotests/bgp_large_community/__init__.py
diff --git a/tests/topotests/bgp_large_community/bgp_large_community_topo_1.json b/tests/topotests/bgp_large_community/bgp_large_community_topo_1.json
new file mode 100644
index 0000000..902c01b
--- /dev/null
+++ b/tests/topotests/bgp_large_community/bgp_large_community_topo_1.json
@@ -0,0 +1,262 @@
+{
+ "ipv4base": "192.168.1.0",
+ "ipv4mask": 24,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {
+ "ipv4": "192.168.1.0",
+ "v4mask": 24,
+ "ipv6": "fd00::",
+ "v6mask": 64
+ },
+ "lo_prefix": {
+ "ipv4": "1.0.",
+ "v4mask": 32,
+ "ipv6": "2001:DB8:F::",
+ "v6mask": 128
+ },
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r3-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1-link1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1-link1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r2": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r4-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "1000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r2-link1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r2-link1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r3": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3-link1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3-link1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r4": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r5-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "4000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4-link1": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r4-link1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4-link1": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r4-link1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r5": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r4-link1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "6000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r5-link1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r5-link1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_large_community/bgp_large_community_topo_2.json b/tests/topotests/bgp_large_community/bgp_large_community_topo_2.json
new file mode 100644
index 0000000..36dee39
--- /dev/null
+++ b/tests/topotests/bgp_large_community/bgp_large_community_topo_2.json
@@ -0,0 +1,344 @@
+{
+ "ipv4base": "10.0.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {
+ "ipv4": "10.0.0.0",
+ "v4mask": 30,
+ "ipv6": "fd00::",
+ "v6mask": 64
+ },
+ "lo_prefix": {
+ "ipv4": "1.0.",
+ "v4mask": 32,
+ "ipv6": "2001:db8:f::",
+ "v6mask": 128
+ },
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "1000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r2": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r4": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "1000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r3": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r5": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r4": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r6": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "4000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {}
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {}
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r5": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r6": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "5000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r5": {}
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r5": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r5": {}
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r5": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r6": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r4": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r5": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "6000000",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r6": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r6": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r6": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r6": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
new file mode 100644
index 0000000..03cfded
--- /dev/null
+++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
@@ -0,0 +1,1229 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2019 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+
+"""
+Following tests are covered to test large-community/community functionality:
+1. Verify if large community attribute can be configured only in correct
+ canonical format.
+2. Verify that the community attribute value, which we have advertised are
+ received in correct format and values, at the receiving end.
+3. Verify BGP Large Community attribute"s transitive property attribute.
+4. Verify that BGP Large Communities attribute are malformed, if the length of
+ the BGP Large Communities Attribute value, expressed in octets,
+ is not a non-zero multiple of 12.
+5. Verify if overriding large community values works fine.
+6. Verify that large community values" aggregation works fine.
+7. Standard community also work fine in conjunction with large-community.
+8. Matching prefixes based on attributes other than prefix list and make use
+ of set clause (IPV6).
+9. Matching prefixes based on attributes other than prefix list and make use
+ of set clause (IPV4).
+10. Verify community and large-community list operations in route-map with all
+ clause (exact, all, any, regex) works.
+11. Verify that any value in BGP Large communities for boundary values.
+12. Clear BGP neighbor-ship and check if large community and community
+ attributes are getting re-populated.
+
+"""
+
+import pytest
+import time
+from os import path as os_path
+import sys
+
+# Required to instantiate the topology builder class.
+from lib.topogen import Topogen, get_topogen
+
+from lib.common_config import (
+ start_topology,
+ write_test_header,
+ write_test_footer,
+ reset_config_on_routers,
+ create_route_maps,
+ create_bgp_community_lists,
+ create_prefix_lists,
+ verify_bgp_community,
+ step,
+ check_address_types,
+ required_linux_kernel_version,
+)
+from lib.topolog import logger
+from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
+from lib.topojson import build_config_from_json
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Save the Current Working Directory to find configuration files.
+CWD = os_path.dirname(os_path.realpath(__file__))
+sys.path.append(os_path.join(CWD, "../"))
+sys.path.append(os_path.join(CWD, "../lib/"))
+
+
+# Global variables
+bgp_convergence = False
+NETWORK = {
+ "ipv4": ["200.50.2.0", "200.50.2.1", "200.50.2.0"],
+ "ipv6": ["1::1", "1::2", "1::0"],
+}
+MASK = {"ipv4": "32", "ipv6": "128"}
+NET_MASK = {"ipv4": "24", "ipv6": "120"}
+IPV4_NET = ["200.50.2.0"]
+IPV6_NET = ["1::0"]
+CONFIG_ROUTER_R1 = False
+CONFIG_ROUTER_R2 = False
+CONFIG_ROUTER_ADDITIVE = False
+ADDR_TYPES = []
+LARGE_COMM = {
+ "r1": "1:1:1 1:2:1 1:3:1 1:4:1 1:5:1",
+ "r2": "2:1:1 2:2:1 2:3:1 2:4:1 2:5:1",
+ "mal_1": "1:1 1:2 1:3 1:4 1:5",
+ "pf_list_1": "0:0:1 0:0:10 0:0:100",
+ "pf_list_2": "0:0:2 0:0:20 0:0:200",
+ "agg_1": "0:0:1 0:0:2 0:0:10 0:0:20 0:0:100 0:0:200 2:1:1 "
+ "2:2:1 2:3:1 2:4:1 2:5:1",
+ "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",
+}
+STANDARD_COMM = {
+ "r1": "1:1 1:2 1:3 1:4 1:5",
+ "r2": "2:1 2:2 2:3 2:4 2:5",
+ "mal_1": "1 2 3 4 5",
+ "pf_list_1": "0:1 0:10 0:100",
+ "pf_list_2": "0:2 0:20 0:200",
+ "agg_1": "0:1 0:2 0:10 0:20 0:100 0:200 2:1 2:2 2:3 2:4 2:5",
+ "agg_2": "0:2 0:20 0:200 2:1 2:2 2:3 2:4 2:5",
+}
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("4.15")
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
+ global ADDR_TYPES
+ testsuite_run_time = time.asctime(time.localtime(time.time()))
+ logger.info("Testsuite start time: {}".format(testsuite_run_time))
+ logger.info("=" * 40)
+
+ logger.info("Running setup_module to create topology")
+
+ # This function initiates the topology build with Topogen...
+ json_file = "{}/bgp_large_community_topo_1.json".format(CWD)
+ tgen = Topogen(json_file, mod.__name__)
+ global topo
+ topo = tgen.json_topo
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start daemons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Checking BGP convergence
+ global bgp_convergence
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ ##tgen.mininet_cli()
+ # Api call verify whether BGP is converged
+ bgp_convergence = verify_bgp_convergence(tgen, topo)
+ assert bgp_convergence is True, "setup_module :Failed \n Error:" " {}".format(
+ bgp_convergence
+ )
+
+ ADDR_TYPES = check_address_types()
+ logger.info("Running setup_module() done")
+
+
+def teardown_module():
+ """
+ Teardown the pytest environment
+
+ * `mod`: module name
+ """
+
+ logger.info("Running teardown_module to delete topology")
+
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ tgen.stop_topology()
+
+ logger.info(
+ "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+ )
+ logger.info("=" * 40)
+
+
+def config_router_r1(tgen, topo, tc_name):
+ global CONFIG_ROUTER_R1
+
+ input_dict_1 = {
+ "r1": {
+ "route_maps": {
+ "LC1": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {"num": LARGE_COMM["r1"]},
+ "community": {"num": STANDARD_COMM["r1"]},
+ },
+ }
+ ]
+ }
+ }
+ }
+
+ step("Configuring LC1 on r1")
+ result = create_route_maps(tgen, input_dict_1)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": "%s/%s"
+ % (NETWORK["ipv4"][0], MASK["ipv4"]),
+ "no_of_network": 4,
+ }
+ ],
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [
+ {"name": "LC1", "direction": "out"}
+ ]
+ }
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [
+ {"name": "LC1", "direction": "out"}
+ ]
+ }
+ }
+ },
+ },
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": "%s/%s"
+ % (NETWORK["ipv6"][0], MASK["ipv6"]),
+ "no_of_network": 4,
+ }
+ ],
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [
+ {"name": "LC1", "direction": "out"}
+ ]
+ }
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [
+ {"name": "LC1", "direction": "out"}
+ ]
+ }
+ }
+ },
+ },
+ }
+ },
+ }
+ }
+ }
+ }
+
+ step("Applying LC1 on r1 neighbors and advertising networks")
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ CONFIG_ROUTER_R1 = True
+
+
+def config_router_r2(tgen, topo, tc_name):
+ global CONFIG_ROUTER_R2
+
+ input_dict = {
+ "r2": {
+ "route_maps": {
+ "LC2": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {"num": LARGE_COMM["r2"]},
+ "community": {"num": STANDARD_COMM["r2"]},
+ },
+ }
+ ]
+ }
+ }
+ }
+
+ step("Configuring route-maps LC2 on r2")
+ result = create_route_maps(tgen, input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_1 = {
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2-link1": {
+ "route_maps": [
+ {"name": "LC2", "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2-link1": {
+ "route_maps": [
+ {"name": "LC2", "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ step("Applying LC2 on r2 neighbors in out direction")
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ CONFIG_ROUTER_R2 = True
+
+
+def config_router_additive(tgen, topo, tc_name):
+ global CONFIG_ROUTER_ADDITIVE
+
+ input_dict = {
+ "r2": {
+ "route_maps": {
+ "LC2": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": LARGE_COMM["r2"],
+ "action": "additive",
+ },
+ "community": {
+ "num": STANDARD_COMM["r2"],
+ "action": "additive",
+ },
+ },
+ }
+ ]
+ }
+ }
+ }
+
+ step("Configuring LC2 with community attributes as additive")
+ result = create_route_maps(tgen, input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ # tgen.mininet_cli()
+ CONFIG_ROUTER_ADDITIVE = True
+
+
+def config_for_as_path(tgen, topo, tc_name):
+ config_router_r1(tgen, topo, tc_name)
+
+ config_router_r2(tgen, topo, tc_name)
+
+ # Create ipv6 prefix list
+ input_dict_1 = {
+ "r1": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1": [
+ {
+ "seqid": "10",
+ "network": "%s/%s" % (NETWORK["ipv4"][0], MASK["ipv4"]),
+ "action": "permit",
+ }
+ ],
+ "pf_list_2": [
+ {
+ "seqid": "10",
+ "network": "%s/%s" % (NETWORK["ipv4"][1], MASK["ipv4"]),
+ "action": "permit",
+ }
+ ],
+ },
+ "ipv6": {
+ "pf_list_3": [
+ {
+ "seqid": "10",
+ "network": "%s/%s" % (NETWORK["ipv6"][0], MASK["ipv6"]),
+ "action": "permit",
+ }
+ ],
+ "pf_list_4": [
+ {
+ "seqid": "10",
+ "network": "%s/%s" % (NETWORK["ipv6"][1], MASK["ipv6"]),
+ "action": "permit",
+ }
+ ],
+ },
+ }
+ }
+ }
+
+ step("Configuring prefix-lists on r1 to filter networks")
+ result = create_prefix_lists(tgen, input_dict_1)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_2 = {
+ "r1": {
+ "route_maps": {
+ "LC1": [
+ {
+ "action": "permit",
+ "seq_id": 10,
+ "match": {"ipv4": {"prefix_lists": "pf_list_1"}},
+ "set": {
+ "large_community": {"num": LARGE_COMM["pf_list_1"]},
+ "community": {"num": STANDARD_COMM["pf_list_1"]},
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": 20,
+ "match": {"ipv6": {"prefix_lists": "pf_list_3"}},
+ "set": {
+ "large_community": {"num": LARGE_COMM["pf_list_1"]},
+ "community": {"num": STANDARD_COMM["pf_list_1"]},
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": 30,
+ "match": {"ipv4": {"prefix_lists": "pf_list_2"}},
+ "set": {
+ "large_community": {"num": LARGE_COMM["pf_list_2"]},
+ "community": {"num": STANDARD_COMM["pf_list_2"]},
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": 40,
+ "match": {"ipv6": {"prefix_lists": "pf_list_4"}},
+ "set": {
+ "large_community": {"num": LARGE_COMM["pf_list_2"]},
+ "community": {"num": STANDARD_COMM["pf_list_2"]},
+ },
+ },
+ ]
+ }
+ }
+ }
+
+ step(
+ "Applying prefix-lists match in route-map LC1 on r1. Setting"
+ " community attritbute for filtered networks"
+ )
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ config_router_additive(tgen, topo, tc_name)
+
+ input_dict_3 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": LARGE_COMM["pf_list_1"],
+ "large": True,
+ },
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": STANDARD_COMM["pf_list_1"],
+ },
+ ]
+ }
+ }
+
+ step("Configuring bgp community lists on r4")
+ result = create_bgp_community_lists(tgen, input_dict_3)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_4 = {
+ "r4": {
+ "route_maps": {
+ "LC4": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {
+ "large_community_list": {"id": "ANY"},
+ "community_list": {"id": "ANY"},
+ },
+ "set": {"path": {"as_num": "4000000", "as_action": "prepend"}},
+ }
+ ]
+ }
+ }
+ }
+
+ step("Applying community list on route-map on r4")
+ result = create_route_maps(tgen, input_dict_4)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_5 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r5": {
+ "dest_link": {
+ "r4-link1": {
+ "route_maps": [
+ {"name": "LC4", "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r5": {
+ "dest_link": {
+ "r4-link1": {
+ "route_maps": [
+ {"name": "LC4", "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ step("Applying route-map LC4 out from r4 to r5 ")
+ result = create_router_bgp(tgen, topo, input_dict_5)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+
+#####################################################
+#
+# Test cases
+#
+#####################################################
+def test_large_community_set(request):
+ """
+ Verify if large community attribute can be configured only in correct
+ canonical format.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # API call to modify router id
+ # input_dict dictionary to be provided to configure route_map
+ input_dict = {
+ "r1": {
+ "route_maps": {
+ "LC1": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {"num": LARGE_COMM["r1"]},
+ "community": {"num": STANDARD_COMM["r1"]},
+ },
+ }
+ ]
+ }
+ }
+ }
+
+ step("Trying to set bgp communities")
+ result = create_route_maps(tgen, input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_advertise(request):
+ """
+ Verify that the community attribute value, which we have advertised are
+ received in correct format and values, at the receiving end.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+ config_router_r1(tgen, topo, tc_name)
+
+ input_dict = {
+ "largeCommunity": LARGE_COMM["r1"],
+ "community": STANDARD_COMM["r1"],
+ }
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r2", [NETWORK[adt][0]], input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_bgp_community(tgen, adt, "r3", [NETWORK[adt][0]], input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_transitive(request):
+ """
+ Verify BGP Large Community attribute"s transitive property attribute.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+
+ config_router_r1(tgen, topo, tc_name)
+
+ input_dict_1 = {
+ "largeCommunity": LARGE_COMM["r1"],
+ "community": STANDARD_COMM["r1"],
+ }
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][0]], input_dict_1)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_override(request):
+ """
+ Verify if overriding large community values works fine.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+ config_router_r1(tgen, topo, tc_name)
+
+ config_router_r2(tgen, topo, tc_name)
+
+ input_dict_3 = {
+ "largeCommunity": LARGE_COMM["r2"],
+ "community": STANDARD_COMM["r2"],
+ }
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][1]], input_dict_3)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_additive(request):
+ """
+ Verify that large community values" aggregation works fine.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+ config_router_r1(tgen, topo, tc_name)
+
+ config_router_r2(tgen, topo, tc_name)
+
+ config_router_additive(tgen, topo, tc_name)
+
+ input_dict_1 = {
+ "largeCommunity": "%s %s" % (LARGE_COMM["r1"], LARGE_COMM["r2"]),
+ "community": "%s %s" % (STANDARD_COMM["r1"], STANDARD_COMM["r2"]),
+ }
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][0]], input_dict_1)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_match_as_path(request):
+ """
+ Matching prefixes based on attributes other than prefix list and make use
+ of set clause.
+ """
+
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+ config_for_as_path(tgen, topo, tc_name)
+
+ input_dict = {
+ "largeCommunity": "%s %s" % (LARGE_COMM["pf_list_1"], LARGE_COMM["r2"]),
+ "community": "%s %s" % (STANDARD_COMM["pf_list_1"], STANDARD_COMM["r2"]),
+ }
+
+ input_dict_1 = {
+ "largeCommunity": "%s %s" % (LARGE_COMM["pf_list_2"], LARGE_COMM["r2"]),
+ "community": "%s %s" % (STANDARD_COMM["pf_list_2"], STANDARD_COMM["r2"]),
+ }
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r5", [NETWORK[adt][0]], input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_bgp_community(
+ tgen, adt, "r5", [NETWORK[adt][1]], input_dict_1, expected=False
+ )
+
+ assert result is not True, "Test case {} : Should fail \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_match_all(request):
+ """
+ Verify community and large-community list operations in route-map with all
+ clause (exact, all, any, regex) works.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+ config_router_r1(tgen, topo, tc_name)
+
+ config_router_r2(tgen, topo, tc_name)
+
+ config_router_additive(tgen, topo, tc_name)
+
+ input_dict_1 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "1:1:1",
+ "large": True,
+ },
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ALL",
+ "value": "1:1:1 1:2:1 1:3:1 1:4:1 1:5:1 2:1:1 2:2:1",
+ "large": True,
+ },
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "EXP_ALL",
+ "value": "1:1:1 1:2:1 1:3:1 1:4:1 1:5:1 2:[1-5]:1",
+ "large": True,
+ },
+ ]
+ }
+ }
+
+ step("Create bgp community lists for ANY, EXACT and EXP_ALL match")
+
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_2 = {
+ "r4": {
+ "route_maps": {
+ "LC4": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {"large-community-list": {"id": "ANY"}},
+ },
+ {
+ "action": "permit",
+ "seq_id": "20",
+ "match": {"large-community-list": {"id": "EXACT"}},
+ },
+ {
+ "action": "permit",
+ "seq_id": "30",
+ "match": {"large-community-list": {"id": "EXP_ALL"}},
+ },
+ ]
+ }
+ }
+ }
+
+ step("Applying bgp community lits on LC4 route-map")
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_3 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r5": {
+ "dest_link": {
+ "r4-link1": {
+ "route_maps": [
+ {"name": "LC4", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r5": {
+ "dest_link": {
+ "r4-link1": {
+ "route_maps": [
+ {"name": "LC4", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ step("Apply route-mpa LC4 on r4 for r2 neighbor, direction 'in'")
+
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_4 = {
+ "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 "
+ "2:4:1 2:5:1"
+ }
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r4", [NETWORK[adt][0]], input_dict_4)
+ assert result is True, "Test case {} : Should fail \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+# @pytest.mark.skip(reason="as-set not working for ipv6")
+def test_large_community_aggregate_network(request):
+ """
+ Restart router and check if large community and community
+ attributes are getting re-populated.
+ """
+
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+
+ config_for_as_path(tgen, topo, tc_name)
+
+ input_dict = {
+ "community": STANDARD_COMM["agg_1"],
+ "largeCommunity": LARGE_COMM["agg_1"],
+ }
+
+ input_dict_1 = {
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "aggregate_address": [
+ {
+ "network": "%s/%s"
+ % (NETWORK["ipv4"][2], NET_MASK["ipv4"]),
+ "as_set": True,
+ }
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "aggregate_address": [
+ {
+ "network": "%s/%s"
+ % (NETWORK["ipv6"][2], NET_MASK["ipv6"]),
+ "as_set": True,
+ }
+ ]
+ }
+ },
+ }
+ }
+ }
+ }
+
+ step("Configuring aggregate address as-set on r2")
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(
+ tgen, adt, "r4", ["%s/%s" % (NETWORK[adt][2], NET_MASK[adt])], input_dict
+ )
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": "%s/%s"
+ % (NETWORK["ipv4"][0], MASK["ipv4"]),
+ "no_of_network": 1,
+ "delete": True,
+ }
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": "%s/%s"
+ % (NETWORK["ipv6"][0], MASK["ipv6"]),
+ "no_of_network": 1,
+ "delete": True,
+ }
+ ]
+ }
+ },
+ }
+ }
+ }
+ }
+
+ step("Stop advertising one of the networks")
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_3 = {
+ "community": STANDARD_COMM["agg_2"],
+ "largeCommunity": LARGE_COMM["agg_2"],
+ }
+
+ for adt in ADDR_TYPES:
+ step("Verifying bgp community values on r5 is also modified")
+ result = verify_bgp_community(
+ tgen, adt, "r4", ["%s/%s" % (NETWORK[adt][2], NET_MASK[adt])], input_dict_3
+ )
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_boundary_values(request):
+ """
+ Verify that any value in BGP Large communities for boundary values.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ input_dict = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "0:-1",
+ }
+ ]
+ }
+ }
+
+ step("Checking boundary value for community 0:-1")
+ result = create_bgp_community_lists(tgen, input_dict)
+ assert result is not True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Checking community attribute 0:65536")
+ input_dict_2 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "0:65536",
+ }
+ ]
+ }
+ }
+
+ step("Checking boundary value for community 0:65536")
+ result = create_bgp_community_lists(tgen, input_dict_2)
+ assert result is not True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Checking boundary value for community 0:4294967296")
+ input_dict_3 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "0:4294967296",
+ "large": True,
+ }
+ ]
+ }
+ }
+
+ result = create_bgp_community_lists(tgen, input_dict_3)
+ assert result is not True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ step("Checking boundary value for community 0:-1:1")
+
+ input_dict_4 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "0:-1:1",
+ "large": True,
+ }
+ ]
+ }
+ }
+
+ result = create_bgp_community_lists(tgen, input_dict_4)
+ assert result is not True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+
+def test_large_community_invalid_chars(request):
+ """
+ BGP canonical lcommunities must only be digits
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ input_dict = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "1:a:2",
+ "large": True,
+ }
+ ]
+ }
+ }
+
+ step("Checking boundary value for community 1:a:2")
+ result = create_bgp_community_lists(tgen, input_dict)
+ assert result is not True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+
+def test_large_community_after_clear_bgp(request):
+ """
+ Clear BGP neighbor-ship and check if large community and community
+ attributes are getting re-populated.
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+ config_router_r1(tgen, topo, tc_name)
+
+ input_dict = {"largeCommunity": LARGE_COMM["r1"], "community": STANDARD_COMM["r1"]}
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r2", [NETWORK[adt][0]], input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Clearing BGP on r1")
+ clear_bgp_and_verify(tgen, topo, "r1")
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, "r2", [NETWORK[adt][0]], input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py
new file mode 100644
index 0000000..b11cda3
--- /dev/null
+++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py
@@ -0,0 +1,2233 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2019 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_bgp_large_community_topo_1.py: Test BGP large community.
+
+Following tests are covered:
+1. Verify the standard large-community-lists can permit or deny
+ large community attribute only in the correct canonical format.
+2. Verify the expanded large-community-lists can permit or deny
+ large community attribute both in the correct canonical format
+ as well as REG_EX.
+3. Verify that we can modify a large-community-list is in use,
+ to add/remove attribute value and it takes immediate effect.
+4. Verify that large community attribute gets advertised when
+ route-map is applied to a neighbor and cleared when route-map
+ is removed.
+5. Verify that duplicate BGP Large Community values are NOT be transmitted.
+6. Verify if we want to remove all the large-community attributes from a
+ set of prefix we can set the value as NONE.
+7. Redistribute connected and static routes in BGP process with a route-map
+ appending/removing L-comm attributes.
+8. Verify if we want to remove specific large-community values from
+ a set of prefix we can make use of DELETE operation based on L-comm list.
+9. Verify that if community values are NOT be advertised to a specific
+ neighbour, we negate send-community command.
+ (Send-community all is enabled by default for all neighbors)
+10. Verify that large-community lists can not be configured without providing
+ specific L-community values(for match/delete operation in a route-map).
+11. Verify that Match_EXACT clause should pass only if all of the L-comm
+ values configured (horizontally) in the community list is present in
+ the prefix. There must be no additional L-communities in the prefix.
+12. Verify that Match_ALL clause should pass only if ALL of the L-comm values
+ configured (horizontally) in the community list is present in the prefix.
+ There could be additional L-communities in the prefix that are not present
+ in the L-comm list.
+13. Verify that Match_ANY clause should pass only if at-least any one L-comm
+ value configured(vertically) in large-community list, is present in prefixes.
+14. Verify large-community lists operation in a route-map with match RegEx
+ statements.
+"""
+
+import os
+import sys
+import pytest
+import time
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+sys.path.append(os.path.join(CWD, "../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topogen import Topogen, get_topogen
+
+from lib.common_config import (
+ start_topology,
+ write_test_header,
+ write_test_footer,
+ reset_config_on_routers,
+ create_route_maps,
+ create_bgp_community_lists,
+ verify_bgp_community,
+ step,
+ verify_create_community_list,
+ delete_route_maps,
+ verify_route_maps,
+ create_static_routes,
+ check_address_types,
+ required_linux_kernel_version,
+)
+from lib.topolog import logger
+from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
+from lib.topojson import build_config_from_json
+
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+bgp_convergence = False
+
+NETWORKS = {"ipv4": ["200.50.2.0/32"], "ipv6": ["1::1/128"]}
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("4.15")
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
+ testsuite_run_time = time.asctime(time.localtime(time.time()))
+ logger.info("Testsuite start time: {}".format(testsuite_run_time))
+ logger.info("=" * 40)
+
+ logger.info("Running setup_module to create topology")
+
+ # This function initiates the topology build with Topogen...
+ json_file = "{}/bgp_large_community_topo_2.json".format(CWD)
+ tgen = Topogen(json_file, mod.__name__)
+ global topo
+ topo = tgen.json_topo
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start daemons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Checking BGP convergence
+ global bgp_convergence, ADDR_TYPES
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Api call verify whether BGP is converged
+ # Ipv4
+ bgp_convergence = verify_bgp_convergence(tgen, topo)
+ assert bgp_convergence is True, "setup_module :Failed \n Error:" " {}".format(
+ bgp_convergence
+ )
+ ADDR_TYPES = check_address_types()
+
+ logger.info("Running setup_module() done")
+
+
+def teardown_module(mod):
+ """
+ Teardown the pytest environment
+
+ * `mod`: module name
+ """
+
+ logger.info("Running teardown_module to delete topology")
+
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ tgen.stop_topology()
+
+ logger.info(
+ "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+ )
+ logger.info("=" * 40)
+
+
+#####################################################
+#
+# Testcases
+#
+#####################################################
+
+
+def test_create_bgp_standard_large_community_list(request):
+ """
+ Create standard large-community-list and verify it can permit
+ or deny large community attribute only in the correct canonical
+ format.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ reset_config_on_routers(tgen)
+
+ step("Create srtandard large community list")
+ input_dict = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "LC_1_STD",
+ "value": "2:1:1 2:1:2 1:2:3",
+ "large": True,
+ },
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "LC_2_STD",
+ "value": "3:1:1 3:1:2",
+ "large": True,
+ },
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify BGP large community is created")
+ result = verify_create_community_list(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create srtandard large community list with in-correct values")
+ input_dict = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "LC_1_STD_ERR",
+ "value": "0:0:0",
+ "large": True,
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ ## TODO should fail
+ step("Verify BGP large community is created")
+ result = verify_create_community_list(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_create_bgp_expanded_large_community_list(request):
+ """
+ Create expanded large-community-list and verify it can permit
+ or deny large community attribute both in the correct canonical
+ format as well as REG_EX
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create expanded large community list")
+ input_dict = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "LC_1_EXP",
+ "value": "1:1:200 1:2:* 3:2:1",
+ "large": True,
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify BGP large community is created")
+ result = verify_create_community_list(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_modify_large_community_lists_referenced_by_rmap(request):
+ """
+ This test is to verify that we can modify a large-community-list
+ is in use, add/remove attribute value and it takes immediate effect.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create standard large community list")
+ input_dict_1 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "LC_DEL",
+ "value": "1:2:1 1:3:1 2:1:1 2:2:2 3:3:3",
+ "large": True,
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_2 = {
+ "r1": {
+ "route_maps": {
+ "RM_R2_OUT": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": "1:2:1 1:3:1 2:10:1 3:3:3 4:4:4 5:5:5",
+ "action": "additive",
+ }
+ },
+ }
+ ]
+ }
+ },
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {"large_comm_list": {"id": "LC_DEL", "delete": True}},
+ }
+ ]
+ }
+ },
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map and advertise networks")
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}],
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [
+ {
+ "name": "RM_R2_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ },
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [{"network": "1::1/128"}],
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [
+ {
+ "name": "RM_R2_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ },
+ }
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify Community-list")
+ dut = "r4"
+ input_dict_4 = {"largeCommunity": "2:10:1 4:4:4 5:5:5"}
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_rmap_apply_and_remove(request):
+ """
+ This test is to verify that large community attribute gets advertised when
+ route-map is applied to a neighbor and cleared when route-map is removed
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_1 = {
+ "r4": {
+ "route_maps": {
+ "RM_LC1": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": "200:200:1 200:200:10 200:200:20000",
+ "action": "additive",
+ }
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map and advertise networks")
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_LC1", "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_LC1", "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r6"
+ input_dict_4 = {"largeCommunity": "200:200:1 200:200:10 200:200:20000"}
+
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Delete route map reference by community-list")
+ input_dict_3 = {"r4": {"route_maps": ["RM_LC1"]}}
+ result = delete_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify route map is deleted")
+ result = verify_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(
+ tgen, adt, dut, NETWORKS[adt], input_dict_4, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "largeCommunity is still present after deleting route-map \n Error: {}".format(
+ tc_name, result
+ )
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_duplicate_large_community_list_attributes_not_transitive(request):
+ """
+ This test is to verify that duplicate BGP Large Community values
+ are NOT be transmitted.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_1 = {
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": "0:0:1 0:0:10 0:0:100 2:0:1 2:0:2 2:0:3"
+ " 2:0:4 2:0:5",
+ "action": "additive",
+ }
+ },
+ }
+ ],
+ "RM_R4_OUT": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": "0:0:1 0:0:10 0:0:10000 2:0:1 2:0:2",
+ "action": "additive",
+ }
+ },
+ }
+ ],
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map and advertise networks")
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ },
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r6"
+ input_dict_4 = {
+ "largeCommunity": "0:0:1 0:0:10 0:0:100 0:0:10000 2:0:1 2:0:2 2:0:3 2:0:4 2:0:5"
+ }
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_rmap_set_none(request):
+ """
+ This test is to verify if we want to remove all the large-community
+ attributes from a set of prefix we can set the value as NONE.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_1 = {
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": "0:0:1 0:0:10 0:0:100 2:0:1 2:0:2 2:0:3"
+ " 2:0:4",
+ "action": "additive",
+ }
+ },
+ }
+ ]
+ }
+ },
+ "r6": {
+ "route_maps": {
+ "RM_R6_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {"large_community": {"num": "none"}},
+ }
+ ]
+ }
+ },
+ }
+ result = create_route_maps(tgen, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r6": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r6": {
+ "route_maps": [
+ {"name": "RM_R6_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r6": {
+ "route_maps": [
+ {"name": "RM_R6_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify Community-list")
+ dut = "r6"
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "Community-list is still present \n Error: {}".format(tc_name, result)
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_lcomm_lists_with_redistribute_static_connected_rmap(request):
+ """
+ This test is to verify redistribute connected and static ipv4 routes
+ in BGP process with a route-map appending/removing L-comm attributes.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("create static routes")
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {"network": "200.50.2.0/32", "next_hop": "10.0.0.6"},
+ {"network": "1::1/128", "next_hop": "fd00:0:0:1::2"},
+ ]
+ }
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("redistribute static routes")
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {
+ "redist_type": "static",
+ "attribute": "route-map RM_R2_OUT",
+ },
+ {
+ "redist_type": "connected",
+ "attribute": "route-map RM_R2_OUT",
+ },
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {
+ "redist_type": "static",
+ "attribute": "route-map RM_R2_OUT",
+ },
+ {
+ "redist_type": "connected",
+ "attribute": "route-map RM_R2_OUT",
+ },
+ ]
+ }
+ },
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "RM_R2_OUT": [
+ {
+ "action": "permit",
+ "set": {"large_community": {"num": "55:55:55 555:555:555"}},
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list for static and connected ipv4 route on" " r2")
+
+ input_dict_5 = {"largeCommunity": "55:55:55 555:555:555"}
+
+ if "ipv4" in ADDR_TYPES:
+ dut = "r2"
+ networks = ["200.50.2.0/32", "1.0.1.17/32"]
+ result = verify_bgp_community(tgen, "ipv4", dut, networks, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Verify large-community-list for static and connected ipv4 route" " on r4")
+ dut = "r4"
+ networks = ["200.50.2.0/32", "1.0.1.17/32"]
+ result = verify_bgp_community(tgen, "ipv4", dut, networks, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ if "ipv6" in ADDR_TYPES:
+ step("Verify large-community-list for static and connected ipv6 route" " on r2")
+ dut = "r2"
+ networks = ["1::1/128", "2001:db8:f::1:17/128"]
+ result = verify_bgp_community(tgen, "ipv6", dut, networks, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Verify large-community-list for static and connected ipv6 route" " on r4")
+ dut = "r4"
+ networks = ["1::1/128", "2001:db8:f::1:17/128"]
+ result = verify_bgp_community(tgen, "ipv6", dut, networks, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_rmap_set_delete(request):
+ """
+ This test is to verify if we want to remove specific large-community
+ values from a set of prefix we can make use of DELETE operation based
+ on L-comm list
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("configure route_map")
+ input_dict_2 = {
+ "r6": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "Test",
+ "value": "1:2:1 1:1:10 1:3:100",
+ "large": True,
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_3 = {
+ "r6": {
+ "route_maps": {
+ "RM_R6_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {"large_comm_list": {"id": "Test", "delete": True}},
+ }
+ ]
+ }
+ },
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": "1:2:1 1:1:10 1:3:100 2:1:1 2:2:2 2:3:3"
+ " 2:4:4 2:5:5",
+ "action": "additive",
+ }
+ },
+ }
+ ]
+ }
+ },
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map and advertise networks")
+ input_dict_4 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r6": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r6": {
+ "route_maps": [
+ {"name": "RM_R6_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r6": {
+ "route_maps": [
+ {"name": "RM_R6_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r6"
+ input_dict_5 = {"largeCommunity": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_no_send_community(request):
+ """
+ This test is to verify if we want to remove specific large-community
+ values from a set of prefix we can make use of DELETE operation based
+ on L-comm list
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_2 = {
+ "r5": {
+ "route_maps": {
+ "RM_R6_OUT": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {"num": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map and advertise networks")
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r5": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {
+ "r5": {
+ "route_maps": [
+ {
+ "name": "RM_R6_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {
+ "r5": {
+ "route_maps": [
+ {
+ "name": "RM_R6_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r6"
+ input_dict_4 = {"largeCommunity": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Configure neighbor for no-send-community")
+ input_dict_5 = {
+ "r5": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {"r5": {"no_send_community": "large"}}
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {"r5": {"no_send_community": "large"}}
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify Community-list")
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(
+ tgen, adt, dut, NETWORKS[adt], input_dict_4, expected=False
+ )
+ assert result is not True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_create_large_community_lists_with_no_attribute_values(request):
+ """
+ This test is to verify that large-community lists can not be
+ configured without providing specific L-community values
+ (for match/delete operation in a route-map).
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create standard large commumity-list")
+ input_dict_1 = {
+ "r5": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "Test1",
+ "large": True,
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ assert result is not True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_rmap_match_exact(request):
+ """
+ This test is to verify that Match_EXACT clause should pass
+ only if all of the L-comm values configured (horizontally)
+ in the community list is present in the prefix. There must
+ be no additional L-communities in the prefix.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_2 = {
+ "r2": {
+ "route_maps": {
+ "RM_R4_OUT": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {"num": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map and advertise networks")
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create standard large commumity-list")
+ input_dict_4 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "EXACT",
+ "value": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5",
+ "large": True,
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify BGP large community is created")
+ result = verify_create_community_list(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_5 = {
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {
+ "large-community-list": ["EXACT"],
+ "match_exact": True,
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_6 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r4"
+ input_dict_4 = {"largeCommunity": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_rmap_match_all(request):
+ """
+ This test is to verify that Match_ALL clause should pass
+ only if ALL of the L-comm values configured (horizontally)
+ in the community list are present in the prefix. There
+ could be additional L-communities in the prefix that are
+ not present in the L-comm list.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_2 = {
+ "r2": {
+ "route_maps": {
+ "RM_R4_OUT": [
+ {
+ "action": "permit",
+ "set": {
+ "large_community": {
+ "num": "1:1:1 1:2:3 2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"
+ }
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create standard large commumity-list")
+ input_dict_4 = {
+ "r3": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ALL",
+ "value": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5",
+ "large": True,
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify BGP large community is created")
+ result = verify_create_community_list(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_5 = {
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {"large-community-list": {"id": "ALL"}},
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_6 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r4"
+ input_dict_4 = {"largeCommunity": "1:1:1 1:2:3 2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_rmap_match_any(request):
+ """
+ This test is to verify that Match_ANY clause should pass
+ only if at-least any one L-comm value configured(vertically)
+ in large-community list, is present in prefixes.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_2 = {
+ "r2": {
+ "route_maps": {
+ "RM_R4_OUT": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {"num": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create standard large commumity-list")
+ input_dict_4 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "2:1:1",
+ "large": True,
+ },
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "2:2:1",
+ "large": True,
+ },
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "2:3:1",
+ "large": True,
+ },
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ANY",
+ "value": "2:4:1",
+ "large": True,
+ },
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify BGP large community is created")
+ result = verify_create_community_list(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_5 = {
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {"large-community-list": {"id": "ANY"}},
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_6 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r4"
+ input_dict_7 = {"largeCommunity": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"}
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_large_community_lists_with_rmap_match_regex(request):
+ """
+ This test is to verify large-community lists" operation in a route-map
+ with match RegEx statements. Match clause should pass only if the
+ complete string of L-comm values are matched
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ step("Create route map")
+ input_dict_2 = {
+ "r2": {
+ "route_maps": {
+ "RM_R4_OUT": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "set": {
+ "large_community": {
+ "num": "1:1:1 1:1:2 2:1:3 2:1:4 2:1:5",
+ },
+ "community": {"num": "1:1 1:2 1:3 1:4 1:5"},
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [{"network": "200.50.2.0/32"}]
+ }
+ },
+ "ipv6": {
+ "unicast": {"advertise_networks": [{"network": "1::1/128"}]}
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2": {
+ "route_maps": [
+ {
+ "name": "RM_R4_OUT",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create standard large commumity-list")
+ input_dict_4 = {
+ "r4": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "ALL",
+ "value": "1:1:1 2:1:3 2:1:4 2:1:5",
+ "large": True,
+ },
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "EXP_ALL",
+ "value": "1:1:1 2:1:[3-5]",
+ "large": True,
+ },
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify BGP large community is created")
+ result = verify_create_community_list(tgen, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_5 = {
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {
+ "large_community_list": {
+ "id": "ALL",
+ },
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure neighbor for route map")
+ input_dict_6 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4": {
+ "route_maps": [
+ {"name": "RM_R4_IN", "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r4"
+ input_dict_7 = {"largeCommunity": "1:1:1 1:1:2 2:1:3 2:1:4 2:1:5"}
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Delete route map reference by community-list")
+ input_dict_3 = {"r4": {"route_maps": ["RM_R4_IN"]}}
+ result = delete_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ result = verify_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create route map")
+ input_dict_5 = {
+ "r4": {
+ "route_maps": {
+ "RM_R4_IN": [
+ {
+ "action": "permit",
+ "seq_id": "20",
+ "match": {
+ "large_community_list": {
+ "id": "EXP_ALL",
+ },
+ },
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("clear ip bgp")
+ result = clear_bgp_and_verify(tgen, topo, "r4")
+ assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify large-community-list")
+ dut = "r4"
+ input_dict_7 = {"largeCommunity": "1:1:1 1:1:2 2:1:3 2:1:4 2:1:5"}
+ for adt in ADDR_TYPES:
+ result = verify_bgp_community(
+ tgen, adt, dut, NETWORKS[adt], input_dict_7, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "largeCommunity is still present \n Error: {}".format(tc_name, result)
+ )
+
+ write_test_footer(tc_name)
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))