summaryrefslogtreecommitdiff
path: root/tests/topotests/bgp_default_originate
diff options
context:
space:
mode:
authorARShreenidhi <rshreenidhi@vmware.com>2022-07-06 05:57:13 +0000
committerIqra Siddiqui <imujeebsiddi@vmware.com>2022-07-06 11:06:54 -0700
commitfbad2f3af9087b1d43531e5a2359693ad1566bc2 (patch)
tree7900ebe6fb40486ccd774d0993dc900a6cc664cf /tests/topotests/bgp_default_originate
parenta633fb579e377fb745d3d59b6158dba9dc784875 (diff)
tests : Topotest support to bgp_default_originate
When there is change in route-map policy associated with default-originate, changes does not reflect. When route-map associated with default-originate is deleted, default route doesn't get withdrawn Update message is not being sent when only route-map is removed from the default-originate config. SNT counter gets incremented on change of every policy associated with default-originate Route-map with multiple match clauses causes inconsistencies with default-originate. Default-originate behaviour on BGP-attributes Signed-off-by: ARShreenidhi <rshreenidhi@vmware.com>
Diffstat (limited to 'tests/topotests/bgp_default_originate')
-rw-r--r--tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py2102
1 files changed, 2102 insertions, 0 deletions
diff --git a/tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py b/tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py
new file mode 100644
index 0000000000..272a7fe291
--- /dev/null
+++ b/tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py
@@ -0,0 +1,2102 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2022 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.
+# Shreenidhi A R <rshreenidhi@vmware.com>
+# 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 scenerios are covered.
+1. When there is change in route-map policy associated with default-originate, changes does not reflect.
+2. When route-map associated with default-originate is deleted, default route doesn't get withdrawn
+3. Update message is not being sent when only route-map is removed from the default-originate config.
+4. SNT counter gets incremented on change of every policy associated with default-originate
+5. Route-map with multiple match clauses causes inconsistencies with default-originate.
+6. BGP-Default originate behaviour with BGP attributes
+"""
+import os
+import sys
+import time
+import pytest
+from copy import deepcopy
+from lib.topolog import logger
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topojson import build_config_from_json
+from lib.topolog import logger
+
+from lib.bgp import (
+ verify_bgp_convergence,
+ create_router_bgp,
+ get_prefix_count_route,
+ modify_as_number,
+ verify_bgp_rib,
+ get_dut_as_number,
+ verify_rib_default_route,
+ verify_fib_default_route,
+)
+from lib.common_config import (
+ verify_fib_routes,
+ step,
+ required_linux_kernel_version,
+ create_route_maps,
+ interface_status,
+ create_prefix_lists,
+ get_frr_ipv6_linklocal,
+ start_topology,
+ write_test_header,
+ verify_prefix_lists,
+ check_address_types,
+ write_test_footer,
+ reset_config_on_routers,
+ create_static_routes,
+ check_router_status,
+ delete_route_maps,
+)
+
+# 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/"))
+
+# Required to instantiate the topology builder class.
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+
+# Global variables
+topo = None
+NETWORK1_1 = {"ipv4": "198.51.1.1/32", "ipv6": "2001:DB8::1:1/128"}
+DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+NEXT_HOP_IP = {"ipv4": "Null0", "ipv6": "Null0"}
+
+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_default_originate_topo1.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)
+
+ global ADDR_TYPES
+ global BGP_CONVERGENCE
+ global DEFAULT_ROUTES
+ global DEFAULT_ROUTE_NXT_HOP_R1, DEFAULT_ROUTE_NXT_HOP_R3
+ ADDR_TYPES = check_address_types()
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
+ BGP_CONVERGENCE
+ )
+
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+
+ interface = topo["routers"]["r1"]["links"]["r2"]["interface"]
+ ipv6_link_local = get_frr_ipv6_linklocal(tgen, "r1", intf=interface)
+ ipv4_nxt_hop = topo["routers"]["r1"]["links"]["r2"]["ipv4"].split("/")[0]
+ ipv6_nxt_hop = topo["routers"]["r1"]["links"]["r2"]["ipv6"].split("/")[0]
+ DEFAULT_ROUTE_NXT_HOP_R1 = {"ipv4": ipv4_nxt_hop, "ipv6": ipv6_link_local}
+
+ interface = topo["routers"]["r3"]["links"]["r2"]["interface"]
+ ipv6_link_local = get_frr_ipv6_linklocal(tgen, "r3", intf=interface)
+ ipv4_nxt_hop = topo["routers"]["r3"]["links"]["r2"]["ipv4"].split("/")[0]
+ ipv6_nxt_hop = topo["routers"]["r3"]["links"]["r2"]["ipv6"].split("/")[0]
+ DEFAULT_ROUTE_NXT_HOP_R3 = {"ipv4": ipv4_nxt_hop, "ipv6": ipv6_link_local}
+
+ logger.info("Running setup_module() done")
+
+
+def teardown_module():
+ """Teardown the pytest environment"""
+
+ 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_default_originate_delete_conditional_routemap(request):
+ """
+ "scenerio covered":
+ 1. When there is change in route-map policy associated with default-originate, changes does not reflect.
+ 2. When route-map associated with default-originate is deleted, default route doesn't get withdrawn
+ 3. Update message is not being sent when only route-map is removed from the default-originate config.
+ 4. SNT counter gets incremented on change of every policy associated with default-originate
+ 5. Route-map with multiple match clauses causes inconsistencies with default-originate.
+ """
+ tgen = get_topogen()
+ global BGP_CONVERGENCE
+ global topo
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+ reset_config_on_routers(tgen)
+
+ if BGP_CONVERGENCE != True:
+ pytest.skip("skipped because of BGP Convergence failure")
+
+ step("Configure IPv4 and IPv6 , IBGP neighbor between R1 and R2")
+ step("Configure IPv4 and IPv6 , EBGP neighbor between R1 and R0")
+ input_dict = {
+ "r0": {
+ "bgp": {
+ "local_as": 999,
+ }
+ },
+ "r1": {
+ "bgp": {
+ "local_as": 1000,
+ }
+ },
+ "r2": {
+ "bgp": {
+ "local_as": 1000,
+ }
+ },
+ "r3": {
+ "bgp": {
+ "local_as": 2000,
+ }
+ },
+ "r4": {
+ "bgp": {
+ "local_as": 3000,
+ }
+ },
+ }
+ result = modify_as_number(tgen, topo, input_dict)
+ try:
+ assert result is True
+ except AssertionError:
+ logger.info("Expected behaviour: {}".format(result))
+ logger.info("BGP config is not created because of invalid ASNs")
+
+ step("After changing the BGP remote as , Verify the BGP Convergence")
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert (
+ BGP_CONVERGENCE is True
+ ), "Complete convergence is expected after changing ASN ....! ERROR :Failed \n Error: {}".format(
+ BGP_CONVERGENCE
+ )
+
+ step("Configure 1 IPv4 and 1 IPv6 Static route on R0 with next-hop as Null0")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r0": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = create_static_routes(tgen, static_routes_input)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the static route \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("verify IPv4 and IPv6 static route are configured and up on R0")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r0": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ },
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r0", static_routes_input)
+ assert (
+ result is True
+ ), "Testcase {} : routes {} not found in R0 FIB \n Error: {}".format(
+ tc_name, static_routes_input, result
+ )
+
+ step(
+ "Configure redistribute static on IPv4 and IPv6 address family on R0 for R0 to R1 neighbor "
+ )
+ redistribute_static = {
+ "r0": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, redistribute_static)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure redistribute configuration....! \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("verify IPv4 and IPv6 static route are received on R1")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r0": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ },
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r1", static_routes_input)
+ assert (
+ result is True
+ ), "Testcase {} : Failed... Routes {} expected in r1 FIB after configuring the redistribute config on R0 \n Error: {}".format(
+ tc_name, static_routes_input, result
+ )
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", static_routes_input)
+ assert (
+ result is True
+ ), "Testcase {} : Failed... Routes {} expected in r1 RIB after configuring the redistribute config on R0\n Error: {}".format(
+ tc_name, static_routes_input, result
+ )
+
+ step(
+ "Configure IPv4 prefix-list 'Pv4' and and IPv6 prefix-list 'Pv6' on R1 to match BGP route Sv41, IPv6 route Sv61 permit "
+ )
+ input_dict_3 = {
+ "r1": {
+ "prefix_lists": {
+ "ipv4": {
+ "Pv4": [
+ {
+ "seqid": "1",
+ "network": NETWORK1_1["ipv4"],
+ "action": "permit",
+ },
+ ]
+ },
+ "ipv6": {
+ "Pv6": [
+ {
+ "seqid": "1",
+ "network": NETWORK1_1["ipv6"],
+ "action": "permit",
+ },
+ ]
+ },
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_3)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the prefix list \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "Configure IPV4 and IPv6 route-map (RMv4 and RMv6) matching prefix-list (Pv4 and Pv6) respectively on R1"
+ )
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv4": {"prefix_lists": "Pv4"}},
+ "set": {
+ "path": {
+ "as_num": "5555",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv6": {"prefix_lists": "Pv6"}},
+ "set": {
+ "path": {
+ "as_num": "5555",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the route map \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "Configure default-originate with route-map (RMv4 and RMv6) on R1, on BGP IPv4 and IPv6 address family "
+ )
+ local_as = get_dut_as_number(tgen, dut="r1")
+ default_originate_config = {
+ "r1": {
+ "bgp": {
+ "local_as": local_as,
+ "address_family": {
+ "ipv4": {
+ "unicast": {"default_originate": {"r2": {"route_map": "RMv4"}}}
+ },
+ "ipv6": {
+ "unicast": {"default_originate": {"r2": {"route_map": "RMv6"}}}
+ },
+ },
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, default_originate_config)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the default originate \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "After configuring default-originate command , verify default routes are advertised on R2 "
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ metric=0,
+ expected_aspath="5555",
+ )
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the default originate \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ expected=True,
+ )
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the default originate \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Changing the as-path policy of the existing route-map")
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv4": {"prefix_lists": "Pv4"}},
+ "set": {
+ "path": {
+ "as_num": "6666",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv6": {"prefix_lists": "Pv6"}},
+ "set": {
+ "path": {
+ "as_num": "6666",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the route map \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "Verify prefix sent count on R1 towards R2 \n Send count shoud not be incremented on change of existing (AS-path) policy "
+ )
+ snapshot = get_prefix_count_route(
+ tgen, topo, dut="r1", peer="r2", link="r1", sent=True, received=False
+ )
+
+ ipv4_prefix_count = False
+ ipv6_prefix_count = False
+ if snapshot["ipv4_count"] == 2:
+ ipv4_prefix_count = True
+ if snapshot["ipv6_count"] == 2:
+ ipv6_prefix_count = True
+
+ assert (
+ ipv4_prefix_count is True
+ ), "Testcase {} : Failed Error: Expected sent Prefix is 2 but obtained {} ".format(
+ tc_name, ipv4_prefix_count
+ )
+ assert (
+ ipv6_prefix_count is True
+ ), "Testcase {} : Failed Error: Expected sent Prefix is 2 but obtained {} ".format(
+ tc_name, ipv6_prefix_count
+ )
+
+ step(
+ "After changing the as-path policy verify the new policy is advertised to router R2"
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ metric=0,
+ expected_aspath="6666",
+ )
+ assert (
+ result is True
+ ), "Testcase {} : Default route with expected attributes is not found in BGP RIB \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ expected=True,
+ )
+ assert (
+ result is True
+ ), "Testcase {} : Default route with expected attributes is not found in BGP FIB \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Remove the as-path policy from the route-map")
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv4": {"prefix_lists": "Pv4"}},
+ "set": {
+ "path": {
+ "as_num": "6666",
+ "as_action": "prepend",
+ "delete": True,
+ }
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv6": {"prefix_lists": "Pv6"}},
+ "set": {
+ "path": {
+ "as_num": "6666",
+ "as_action": "prepend",
+ "delete": True,
+ }
+ },
+ },
+ ],
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the route map \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "After removing the route policy (AS-Path) verify that as-path is removed in r2 "
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ )
+ assert result is True, "Testcase {} : Failed ... ! \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ expected=True,
+ )
+ assert result is True, "Testcase {} : Failed .... !\n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Delete the route-map ")
+
+ delete_routemap = {"r1": {"route_maps": ["RMv4", "RMv6"]}}
+ result = delete_route_maps(tgen, delete_routemap)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to delete the route-map\n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "After deleting route-map , verify the default route in FIB and RIB are removed "
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ metric=0,
+ expected=False,
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : After removing the route-map the default-route is not removed from R2 RIB\n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ expected=False,
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : After removing the route-map the default-route is not removed from R2 FIB \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Create route-map with with sequnce number 10 ")
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {"ipv4": {"prefix_lists": "Pv4"}},
+ "set": {
+ "path": {
+ "as_num": "9999",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "10",
+ "match": {"ipv6": {"prefix_lists": "Pv6"}},
+ "set": {
+ "path": {
+ "as_num": "9999",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the route map \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "After Configuring the route-map the dut is expected to receive the route policy (as-path) as 99999"
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ metric=0,
+ expected_aspath="9999",
+ )
+ assert result is True, "Testcase {} : Failed...! \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ expected=True,
+ )
+ assert result is True, "Testcase {} : Failed ...!\n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Create another route-map with seq number less than the previous i. <10 ")
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "5",
+ "match": {"ipv4": {"prefix_lists": "Pv4"}},
+ "set": {
+ "path": {
+ "as_num": "7777",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "5",
+ "match": {"ipv6": {"prefix_lists": "Pv6"}},
+ "set": {
+ "path": {
+ "as_num": "7777",
+ "as_action": "prepend",
+ }
+ },
+ },
+ ],
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert (
+ result is True
+ ), "Testcase {} : Failed to configure the route map \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "On creating new route-map the route-map with lower seq id should be considered "
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ metric=0,
+ expected_aspath="7777",
+ )
+ assert (
+ result is True
+ ), "Testcase {} : Route-map with lowest prefix is not considered \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R1,
+ expected=True,
+ )
+ assert (
+ result is True
+ ), "Testcase {} : Route-map with lowest prefix is not considered \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_verify_default_originate_after_BGP_attributes_p1(request):
+ """
+ "Verify different BGP attributes with default-originate route "
+ """
+ tgen = get_topogen()
+ global BGP_CONVERGENCE
+ global topo
+ # test case name
+ 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():
+ check_router_status(tgen)
+ reset_config_on_routers(tgen)
+
+ if BGP_CONVERGENCE != True:
+ pytest.skip("skipped because of BGP Convergence failure")
+
+ step("Configure IPv4 and IPv6 , EBGP neighbor between R3 and R2")
+ step("Configure IPv4 and IPv6 IBGP neighbor between R3 and R4")
+ r0_local_as = topo['routers']['r0']['bgp']['local_as']
+ r1_local_as = topo['routers']['r1']['bgp']['local_as']
+ r2_local_as = topo['routers']['r2']['bgp']['local_as']
+ r3_local_as = topo['routers']['r3']['bgp']['local_as']
+ r4_local_as = topo['routers']['r4']['bgp']['local_as']
+ input_dict = {
+ "r0": {
+ "bgp": {
+ "local_as": r0_local_as,
+ }
+ },
+ "r1": {
+ "bgp": {
+ "local_as": r1_local_as,
+ }
+ },
+ "r2": {
+ "bgp": {
+ "local_as": r2_local_as,
+ }
+ },
+ "r3": {
+ "bgp": {
+ "local_as": 4000,
+ }
+ },
+ "r4": {
+ "bgp": {
+ "local_as": 4000,
+ }
+ },
+ }
+ result = modify_as_number(tgen, topo, input_dict)
+
+ try:
+ assert result is True
+ except AssertionError:
+ logger.info("Expected behaviour: {}".format(result))
+ logger.info("BGP config is not created because of invalid ASNs")
+ step("After changing the BGP AS Path Verify the BGP Convergence")
+
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
+ BGP_CONVERGENCE
+ )
+
+ step(
+ "Configure one IPv4 and one IPv6, Static route on R4 with next-hop as Null0 IPv4 route Sv41, IPv6 route Sv61 "
+ )
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = create_static_routes(tgen, static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ step("Verify IPv4 and IPv6 static routes configured on R4 in FIB")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r4", static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "Configure redistribute static knob on R4 , for R4 to R3 neighbor for IPv4 and IPv6 address family "
+ )
+ redistribute_static = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, redistribute_static)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify After configuring redistribute static , verify route received in BGP table of R3"
+ )
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r3": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r3", static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_bgp_rib(tgen, addr_type, "r3", static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ NOTE = """Configure 2 IPv4 prefix-list Pv41 Pv42 and and 2 IPv6 prefix-list Pv61 Pv62 on R3 to match BGP IPv4 route Sv41, 200.1.1.1/24 , IPv6 route Sv61 and 200::1/64"""
+ step(NOTE)
+ input_dict_3 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "Pv41": [
+ {
+ "seqid": "1",
+ "network": NETWORK1_1["ipv4"],
+ "action": "permit",
+ }
+ ],
+ "Pv42": [
+ {"seqid": "1", "network": "200.1.1.1/24", "action": "permit"}
+ ],
+ },
+ "ipv6": {
+ "Pv61": [
+ {
+ "seqid": "1",
+ "network": NETWORK1_1["ipv6"],
+ "action": "permit",
+ }
+ ],
+ "Pv62": [
+ {"seqid": " 1", "network": "200::1/64", "action": "permit"}
+ ],
+ },
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("verify IPv4 and IPv6 Prefix list got configured on R3")
+ input_dict = {"r3": {"prefix_lists": ["Pv41", "Pv61", "Pv42", "Pv62"]}}
+ result = verify_prefix_lists(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Configure 2 sequence of route-map for IPv4 seq1 permit Pv41 and seq2 permit Pv42 and for IPv6 seq1 permit Pv61 , seq2 permit Pv62 on R3"
+ )
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv4": {"prefix_lists": "Pv41"}},
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "match": {"ipv4": {"prefix_lists": "Pv42"}},
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "match": {"ipv6": {"prefix_lists": "Pv61"}},
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "match": {"ipv6": {"prefix_lists": "Pv62"}},
+ },
+ ],
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Apply on route-map seq1 set as-path prepend to 200 and route-map seq2 set as-path prepend to 300 for IPv4 and IPv6 route-map "
+ )
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "path": {
+ "as_num": "200",
+ "as_action": "prepend",
+ }
+ }
+
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "path": {
+ "as_num": "300",
+ "as_action": "prepend",
+ }
+ }
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "path": {
+ "as_num": "200",
+ "as_action": "prepend",
+ }
+ }
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "path": {
+ "as_num": "300",
+ "as_action": "prepend",
+ }
+ }
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ " Configure default-originate with IPv4 and IPv6 route-map on R3 for R3-R2 IPv4 and IPv6 BGP neighbor"
+ )
+
+ local_as = get_dut_as_number(tgen, dut="r3")
+ default_originate_config = {
+ "r3": {
+ "bgp": {
+ "local_as": local_as,
+ "address_family": {
+ "ipv4": {
+ "unicast": {"default_originate": {"r2": {"route_map": "RMv4"}}}
+ },
+ "ipv6": {
+ "unicast": {"default_originate": {"r2": {"route_map": "RMv6"}}}
+ },
+ },
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, default_originate_config)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify IPv4 and IPv6 default route received on R2 with both the AS path on R2"
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ metric=0,
+ expected_aspath="4000 200",
+ )
+
+ step(
+ "Modify AS prepend path adding one more value 500 in route-map sequence 1 and 600 for route-map sequence 2 for IPv4 and IPv6 route-map"
+ )
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "path": {
+ "as_num": "500",
+ "as_action": "prepend",
+ }
+ }
+
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "path": {
+ "as_num": "600",
+ "as_action": "prepend",
+ }
+ }
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "path": {
+ "as_num": "500",
+ "as_action": "prepend",
+ }
+ }
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "path": {
+ "as_num": "600",
+ "as_action": "prepend",
+ }
+ }
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+
+ step("As path 500 added to IPv4 and IPv6 default -originate route received on R2")
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ metric=0,
+ expected_aspath="4000 500",
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step(
+ "Apply on route-map seq1 set metric value to 70 and route-map seq2 set metric 80 IPv4 and IPv6 route-map"
+ )
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "metric": 70,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "metric": 80,
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "metric": 70,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "metric": 80,
+ },
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify Configured metric value received on R2 along with as-path for IPv4 and IPv6 default routes "
+ )
+
+
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "::/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ metric=70,
+ expected_aspath="4000 500",
+ )
+
+
+ step(
+ "Modify route-map seq1 configure metric 50 and route-map seq2 configure metric 100 IPv4 and IPv6 route-map "
+ )
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "metric": 50,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "metric": 100,
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "metric": 50,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "metric": 100,
+ },
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify Configured metric value received on R2 along with as-path for IPv4 and IPv6 default routes "
+ )
+
+
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ metric=50,
+ expected_aspath="4000 500",
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step("Delete AS-prepend from IP4 and IPv6 route-map configured on R3 ")
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+
+ "set": {
+ "path": {
+ "as_num": "500",
+ "as_action": "prepend",
+ "delete": True,
+ },
+ "delete": True,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "path": {
+ "as_num": "600",
+ "as_action": "prepend",
+ "delete": True,
+ },
+ "delete": True,
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "path": {
+ "as_num": "500",
+ "as_action": "prepend",
+ "delete": True,
+ },
+ "delete": True,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "path": {
+ "as_num": "600",
+ "as_action": "prepend",
+ "delete": True,
+ },
+ "delete": True,
+ },
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify AS-prepend is deleted from default originate route and metric value only present on R2 for IPv4 and IPv6 default routes "
+ )
+
+
+
+
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ metric=50,
+ expected_aspath="4000",
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+
+ step("Delete metric value from IP4 and IPv6 route-map configured on R3 ")
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {"metric": 50, "delete": True},
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {"metric": 100, "delete": True},
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {"metric": 50, "delete": True},
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {"metric": 100, "delete": True},
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify Metric value deleted from IPv4 and IPv6 default route on R2 ,verify default routes "
+ )
+
+
+
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ metric=0,
+ expected_aspath="4000",
+ )
+
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+ step("Change IPv4 and IPv6 , EBGP to IBGP neighbor between R3 and R2")
+ step("Change IPv4 and IPv6 IBGP to EBGP neighbor between R3 and R4")
+ r0_local_as = topo['routers']['r0']['bgp']['local_as']
+ r1_local_as = topo['routers']['r1']['bgp']['local_as']
+ r2_local_as = topo['routers']['r2']['bgp']['local_as']
+ r3_local_as = topo['routers']['r3']['bgp']['local_as']
+ r4_local_as = topo['routers']['r4']['bgp']['local_as']
+ input_dict = {
+ "r0": {
+ "bgp": {
+ "local_as": r0_local_as,
+ }
+ },
+ "r1": {
+ "bgp": {
+ "local_as": r1_local_as,
+ }
+ },
+
+ "r2": {
+ "bgp": {
+ "local_as": 1111,
+ }
+ },
+ "r3": {
+ "bgp": {
+ "local_as": 1111,
+ }
+ },
+ "r4": {
+ "bgp": {
+ "local_as": 5555,
+ }
+ },
+ }
+ result = modify_as_number(tgen, topo, input_dict)
+ try:
+ assert result is True
+ except AssertionError:
+ logger.info("Expected behaviour: {}".format(result))
+ logger.info("BGP config is not created because of invalid ASNs")
+ step("After changing the BGP AS Path Verify the BGP Convergence")
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
+ BGP_CONVERGENCE
+ )
+ step(
+ "Configure one IPv4 and one IPv6, Static route on R4 with next-hop as Null0 IPv4 route Sv41, IPv6 route Sv61 "
+ )
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = create_static_routes(tgen, static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ step("Verify IPv4 and IPv6 static routes configured on R4 in FIB")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r4", static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step(
+ "Configure redistribute static knob on R4 , for R4 to R3 neighbor for IPv4 and IPv6 address family "
+ )
+ redistribute_static = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, redistribute_static)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify After configuring redistribute static , verify route received in BGP table of R3"
+ )
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r3": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r3", static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_bgp_rib(tgen, addr_type, "r3", static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ step(
+ " Configure default-originate with IPv4 and IPv6 route-map on R3 for R3-R2 IPv4 and IPv6 BGP neighbor"
+ )
+ local_as = get_dut_as_number(tgen, dut="r3")
+ default_originate_config = {
+ "r3": {
+ "bgp": {
+ "local_as": local_as,
+ "address_family": {
+ "ipv4": {
+ "unicast": {"default_originate": {"r2": {"route_map": "RMv4"}}}
+ },
+ "ipv6": {
+ "unicast": {"default_originate": {"r2": {"route_map": "RMv6"}}}
+ },
+ },
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, default_originate_config)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify IPv4 and IPv6 default route received on R2 with both the AS path on R2"
+ )
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "0::0/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ )
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step(
+ "Configure local -preference to 50 on IPv4 and IPv6 route map seq1 and 60 on seq2"
+ )
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "locPrf": 50,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "locPrf": 60,
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "locPrf": 50,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "locPrf": 60,
+ },
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify Configured metric value received on R2 along with as-path for IPv4 and IPv6 default routes "
+ )
+
+
+
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ locPrf=50,
+ )
+
+
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ step(
+ "Modify local preference value to 150 on IPv4 and IPv6 route map seq1 and 160 on seq2"
+ )
+ route_map = {
+ "r3": {
+ "route_maps": {
+ "RMv4": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "locPrf": 150,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "locPrf": 160,
+ },
+ },
+ ],
+ "RMv6": [
+ {
+ "action": "permit",
+ "seq_id": "1",
+ "set": {
+ "locPrf": 150,
+ },
+ },
+ {
+ "action": "permit",
+ "seq_id": "2",
+ "set": {
+ "locPrf": 160,
+ },
+ },
+ ],
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, route_map)
+ assert result is True, "Test case {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Verify Modified local-preference value received on R2 for IPv4 and IPv6 default routes "
+ )
+
+
+
+
+ DEFAULT_ROUTES = {"ipv4": "0.0.0.0/0", "ipv6": "::/0"}
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ locPrf=150,
+ )
+
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+ # updating the topology with the updated AS-Number to avoid conflict in con configuring the AS
+ updated_topo = topo
+ updated_topo['routers']['r0']['bgp']['local_as']=get_dut_as_number(tgen,"r0")
+ updated_topo['routers']['r1']['bgp']['local_as']=get_dut_as_number(tgen,"r1")
+ updated_topo['routers']['r2']['bgp']['local_as']=get_dut_as_number(tgen,"r2")
+ updated_topo['routers']['r3']['bgp']['local_as']=get_dut_as_number(tgen,"r3")
+ updated_topo['routers']['r4']['bgp']['local_as']=get_dut_as_number(tgen,"r4")
+
+ step("Shut IPv4/IPv6 BGP neighbor from R4 ( R4-R3) using 'neighbor x.x.x.x shut' command ")
+ local_as = get_dut_as_number(tgen, dut="r4")
+ shut_neighbor = {
+ "r4": {
+ "bgp": {
+ "local_as": local_as,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {"shutdown":True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {"shutdown":True}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, updated_topo, shut_neighbor)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ interface = topo['routers']['r3']['links']['r4']['interface']
+ input_dict = {
+ "r1": {
+ "interface_list": [interface],
+ "status": "down"
+ }
+ }
+
+ result = interface_status(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Shut down the interface failed ! \n Error: {}".format(tc_name, result)
+
+ step("After shutting the interface verify the BGP convergence")
+ result = verify_bgp_convergence(tgen,topo,expected=False)
+ assert result is not True, "Testcase {} : Failed \n After shutting Down BGP convergence should Fail and return False \n Error: {}".format(tc_name, result)
+
+ step("verify default route deleted from R2 ")
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected=False)
+ assert result is not True, "Testcase {} : Failed \n Error: After Shut down interface the default route is NOT expected but found in RIB -> {}".format( tc_name, result)
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected=False)
+ assert result is not True, "Testcase {} : Failed \n Error: After Shut down interface the default route is NOT expected but found in FIB -> {}".format( tc_name, result)
+
+
+ step("no Shut IPv4/IPv6 BGP neighbor from R4 ( R4-R3) using 'neighbor x.x.x.x shut' command ")
+ local_as = get_dut_as_number(tgen, dut="r4")
+ shut_neighbor = {
+ "r4": {
+ "bgp": {
+ "local_as": local_as,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {"shutdown":False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {"shutdown":False}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, updated_topo, shut_neighbor)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ interface = topo['routers']['r3']['links']['r4']['interface']
+ input_dict = {
+ "r1": {
+ "interface_list": [interface],
+ "status": "up"
+ }
+ }
+
+ result = interface_status(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Bring up interface failed ! \n Error: {}".format(tc_name, result)
+
+ step("After no shutting the interface verify the BGP convergence")
+ result = verify_bgp_convergence(tgen,topo,expected=True)
+ assert result is True, "Testcase {} : Failed \n After shutting Down BGP convergence should Fail and return False \n Error: {}".format(tc_name, result)
+
+ step("After no shut neighbor , verify default route relearn on R2")
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected=True)
+ assert result is True, "Testcase {} : Failed \n Error: After no Shut down interface the default route is expected but found in RIB -> {}".format( tc_name, result)
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected=True)
+ assert result is True, "Testcase {} : Failed \n Error: After Shut down interface the default route is expected but found in FIB -> {}".format( tc_name, result)
+
+
+
+ step("Remove IPv4/IPv6 static route configure on R4")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ "delete": True
+ }
+ ]
+ }
+ }
+ result = create_static_routes(tgen, static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ step("Verify IPv4 and IPv6 static routes removed on R4 in FIB")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r4", static_routes_input, expected=False)
+ assert result is not True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ result = verify_bgp_rib(tgen, addr_type, "r4", static_routes_input, expected=False)
+ assert result is not True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("After removing static route , verify default route removed on R2")
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= False)
+ assert result is not True, "Testcase {} : Failed \n Error: After removing static the default route is NOT expected but found in RIB -> {}".format( tc_name, result)
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= False)
+ assert result is not True, "Testcase {} : Failed \n Error: After removing static the default route is NOT expected but found in FIB -> {}".format( tc_name, result)
+
+
+ step("Configuring the static route back in r4")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = create_static_routes(tgen, static_routes_input)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ step("Verify IPv4 and IPv6 static routes configured on R4 in FIB")
+ for addr_type in ADDR_TYPES:
+ static_routes_input = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK1_1[addr_type]],
+ "next_hop": NEXT_HOP_IP[addr_type],
+ }
+ ]
+ }
+ }
+ result = verify_fib_routes(tgen, addr_type, "r4", static_routes_input, expected=True)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+ result = verify_bgp_rib(tgen, addr_type, "r4", static_routes_input, expected=True)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("After adding static route back , verify default route learned on R2")
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= True)
+ assert result is True, "Testcase {} : Failed \n Error: After removing static the default route is expected but found in RIB -> {}".format( tc_name, result)
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= True)
+ assert result is True, "Testcase {} : Failed \n Error: After removing static the default route is expected but found in FIB -> {}".format( tc_name, result)
+
+ step("Deactivate IPv4 and IPv6 neighbor configured from R4 ( R4-R3)")
+
+ configure_bgp_on_r1 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r4": {"deactivate": "ipv4"}}}
+ }
+ },
+
+ },"ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r4": {"deactivate": "ipv6"}}}
+ }
+ },
+
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, updated_topo, configure_bgp_on_r1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("After deactivating the BGP neighbor , verify default route removed on R2")
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= False)
+ assert result is not True, "Testcase {} : Failed \n Error: After Deactivating the BGP neighbor the default route is NOT expected but found in RIB -> {}".format( tc_name, result)
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= False)
+ assert result is not True, "Testcase {} : Failed \n Error: After Deactivating the BGP neighbor the default route is NOT expected but found in FIB -> {}".format( tc_name, result)
+
+ step("Activate IPv4 and IPv6 neighbor configured from R4 ( R4-R3)")
+
+ configure_bgp_on_r1 = {
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r4": {"activate": "ipv4"}}}
+ }
+ },
+
+ },"ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r4": {"activate": "ipv6"}}}
+ }
+ },
+
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, updated_topo, configure_bgp_on_r1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify bgp convergence.")
+ bgp_convergence = verify_bgp_convergence(tgen, updated_topo)
+ assert bgp_convergence is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, bgp_convergence
+ )
+ step("After Activating the BGP neighbor , verify default route learned on R2")
+ result = verify_rib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= True)
+ assert result is True, "Testcase {} : Failed \n Error: After Deactivating the BGP neighbor the default route is expected but found in RIB -> {}".format( tc_name, result)
+
+ result = verify_fib_default_route(
+ tgen,
+ topo,
+ dut="r2",
+ routes=DEFAULT_ROUTES,
+ expected_nexthop=DEFAULT_ROUTE_NXT_HOP_R3,
+ expected= True)
+ assert result is True, "Testcase {} : Failed \n Error: After Deactivating the BGP neighbor the default route is expected but found in FIB -> {}".format( tc_name, result)
+ write_test_footer(tc_name)
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))