summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/topotests/bgp_extended_optional_parameters_length/__init__.py0
-rw-r--r--tests/topotests/bgp_extended_optional_parameters_length/r1/bgpd.conf6
-rw-r--r--tests/topotests/bgp_extended_optional_parameters_length/r1/zebra.conf4
-rw-r--r--tests/topotests/bgp_extended_optional_parameters_length/r2/bgpd.conf8
-rw-r--r--tests/topotests/bgp_extended_optional_parameters_length/r2/zebra.conf7
-rw-r--r--tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py106
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py1542
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py404
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py (renamed from tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py)2321
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py1686
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py1515
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py1216
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py1367
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py1024
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py4358
-rw-r--r--tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py34
-rw-r--r--tests/topotests/lib/common_config.py39
-rw-r--r--tests/topotests/lib/ospf.py23
-rw-r--r--tests/topotests/lib/pim.py44
-rw-r--r--tests/topotests/ospfv3_basic_functionality/ospfv3_nssa.json86
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py162
21 files changed, 9236 insertions, 6716 deletions
diff --git a/tests/topotests/bgp_extended_optional_parameters_length/__init__.py b/tests/topotests/bgp_extended_optional_parameters_length/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_extended_optional_parameters_length/__init__.py
diff --git a/tests/topotests/bgp_extended_optional_parameters_length/r1/bgpd.conf b/tests/topotests/bgp_extended_optional_parameters_length/r1/bgpd.conf
new file mode 100644
index 0000000000..d83013ca99
--- /dev/null
+++ b/tests/topotests/bgp_extended_optional_parameters_length/r1/bgpd.conf
@@ -0,0 +1,6 @@
+!
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.2 remote-as external
+ neighbor 192.168.1.2 extended-optional-parameters
+!
diff --git a/tests/topotests/bgp_extended_optional_parameters_length/r1/zebra.conf b/tests/topotests/bgp_extended_optional_parameters_length/r1/zebra.conf
new file mode 100644
index 0000000000..b29940f46a
--- /dev/null
+++ b/tests/topotests/bgp_extended_optional_parameters_length/r1/zebra.conf
@@ -0,0 +1,4 @@
+!
+int r1-eth0
+ ip address 192.168.1.1/24
+!
diff --git a/tests/topotests/bgp_extended_optional_parameters_length/r2/bgpd.conf b/tests/topotests/bgp_extended_optional_parameters_length/r2/bgpd.conf
new file mode 100644
index 0000000000..e390d6ed8d
--- /dev/null
+++ b/tests/topotests/bgp_extended_optional_parameters_length/r2/bgpd.conf
@@ -0,0 +1,8 @@
+router bgp 65002
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.1 remote-as external
+ neighbor 192.168.1.1 extended-optional-parameters
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_extended_optional_parameters_length/r2/zebra.conf b/tests/topotests/bgp_extended_optional_parameters_length/r2/zebra.conf
new file mode 100644
index 0000000000..dc15cf756a
--- /dev/null
+++ b/tests/topotests/bgp_extended_optional_parameters_length/r2/zebra.conf
@@ -0,0 +1,7 @@
+!
+int lo
+ ip address 172.16.16.1/32
+!
+int r2-eth0
+ ip address 192.168.1.2/24
+!
diff --git a/tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py b/tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py
new file mode 100644
index 0000000000..e677dc6ff6
--- /dev/null
+++ b/tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2021 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# 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 NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF 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 if Extended Optional Parameters Length encoding format works
+if forced with a knob.
+https://datatracker.ietf.org/doc/html/rfc9072
+"""
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+pytestmark = pytest.mark.bgpd
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def setup_module(mod):
+ topodef = {"s1": ("r1", "r2")}
+ tgen = Topogen(topodef, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for i, (rname, router) in enumerate(router_list.items(), 1):
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_extended_optional_parameters_length():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r1"]
+
+ def _bgp_converge(router):
+ output = json.loads(router.vtysh_cmd("show bgp ipv4 unicast summary json"))
+ expected = {
+ "peers": {
+ "192.168.1.2": {
+ "pfxRcd": 2,
+ "pfxSnt": 2,
+ "state": "Established",
+ "peerState": "OK",
+ }
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge, router)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Can't converge with extended-optional-parameters"
+
+ def _bgp_extended_optional_parameters_length(router):
+ output = json.loads(router.vtysh_cmd("show bgp neighbor 192.168.1.2 json"))
+ expected = {"192.168.1.2": {"extendedOptionalParametersLength": True}}
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_extended_optional_parameters_length, router)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Can't see Extended Optional Parameters Length to be used"
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py
new file mode 100644
index 0000000000..290bf16fea
--- /dev/null
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py
@@ -0,0 +1,1542 @@
+#!/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 BGP Gracefull Restart functionality.
+Basic Common Test steps for all the test case below :
+- Create topology (setup module)
+ Creating 2 routers topology, r1, r2 in IBGP
+- Bring up topology
+- Verify for bgp to converge
+- Configure BGP Garceful Restart on both the routers.
+
+1. Transition from Peer-level helper to Global Restarting
+2. Transition from Peer-level helper to Global inherit helper
+3. Transition from Peer-level restarting to Global inherit helper
+4. Default GR functional mode is Helper.
+5. Verify that the restarting node sets "R" bit while sending the
+ BGP open messages after the node restart, only if GR is enabled.
+6. Verify if restarting node resets R bit in BGP open message
+ during normal BGP session flaps as well, even when GR restarting
+ mode is enabled. Here link flap happen due to interface UP/DOWN.
+7. Verify if restarting node resets R bit in BGP
+ open message during normal BGP session flaps when GR is disabled.
+8. Verify that restarting nodes set "F" bit while sending
+ the BGP open messages after it restarts, only when BGP GR is enabled.
+9. Verify that only GR helper routers keep the stale
+ route entries, not any GR disabled router.
+10. Verify that GR helper routers keeps all the routes received
+ from restarting node if both the routers are configured as
+ GR restarting node.
+11. Verify that GR helper routers delete all the routes
+ received from a node if both the routers are configured as GR
+ helper node.
+12. After BGP neighborship is established and GR capability is exchanged,
+ transition restarting router to disabled state and vice versa.
+13. After BGP neighborship is established and GR capability is exchanged,
+ transition restarting router to disabled state and vice versa.
+14. Verify that restarting nodes reset "F" bit while sending
+ the BGP open messages after it's restarts, when BGP GR is **NOT** enabled.
+15. Verify that only GR helper routers keep the stale
+ route entries, not any GR disabled router.
+16. Transition from Global Restarting to Disable and then Global
+ Disable to Restarting.
+17. Transition from Global Helper to Disable and then Global
+ Disable to Helper.
+18. Transition from Global Restart to Helper and then Global
+ Helper to Restart, Global Mode : GR Restarting
+ PerPeer Mode : GR Helper
+ GR Mode effective : GR Helper
+19. Transition from Peer-level helper to Global Restarting,
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Restarting
+ GR Mode effective : GR Restarting
+20. Transition from Peer-level restart to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Restarting
+ GR Mode effective : GR Restarting
+21. Transition from Peer-level disabled to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Disabled
+ GR Mode effective : GR Disabled
+22. Peer-level inherit from Global Restarting
+ Global Mode : GR Restart
+ PerPeer Mode : None
+ GR Mode effective : GR Restart
+23. Transition from Peer-level disbale to Global inherit helper
+ Global Mode : None
+ PerPeer Mode : GR Disable
+ GR Mode effective : GR Disable
+
+These tests have been broken up into 4 sub python scripts because
+the totality of this run was fairly significant.
+"""
+
+import os
+import sys
+import time
+import pytest
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join("../"))
+sys.path.append(os.path.join("../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topojson import build_config_from_json
+from lib.bgp import (
+ clear_bgp,
+ verify_bgp_rib,
+ verify_graceful_restart,
+ create_router_bgp,
+ verify_r_bit,
+ verify_f_bit,
+ verify_bgp_convergence,
+ verify_bgp_convergence_from_running_config,
+)
+
+from lib.common_config import (
+ write_test_header,
+ reset_config_on_routers,
+ start_topology,
+ kill_router_daemons,
+ start_router_daemons,
+ verify_rib,
+ check_address_types,
+ write_test_footer,
+ check_router_status,
+ shutdown_bringup_interface,
+ step,
+ get_frr_ipv6_linklocal,
+ required_linux_kernel_version,
+)
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+NEXT_HOP_IP = {"ipv4": "192.168.1.10", "ipv6": "fd00:0:0:1::10"}
+NEXT_HOP_IP_1 = {"ipv4": "192.168.0.1", "ipv6": "fd00::1"}
+NEXT_HOP_IP_2 = {"ipv4": "192.168.0.2", "ipv6": "fd00::2"}
+BGP_CONVERGENCE = False
+GR_RESTART_TIMER = 20
+PREFERRED_NEXT_HOP = "link_local"
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+
+ global ADDR_TYPES
+
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("4.16")
+ 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_gr_topojson_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 deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # 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
+ 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
+ )
+
+ 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)
+
+
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
+ """
+ This function groups the repetitive function calls into one function.
+ """
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][peer]["links"]["r1-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][dut]["links"]["r2-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ return True
+
+
+def next_hop_per_address_family(
+ tgen, dut, peer, addr_type, next_hop_dict, preferred_next_hop=PREFERRED_NEXT_HOP
+):
+ """
+ This function returns link_local or global next_hop per address-family
+ """
+
+ intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
+ if addr_type == "ipv6" and "link_local" in preferred_next_hop:
+ next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
+ else:
+ next_hop = next_hop_dict[addr_type]
+
+ return next_hop
+
+
+def BGP_GR_TC_50_p1(request):
+ """
+ Test Objective : Transition from Peer-level helper to Global inherit helper
+ Global Mode : None
+ PerPeer Mode : Helper
+ GR Mode effective : GR Helper
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 as GR helper node at per Peer-level for R2"
+ " and configure R2 as global restarting node."
+ )
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 advertises GR capabilities as a helper node")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Bring up BGP on R2 and remove Peer-level GR config from R1 ")
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": False}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, "r1", neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify on R2 that R1 still advertises GR capabilities as a helper node")
+
+ input_dict = {
+ "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Start BGP on R2")
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_51_p1(request):
+ """
+ Test Objective : Transition from Peer-level restarting to Global inherit helper
+ Global Mode : None
+ PerPeer Mode : GR Restart
+ GR Mode effective : GR Restart
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 as GR restarting node at per Peer-level for R2")
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+ step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, "r2", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R1")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ step(
+ "Verify that R1 keeps the stale entries in FIB & R2 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, "r2", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Bring up BGP on R1 and remove Peer-level GR config")
+
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": False}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, "r1", neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify on R2 that R1 advertises GR capabilities as a helper node")
+
+ input_dict = {
+ "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGPd on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Start BGP on R2")
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_53_p1(request):
+ """
+ Test Objective : Default GR functional mode is Helper.
+ Global Mode : None
+ PerPeer Mode : None
+ GR Mode effective : GR Helper
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R2 as global restarting node")
+
+ input_dict = {"r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}}
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step(
+ "Verify on R2 that R1 advertises GR capabilities as a helper node based on inherit"
+ )
+
+ input_dict = {
+ "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGPd on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Start BGP on R2")
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_4_p0(request):
+ """
+ Test Objective : Verify that the restarting node sets "R" bit while sending the
+ BGP open messages after the node restart, only if GR is enabled.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Helper Mode] initialized "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ protocol = "bgp"
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Phase 2] : R2 goes for reload ")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ logger.info(
+ "[Phase 3] : R2 is still down, restart time {} sec."
+ "So time verify the routes are present in BGP RIB and ZEBRA ".format(
+ GR_RESTART_TIMER
+ )
+ )
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(
+ tgen, addr_type, dut, input_topo, next_hop, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes
+ result = verify_rib(
+ tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ logger.info("[Phase 5] : R2 is about to come up now ")
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_5_1_2_p1(request):
+ """
+ Test Objective : Verify if restarting node resets R bit in BGP open message
+ during normal BGP session flaps as well, even when GR restarting mode is enabled.
+ Here link flap happen due to interface UP/DOWN.
+
+ """
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ protocol = "bgp"
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Phase 2] : Now flap the link running the BGP session ")
+ # Shutdown interface
+ intf = "r2-r1-eth0"
+ shutdown_bringup_interface(tgen, "r2", intf)
+
+ # Bring up Interface
+ shutdown_bringup_interface(tgen, "r2", intf, ifaceaction=True)
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Phase 2] : Restart BGPd on router R2. ")
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_6_1_2_p1(request):
+ """
+ Test Objective : Verify if restarting node resets R bit in BGP
+ open message during normal BGP session flaps when GR is disabled.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Phase 1] : Test Setup" "[Restart Mode]R1-----R2[Helper Mode] initialized "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ protocol = "bgp"
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Phase 1] : Changing mode" "[Disable Mode]R1-----R2[Helper Mode]")
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, "r1", neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ # Verify GR stats
+ input_dict = {
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ # here the verify_graceful_restart fro the neighbor would be
+ # "NotReceived" as the latest GR config is not yet applied.
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Phase 2] : Now flap the link running the BGP session ")
+ # Shutdown interface
+ intf = "r2-r1-eth0"
+ shutdown_bringup_interface(tgen, "r2", intf)
+
+ # Bring up Interface
+ shutdown_bringup_interface(tgen, "r2", intf, ifaceaction=True)
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_r_bit(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r2: R-bit is set to True\n Error: {}".format(
+ tc_name, result
+ )
+
+ logger.info("Restart BGPd on R2 ")
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_r_bit(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r2: R-bit is set to True\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_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
new file mode 100644
index 0000000000..0647ad5d06
--- /dev/null
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
@@ -0,0 +1,404 @@
+#!/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 BGP Gracefull Restart functionality.
+Basic Common Test steps for all the test case below :
+- Create topology (setup module)
+ Creating 2 routers topology, r1, r2 in IBGP
+- Bring up topology
+- Verify for bgp to converge
+- Configure BGP Garceful Restart on both the routers.
+
+1. Transition from Peer-level helper to Global Restarting
+2. Transition from Peer-level helper to Global inherit helper
+3. Transition from Peer-level restarting to Global inherit helper
+4. Default GR functional mode is Helper.
+5. Verify that the restarting node sets "R" bit while sending the
+ BGP open messages after the node restart, only if GR is enabled.
+6. Verify if restarting node resets R bit in BGP open message
+ during normal BGP session flaps as well, even when GR restarting
+ mode is enabled. Here link flap happen due to interface UP/DOWN.
+7. Verify if restarting node resets R bit in BGP
+ open message during normal BGP session flaps when GR is disabled.
+8. Verify that restarting nodes set "F" bit while sending
+ the BGP open messages after it restarts, only when BGP GR is enabled.
+9. Verify that only GR helper routers keep the stale
+ route entries, not any GR disabled router.
+10. Verify that GR helper routers keeps all the routes received
+ from restarting node if both the routers are configured as
+ GR restarting node.
+11. Verify that GR helper routers delete all the routes
+ received from a node if both the routers are configured as GR
+ helper node.
+12. After BGP neighborship is established and GR capability is exchanged,
+ transition restarting router to disabled state and vice versa.
+13. After BGP neighborship is established and GR capability is exchanged,
+ transition restarting router to disabled state and vice versa.
+14. Verify that restarting nodes reset "F" bit while sending
+ the BGP open messages after it's restarts, when BGP GR is **NOT** enabled.
+15. Verify that only GR helper routers keep the stale
+ route entries, not any GR disabled router.
+16. Transition from Global Restarting to Disable and then Global
+ Disable to Restarting.
+17. Transition from Global Helper to Disable and then Global
+ Disable to Helper.
+18. Transition from Global Restart to Helper and then Global
+ Helper to Restart, Global Mode : GR Restarting
+ PerPeer Mode : GR Helper
+ GR Mode effective : GR Helper
+19. Transition from Peer-level helper to Global Restarting,
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Restarting
+ GR Mode effective : GR Restarting
+20. Transition from Peer-level restart to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Restarting
+ GR Mode effective : GR Restarting
+21. Transition from Peer-level disabled to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Disabled
+ GR Mode effective : GR Disabled
+22. Peer-level inherit from Global Restarting
+ Global Mode : GR Restart
+ PerPeer Mode : None
+ GR Mode effective : GR Restart
+23. Transition from Peer-level disbale to Global inherit helper
+ Global Mode : None
+ PerPeer Mode : GR Disable
+ GR Mode effective : GR Disable
+
+These tests have been broken up into 4 sub python scripts because
+the totality of this run was fairly significant.
+"""
+
+import os
+import sys
+import time
+import pytest
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join("../"))
+sys.path.append(os.path.join("../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topojson import build_config_from_json
+from lib.bgp import (
+ clear_bgp,
+ verify_bgp_rib,
+ verify_graceful_restart,
+ create_router_bgp,
+ verify_r_bit,
+ verify_f_bit,
+ verify_bgp_convergence,
+ verify_bgp_convergence_from_running_config,
+)
+
+from lib.common_config import (
+ write_test_header,
+ reset_config_on_routers,
+ start_topology,
+ kill_router_daemons,
+ start_router_daemons,
+ verify_rib,
+ check_address_types,
+ write_test_footer,
+ check_router_status,
+ shutdown_bringup_interface,
+ step,
+ get_frr_ipv6_linklocal,
+ required_linux_kernel_version,
+)
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+NEXT_HOP_IP = {"ipv4": "192.168.1.10", "ipv6": "fd00:0:0:1::10"}
+NEXT_HOP_IP_1 = {"ipv4": "192.168.0.1", "ipv6": "fd00::1"}
+NEXT_HOP_IP_2 = {"ipv4": "192.168.0.2", "ipv6": "fd00::2"}
+BGP_CONVERGENCE = False
+GR_RESTART_TIMER = 20
+PREFERRED_NEXT_HOP = "link_local"
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+
+ global ADDR_TYPES
+
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("4.16")
+ 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_gr_topojson_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 deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # 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
+ 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
+ )
+
+ 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)
+
+
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
+ """
+ This function groups the repetitive function calls into one function.
+ """
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][peer]["links"]["r1-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][dut]["links"]["r2-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ return True
+
+
+def next_hop_per_address_family(
+ tgen, dut, peer, addr_type, next_hop_dict, preferred_next_hop=PREFERRED_NEXT_HOP
+):
+ """
+ This function returns link_local or global next_hop per address-family
+ """
+
+ intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
+ if addr_type == "ipv6" and "link_local" in preferred_next_hop:
+ next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
+ else:
+ next_hop = next_hop_dict[addr_type]
+
+ return next_hop
+
+
+def test_BGP_GR_TC_8_p1(request):
+ """
+ Test Objective : Verify that restarting nodes set "F" bit while sending
+ the BGP open messages after it restarts, only when BGP GR is enabled.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"preserve-fw-state": True},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ protocol = "bgp"
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Phase 2] : R1 goes for reload ")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Phase 3] : R1 is about to come up now ")
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r2", peer="r1")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_f_bit(tgen, topo, addr_type, input_dict, dut="r2", peer="r1")
+ assert result is True, "Testcase {} : 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_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py
index 56f6e1a3be..0c3ff6451e 100644
--- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py
@@ -85,6 +85,9 @@ Basic Common Test steps for all the test case below :
Global Mode : None
PerPeer Mode : GR Disable
GR Mode effective : GR Disable
+
+These tests have been broken up into 4 sub python scripts because
+the totality of this run was fairly significant.
"""
import os
@@ -519,1165 +522,6 @@ def BGP_GR_TC_50_p1(request):
write_test_footer(tc_name)
-def test_BGP_GR_TC_51_p1(request):
- """
- Test Objective : Transition from Peer-level restarting to Global inherit helper
- Global Mode : None
- PerPeer Mode : GR Restart
- GR Mode effective : GR Restart
-
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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 R1 as GR restarting node at per Peer-level for R2")
-
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
- step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- next_hop = next_hop_per_address_family(
- tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, "r2", input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- step("Kill BGP on R1")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- step(
- "Verify that R1 keeps the stale entries in FIB & R2 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- next_hop = next_hop_per_address_family(
- tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, "r2", input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- step("Bring up BGP on R1 and remove Peer-level GR config")
-
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": False}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": False}
- }
- }
- }
- }
- },
- }
- }
- }
- }
-
- result = create_router_bgp(tgen, topo, input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0]
- clear_bgp(tgen, addr_type, "r1", neighbor=neighbor)
-
- result = verify_bgp_convergence_from_running_config(tgen)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- step("Verify on R2 that R1 advertises GR capabilities as a helper node")
-
- input_dict = {
- "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- next_hop = next_hop_per_address_family(
- tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- step("Kill BGPd on R2")
-
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- step(
- "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- next_hop = next_hop_per_address_family(
- tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- step("Start BGP on R2")
-
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_53_p1(request):
- """
- Test Objective : Default GR functional mode is Helper.
- Global Mode : None
- PerPeer Mode : None
- GR Mode effective : GR Helper
-
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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 R2 as global restarting node")
-
- input_dict = {"r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}}
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step(
- "Verify on R2 that R1 advertises GR capabilities as a helper node based on inherit"
- )
-
- input_dict = {
- "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- next_hop = next_hop_per_address_family(
- tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- step("Kill BGPd on R2")
-
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- step(
- "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- next_hop = next_hop_per_address_family(
- tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- step("Start BGP on R2")
-
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_4_p0(request):
- """
- Test Objective : Verify that the restarting node sets "R" bit while sending the
- BGP open messages after the node restart, only if GR is enabled.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Helper Mode] initialized "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- protocol = "bgp"
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Phase 2] : R2 goes for reload ")
-
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- logger.info(
- "[Phase 3] : R2 is still down, restart time {} sec."
- "So time verify the routes are present in BGP RIB and ZEBRA ".format(
- GR_RESTART_TIMER
- )
- )
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(
- tgen, addr_type, dut, input_topo, next_hop, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes
- result = verify_rib(
- tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- logger.info("[Phase 5] : R2 is about to come up now ")
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_5_1_2_p1(request):
- """
- Test Objective : Verify if restarting node resets R bit in BGP open message
- during normal BGP session flaps as well, even when GR restarting mode is enabled.
- Here link flap happen due to interface UP/DOWN.
-
- """
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- protocol = "bgp"
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Phase 2] : Now flap the link running the BGP session ")
- # Shutdown interface
- intf = "r2-r1-eth0"
- shutdown_bringup_interface(tgen, "r2", intf)
-
- # Bring up Interface
- shutdown_bringup_interface(tgen, "r2", intf, ifaceaction=True)
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Phase 2] : Restart BGPd on router R2. ")
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_6_1_2_p1(request):
- """
- Test Objective : Verify if restarting node resets R bit in BGP
- open message during normal BGP session flaps when GR is disabled.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Phase 1] : Test Setup" "[Restart Mode]R1-----R2[Helper Mode] initialized "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- protocol = "bgp"
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Phase 1] : Changing mode" "[Disable Mode]R1-----R2[Helper Mode]")
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- }
- }
- }
- }
-
- result = create_router_bgp(tgen, topo, input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0]
- clear_bgp(tgen, addr_type, "r1", neighbor=neighbor)
-
- result = verify_bgp_convergence_from_running_config(tgen)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- # Verify GR stats
- input_dict = {
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- # here the verify_graceful_restart fro the neighbor would be
- # "NotReceived" as the latest GR config is not yet applied.
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Phase 2] : Now flap the link running the BGP session ")
- # Shutdown interface
- intf = "r2-r1-eth0"
- shutdown_bringup_interface(tgen, "r2", intf)
-
- # Bring up Interface
- shutdown_bringup_interface(tgen, "r2", intf, ifaceaction=True)
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_r_bit(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r2: R-bit is set to True\n Error: {}".format(
- tc_name, result
- )
-
- logger.info("Restart BGPd on R2 ")
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_r_bit(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r2: R-bit is set to True\n Error: {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_8_p1(request):
- """
- Test Objective : Verify that restarting nodes set "F" bit while sending
- the BGP open messages after it restarts, only when BGP GR is enabled.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {"preserve-fw-state": True},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- },
- }
- },
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- protocol = "bgp"
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Phase 2] : R1 goes for reload ")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Phase 3] : R1 is about to come up now ")
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r2", peer="r1")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_f_bit(tgen, topo, addr_type, input_dict, dut="r2", peer="r1")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
def test_BGP_GR_TC_19_p1(request):
"""
Test Objective : Verify that GR helper routers keeps all the routes received
@@ -3904,1165 +2748,6 @@ def test_BGP_GR_TC_45_p1(request):
write_test_footer(tc_name)
-def test_BGP_GR_TC_46_p1(request):
- """
- Test Objective : transition from Peer-level helper to Global Restarting
- Global Mode : GR Restarting
- PerPeer Mode : GR Helper
- GR Mode effective : GR Helper
-
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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 R1 and R2 as GR restarting node in global"
- " and helper in per-Peer-level"
- )
-
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- },
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r2"
- peer = "r1"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- step("Kill BGP on R2")
-
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- step(
- "Verify that R1 keeps the stale entries in RIB & FIB and R2 keeps stale entries in FIB using"
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r2"
- peer = "r1"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- step(
- "Bring up BGP on R1 and remove Peer-level GR config"
- " from R1 following by a session reset"
- )
-
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-helper": False}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-helper": False}
- }
- }
- }
- }
- },
- }
- }
- }
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
-
- input_dict = {
- "r1": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- step("Kill BGP on R1")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- step(
- "Verify that R1 keeps the stale entries in FIB command and R2 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_47_p1(request):
- """
- Test Objective : transition from Peer-level restart to Global Restart
- Global Mode : GR Restarting
- PerPeer Mode : GR Restarting
- GR Mode effective : GR Restarting
-
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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 R1 and R2 as GR restarting node in global and per-Peer-level")
-
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": True}
- }
- }
- }
- }
- },
- },
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- step("Kill BGP on R1")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- step(
- "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- step(
- "Bring up BGP on R1 and remove Peer-level GR"
- " config from R1 following by a session reset"
- )
-
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": False}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart": False}
- }
- }
- }
- }
- },
- }
- }
- }
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step("Verify on R2 that R1 still advertises GR capabilities as a restarting node")
-
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- }
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- step("Kill BGP on R1")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- step(
- "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_48_p1(request):
- """
- Test Objective : transition from Peer-level disabled to Global Restart
- Global Mode : GR Restarting
- PerPeer Mode : GR Disabled
- GR Mode effective : GR Disabled
-
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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 R1 as GR restarting node in global level and"
- " GR Disabled in per-Peer-level"
- )
-
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- },
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step("Verify on R2 that R1 does't advertise any GR capabilities")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- step("Kill BGP on R1")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- step("Verify on R2 and R1 that none of the routers keep stale entries")
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(
- tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(
- tgen, addr_type, dut, input_topo, next_hop, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r2: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- result = verify_rib(
- tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r2: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
-
- step("Bring up BGP on R1 and remove Peer-level GR config from R1")
-
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": False}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": False}
- }
- }
- }
- }
- },
- }
- }
- }
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
-
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- }
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
- }
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- step("Kill BGP on R1")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- step(
- "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_49_p1(request):
- """
- Test Objective : Peer-level inherit from Global Restarting
- Global Mode : GR Restart
- PerPeer Mode : None
- GR Mode effective : GR Restart
-
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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 R1 as GR restarting node in global level")
-
- input_dict = {
- "r1": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- "r2": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step(
- "Verify that R2 receives GR restarting capabilities"
- " from R1 based on inheritence"
- )
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- step("Kill BGPd on router R1")
-
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- step(
- "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r1"
- peer = "r2"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r2"
- peer = "r1"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- write_test_footer(tc_name)
-
-
-def BGP_GR_TC_52_p1(request):
- """
- Test Objective : Transition from Peer-level disbale to Global inherit helper
- Global Mode : None
- PerPeer Mode : GR Disable
- GR Mode effective : GR Disable
-
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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 R1 as GR disabled node at per Peer-level for R2"
- " & R2 as GR restarting node"
- )
-
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step("Verify on R2 that R1 does't advertise any GR capabilities")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r2"
- peer = "r1"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- step("Kill BGP on R2")
-
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- step(
- "Verify that R2 keeps the stale entries in FIB & R1 doesn't keep RIB & FIB entries."
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r2"
- peer = "r1"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(
- tgen, addr_type, dut, input_topo, next_hop, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- result = verify_rib(
- tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
-
- step("Bring up BGP on R2 and remove Peer-level GR config from R1")
-
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": False}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1-link1": {"graceful-restart-disable": False}
- }
- }
- }
- }
- },
- }
- }
- }
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- step(
- "Verify on R2 that R1 advertises GR capabilities as a helper node from global inherit"
- )
-
- input_dict = {
- "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- dut = "r2"
- peer = "r1"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- step("Kill BGP on R2")
-
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- step(
- "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
- )
-
- for addr_type in ADDR_TYPES:
- dut = "r2"
- peer = "r1"
- protocol = "bgp"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_1
- )
- input_topo = {"r1": topo["routers"]["r1"]}
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
- tc_name, result
- )
-
- dut = "r1"
- peer = "r2"
- next_hop = next_hop_per_address_family(
- tgen, dut, peer, addr_type, NEXT_HOP_IP_2
- )
- input_topo = {"r2": topo["routers"]["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
- assert (
- result is True
- ), "Testcase {} :Failed \n Routes are 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))
diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py
new file mode 100644
index 0000000000..791ca37eae
--- /dev/null
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py
@@ -0,0 +1,1686 @@
+#!/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 BGP Gracefull Restart functionality.
+Basic Common Test steps for all the test case below :
+- Create topology (setup module)
+ Creating 2 routers topology, r1, r2 in IBGP
+- Bring up topology
+- Verify for bgp to converge
+- Configure BGP Garceful Restart on both the routers.
+
+1. Transition from Peer-level helper to Global Restarting
+2. Transition from Peer-level helper to Global inherit helper
+3. Transition from Peer-level restarting to Global inherit helper
+4. Default GR functional mode is Helper.
+5. Verify that the restarting node sets "R" bit while sending the
+ BGP open messages after the node restart, only if GR is enabled.
+6. Verify if restarting node resets R bit in BGP open message
+ during normal BGP session flaps as well, even when GR restarting
+ mode is enabled. Here link flap happen due to interface UP/DOWN.
+7. Verify if restarting node resets R bit in BGP
+ open message during normal BGP session flaps when GR is disabled.
+8. Verify that restarting nodes set "F" bit while sending
+ the BGP open messages after it restarts, only when BGP GR is enabled.
+9. Verify that only GR helper routers keep the stale
+ route entries, not any GR disabled router.
+10. Verify that GR helper routers keeps all the routes received
+ from restarting node if both the routers are configured as
+ GR restarting node.
+11. Verify that GR helper routers delete all the routes
+ received from a node if both the routers are configured as GR
+ helper node.
+12. After BGP neighborship is established and GR capability is exchanged,
+ transition restarting router to disabled state and vice versa.
+13. After BGP neighborship is established and GR capability is exchanged,
+ transition restarting router to disabled state and vice versa.
+14. Verify that restarting nodes reset "F" bit while sending
+ the BGP open messages after it's restarts, when BGP GR is **NOT** enabled.
+15. Verify that only GR helper routers keep the stale
+ route entries, not any GR disabled router.
+16. Transition from Global Restarting to Disable and then Global
+ Disable to Restarting.
+17. Transition from Global Helper to Disable and then Global
+ Disable to Helper.
+18. Transition from Global Restart to Helper and then Global
+ Helper to Restart, Global Mode : GR Restarting
+ PerPeer Mode : GR Helper
+ GR Mode effective : GR Helper
+19. Transition from Peer-level helper to Global Restarting,
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Restarting
+ GR Mode effective : GR Restarting
+20. Transition from Peer-level restart to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Restarting
+ GR Mode effective : GR Restarting
+21. Transition from Peer-level disabled to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Disabled
+ GR Mode effective : GR Disabled
+22. Peer-level inherit from Global Restarting
+ Global Mode : GR Restart
+ PerPeer Mode : None
+ GR Mode effective : GR Restart
+23. Transition from Peer-level disbale to Global inherit helper
+ Global Mode : None
+ PerPeer Mode : GR Disable
+ GR Mode effective : GR Disable
+
+These tests have been broken up into 4 sub python scripts because
+the totality of this run was fairly significant.
+"""
+
+import os
+import sys
+import time
+import pytest
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join("../"))
+sys.path.append(os.path.join("../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topojson import build_config_from_json
+from lib.bgp import (
+ clear_bgp,
+ verify_bgp_rib,
+ verify_graceful_restart,
+ create_router_bgp,
+ verify_r_bit,
+ verify_f_bit,
+ verify_bgp_convergence,
+ verify_bgp_convergence_from_running_config,
+)
+
+from lib.common_config import (
+ write_test_header,
+ reset_config_on_routers,
+ start_topology,
+ kill_router_daemons,
+ start_router_daemons,
+ verify_rib,
+ check_address_types,
+ write_test_footer,
+ check_router_status,
+ shutdown_bringup_interface,
+ step,
+ get_frr_ipv6_linklocal,
+ required_linux_kernel_version,
+)
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+NEXT_HOP_IP = {"ipv4": "192.168.1.10", "ipv6": "fd00:0:0:1::10"}
+NEXT_HOP_IP_1 = {"ipv4": "192.168.0.1", "ipv6": "fd00::1"}
+NEXT_HOP_IP_2 = {"ipv4": "192.168.0.2", "ipv6": "fd00::2"}
+BGP_CONVERGENCE = False
+GR_RESTART_TIMER = 20
+PREFERRED_NEXT_HOP = "link_local"
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+
+ global ADDR_TYPES
+
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("4.16")
+ 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_gr_topojson_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 deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # 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
+ 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
+ )
+
+ 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)
+
+
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
+ """
+ This function groups the repetitive function calls into one function.
+ """
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][peer]["links"]["r1-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][dut]["links"]["r2-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ return True
+
+
+def next_hop_per_address_family(
+ tgen, dut, peer, addr_type, next_hop_dict, preferred_next_hop=PREFERRED_NEXT_HOP
+):
+ """
+ This function returns link_local or global next_hop per address-family
+ """
+
+ intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
+ if addr_type == "ipv6" and "link_local" in preferred_next_hop:
+ next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
+ else:
+ next_hop = next_hop_dict[addr_type]
+
+ return next_hop
+
+
+def BGP_GR_TC_50_p1(request):
+ """
+ Test Objective : Transition from Peer-level helper to Global inherit helper
+ Global Mode : None
+ PerPeer Mode : Helper
+ GR Mode effective : GR Helper
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 as GR helper node at per Peer-level for R2"
+ " and configure R2 as global restarting node."
+ )
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 advertises GR capabilities as a helper node")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Bring up BGP on R2 and remove Peer-level GR config from R1 ")
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": False}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, "r1", neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify on R2 that R1 still advertises GR capabilities as a helper node")
+
+ input_dict = {
+ "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ next_hop = next_hop_per_address_family(
+ tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Start BGP on R2")
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_46_p1(request):
+ """
+ Test Objective : transition from Peer-level helper to Global Restarting
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Helper
+ GR Mode effective : GR Helper
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 and R2 as GR restarting node in global"
+ " and helper in per-Peer-level"
+ )
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r2"
+ peer = "r1"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ step("Kill BGP on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R1 keeps the stale entries in RIB & FIB and R2 keeps stale entries in FIB using"
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r2"
+ peer = "r1"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ step(
+ "Bring up BGP on R1 and remove Peer-level GR config"
+ " from R1 following by a session reset"
+ )
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-helper": False}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
+
+ input_dict = {
+ "r1": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R1")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ step(
+ "Verify that R1 keeps the stale entries in FIB command and R2 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_47_p1(request):
+ """
+ Test Objective : transition from Peer-level restart to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Restarting
+ GR Mode effective : GR Restarting
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 and R2 as GR restarting node in global and per-Peer-level")
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ step("Kill BGP on R1")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ step(
+ "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ step(
+ "Bring up BGP on R1 and remove Peer-level GR"
+ " config from R1 following by a session reset"
+ )
+
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart": False}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 still advertises GR capabilities as a restarting node")
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ }
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R1")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ step(
+ "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_48_p1(request):
+ """
+ Test Objective : transition from Peer-level disabled to Global Restart
+ Global Mode : GR Restarting
+ PerPeer Mode : GR Disabled
+ GR Mode effective : GR Disabled
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 as GR restarting node in global level and"
+ " GR Disabled in per-Peer-level"
+ )
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 does't advertise any GR capabilities")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ step("Kill BGP on R1")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ step("Verify on R2 and R1 that none of the routers keep stale entries")
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(
+ tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(
+ tgen, addr_type, dut, input_topo, next_hop, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r2: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ result = verify_rib(
+ tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r2: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+
+ step("Bring up BGP on R1 and remove Peer-level GR config from R1")
+
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": False}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 advertises GR capabilities as a restarting node")
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ }
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R1")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ step(
+ "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_49_p1(request):
+ """
+ Test Objective : Peer-level inherit from Global Restarting
+ Global Mode : GR Restart
+ PerPeer Mode : None
+ GR Mode effective : GR Restart
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 as GR restarting node in global level")
+
+ input_dict = {
+ "r1": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step(
+ "Verify that R2 receives GR restarting capabilities"
+ " from R1 based on inheritence"
+ )
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ step("Kill BGPd on router R1")
+
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ step(
+ "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r1"
+ peer = "r2"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r2"
+ peer = "r1"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def BGP_GR_TC_52_p1(request):
+ """
+ Test Objective : Transition from Peer-level disbale to Global inherit helper
+ Global Mode : None
+ PerPeer Mode : GR Disable
+ GR Mode effective : GR Disable
+
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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 R1 as GR disabled node at per Peer-level for R2"
+ " & R2 as GR restarting node"
+ )
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step("Verify on R2 that R1 does't advertise any GR capabilities")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r2"
+ peer = "r1"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ step("Kill BGP on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 doesn't keep RIB & FIB entries."
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r2"
+ peer = "r1"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(
+ tgen, addr_type, dut, input_topo, next_hop, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ result = verify_rib(
+ tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+
+ step("Bring up BGP on R2 and remove Peer-level GR config from R1")
+
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": False}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {"graceful-restart-disable": False}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ step(
+ "Verify on R2 that R1 advertises GR capabilities as a helper node from global inherit"
+ )
+
+ input_dict = {
+ "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}},
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r2"
+ peer = "r1"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Kill BGP on R2")
+
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ step(
+ "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB"
+ )
+
+ for addr_type in ADDR_TYPES:
+ dut = "r2"
+ peer = "r1"
+ protocol = "bgp"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_1
+ )
+ input_topo = {"r1": topo["routers"]["r1"]}
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
+ tc_name, result
+ )
+
+ dut = "r1"
+ peer = "r2"
+ next_hop = next_hop_per_address_family(
+ tgen, dut, peer, addr_type, NEXT_HOP_IP_2
+ )
+ input_topo = {"r2": topo["routers"]["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
+ assert (
+ result is True
+ ), "Testcase {} :Failed \n Routes are 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))
diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py
new file mode 100644
index 0000000000..064fde1633
--- /dev/null
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py
@@ -0,0 +1,1515 @@
+#!/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 BGP Graceful Restart functionality.
+Basic Common Test steps for all the test case below :
+- Create topology (setup module)
+ Creating 7 routers topology
+- Bring up topology
+- Verify for bgp to converge
+- Configure BGP Graceful Restart on both the routers.
+
+TC_1_2:
+ Verify that EOR message is sent out only after initial convergence
+ Verify whether EOR message is received from all the peers after restart
+TC_3:
+ Verify the selection deferral timer functionality when EOR is not sent
+ by the helper router
+TC_11:
+ Verify that selection-deferral timer sets the maximum time to
+ avoid deadlock during which the best-path
+TC_10:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_15:
+ Test Objective : Test GR scenarios by enabling Graceful Restart
+ for multiple address families..
+TC_16:
+ Test Objective : Verify BGP-GR feature when restarting node
+ is a transit router for it's iBGP peers.
+TC_18:
+ Test Objective : Verify that GR helper router deletes stale routes
+ received from restarting node, if GR capability is not present in
+TC_19:
+ Test Objective : Verify that GR routers keeps all the routes
+ received from restarting node if both the routers are
+TC_26:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_28:
+ Test Objective : Verify if helper node goes down before restarting
+ node comes up online, helper node sets the R-bit to avoid dead-lock
+TC_29:
+ Test Objective : Change timers on the fly, and
+ verify if it takes immediate effect.
+TC_33:
+ Test Objective : Helper router receives same prefixes from two
+ different routers (GR-restarting and GR-disabled). Keeps the
+TC_34_1:
+ Test Objective : Restarting node doesn't preserve forwarding
+ state, helper router should not keep the stale entries.
+TC_34_2:
+ Test Objective : Restarting node doesn't preserve the forwarding
+ state verify the behaviour on helper node, if it still keeps the
+TC_32:
+ Test Objective : Restarting node is connected to multiple helper
+ nodes, one of them doesn't send EOR to restarting router. Verify
+TC_37:
+ Test Objective : Verify if helper node restarts before sending the
+ EOR message, restarting node doesn't wait until stale path timer
+TC_30:
+ Test Objective : Restarting node removes stale routes from Zebra
+ after receiving an EOR from helper router.
+
+"""
+
+import os
+import sys
+import time
+import pytest
+from time import sleep
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join("../"))
+sys.path.append(os.path.join("../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topojson import build_config_from_json
+from lib.bgp import (
+ clear_bgp,
+ verify_bgp_rib,
+ verify_graceful_restart,
+ create_router_bgp,
+ verify_r_bit,
+ verify_eor,
+ verify_f_bit,
+ verify_bgp_convergence,
+ verify_gr_address_family,
+ modify_bgp_config_when_bgpd_down,
+ verify_graceful_restart_timers,
+ verify_bgp_convergence_from_running_config,
+)
+
+from lib.common_config import (
+ write_test_header,
+ reset_config_on_routers,
+ start_topology,
+ kill_router_daemons,
+ start_router_daemons,
+ verify_rib,
+ check_address_types,
+ write_test_footer,
+ check_router_status,
+ step,
+ get_frr_ipv6_linklocal,
+ required_linux_kernel_version,
+)
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+BGP_CONVERGENCE = False
+GR_RESTART_TIMER = 5
+GR_SELECT_DEFER_TIMER = 5
+GR_STALEPATH_TIMER = 5
+PREFERRED_NEXT_HOP = "link_local"
+NEXT_HOP_4 = ["192.168.1.1", "192.168.4.2"]
+NEXT_HOP_6 = ["fd00:0:0:1::1", "fd00:0:0:4::2"]
+
+
+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.16")
+ 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_gr_topojson_topo2.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 deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Api call verify whether BGP is converged
+ ADDR_TYPES = check_address_types()
+
+ for addr_type in ADDR_TYPES:
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format(
+ BGP_CONVERGENCE
+ )
+
+ 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)
+
+
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
+ """
+ This function groups the repetitive function calls into one function.
+ """
+
+ logger.info("configure_gr_followed_by_clear: dut %s peer %s", dut, peer)
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][peer]["links"][dut][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][dut]["links"][peer][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ return True
+
+
+def next_hop_per_address_family(tgen, dut, peer, addr_type, next_hop_dict):
+ """
+ This function returns link_local or global next_hop per address-family
+ """
+
+ intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
+ if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
+ next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
+ else:
+ next_hop = next_hop_dict[addr_type]
+
+ return next_hop
+
+
+def test_BGP_GR_TC_1_2_p0(request):
+ """
+ Verify that EOR message is sent out only after initial convergence
+ Verify whether EOR message is received from all the peers after restart
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "Verify EOR Sent and Received : BGP_GR_TC_1_2 >> "
+ "BGP GR [Helper Mode]R3-----R1[Restart Mode] "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ "preserve-fw-state": True,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes received from router R3
+ dut = "r1"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("R1 goes for reload")
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying RIB routes
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("Starting bgpd process")
+ start_router_daemons(tgen, "r1", ["bgpd"])
+ logger.info("R1 is UP Now")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes received from router R3
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying EOR on restarting router
+ result = verify_eor(tgen, topo, addr_type, input_dict, dut="r3", peer="r1")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_3_p0(request):
+ """
+ Verify the selection deferral timer functionality when EOR is not sent
+ by the helper router
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Verify route download to RIB: BGP_GR_TC_3 >> "
+ "BGP GR [Helper Mode]R1-----R2[Restart Mode] "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "disable-eor": True,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ "r2": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ "preserve-fw-state": True,
+ "timer": {"select-defer-time": GR_SELECT_DEFER_TIMER},
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes received from router R1
+ dut = "r2"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("R2 goes for reload ")
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ logger.info("R2 is about to come up now")
+ start_router_daemons(tgen, "r2", ["bgpd"])
+ logger.info("R2 is UP Now")
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes received from router R1
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verify EOR on restarting router
+ result = verify_eor(
+ tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r2: EOR is set to True\n Error: {}".format(
+ tc_name, result
+ )
+
+ logger.info(
+ "Waiting for selection deferral timer({} sec)..".format(GR_SELECT_DEFER_TIMER)
+ )
+ sleep(GR_SELECT_DEFER_TIMER)
+
+ for addr_type in ADDR_TYPES:
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, "r2", input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_TC_11_p0(request):
+ """
+ Verify that selection-deferral timer sets the maximum time to
+ avoid deadlock during which the best-path
+ selection process is deferred, after a peer session was restarted
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info("Verify EOR Sent after deferral timeout : BGP_GR_TC_11")
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ "select-defer-time": GR_SELECT_DEFER_TIMER,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}},
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}},
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}},
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}},
+ }
+ }
+ },
+ },
+ }
+ },
+ "r3": {
+ "bgp": {
+ "graceful-restart": {"disable-eor": True},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ clear_bgp(tgen, addr_type, "r1")
+ clear_bgp(tgen, addr_type, "r3")
+
+ result = verify_bgp_convergence_from_running_config(tgen, topo)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes received from router R1
+ dut = "r1"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("R1 goes for reload")
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("Starting bgpd process")
+ start_router_daemons(tgen, "r1", ["bgpd"])
+ logger.info("R1 is UP Now")
+
+ for addr_type in ADDR_TYPES:
+ # Verify EOR on restarting router
+ result = verify_eor(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
+ tc_name, result
+ )
+
+ logger.info(
+ "Waiting for selection deferral timer({} sec).. ".format(
+ GR_SELECT_DEFER_TIMER + 2
+ )
+ )
+ sleep(GR_SELECT_DEFER_TIMER + 2)
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes received from router R1
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying EOR on restarting router
+ result = verify_eor(
+ tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_10_p2(request):
+ """
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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("Test Setup: [Helper Mode]R3-----R1[Restart Mode] initialized")
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "next_hop_self": True,
+ "graceful-restart": True,
+ "activate": "ipv6",
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "next_hop_self": True,
+ "graceful-restart": True,
+ "activate": "ipv4",
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "graceful-restart-helper": True,
+ "activate": "ipv6",
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "graceful-restart-helper": True,
+ "activate": "ipv4",
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ step(
+ "Verifying GR config and operational state for addr_type {}".format(
+ addr_type
+ )
+ )
+
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_topo = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv4Unicast",
+ dut="r1",
+ peer="r3",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv6Unicast",
+ dut="r1",
+ peer="r3",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv4Unicast",
+ dut="r3",
+ peer="r1",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv6Unicast",
+ dut="r3",
+ peer="r1",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Killing bgpd on r1")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ input_topo = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ step("Starting bgpd on r1")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ input_topo = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def BGP_GR_16_p2(request):
+ """
+ Test Objective : Verify BGP-GR feature when restarting node
+ is a transit router for it's iBGP peers.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Step 1] : Test Setup " "[Helper Mode]R3-----R1[Restart Mode] initialized"
+ )
+
+ # Configure graceful-restart and timers
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "graceful-restart": True,
+ "next_hop_self": True,
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "graceful-restart": True,
+ "next_hop_self": True,
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info(
+ "[Step 2] : Test Setup "
+ "[Helper Mode]R3-----R1[Restart Mode]"
+ "--------R6[Helper Mode] initialized"
+ )
+
+ # Configure graceful-restart and timers
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ result = verify_bgp_convergence_from_running_config(tgen, topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_18_p1(request):
+ """
+ Test Objective : Verify that GR helper router deletes stale routes
+ received from restarting node, if GR capability is not present in
+ restarting node's OPEN message.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Step 1] : Test Setup " "[Helper Mode]R6-----R1[Restart Mode] initialized"
+ )
+
+ # Configure graceful-restart and timers
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r6": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r6": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r6": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r6")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r6"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info(
+ "[Step 2] : Test Setup "
+ "[Helper Mode]R6-----R1[Restart Mode]"
+ "--------R2[Helper Mode] initialized"
+ )
+
+ # Configure graceful-restart and timers
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r2"
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 3] : Configure R1 to prevent sending EOR")
+
+ # Modify graceful-restart config to prevent sending EOR
+ input_dict_3 = {"r1": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
+
+ # Modify configuration to delete routes
+ network = {"ipv4": "101.0.20.1/32", "ipv6": "1::1/128"}
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": network[addr_type],
+ "no_of_network": 5,
+ "delete": True,
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Modify graceful-restart config
+ input_dict_3 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-disable": True}
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r1": {"graceful-restart-disable": True}
+ }
+ },
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-disable": True}
+ }
+ },
+ "r6": {
+ "dest_link": {
+ "r1": {"graceful-restart-disable": True}
+ }
+ },
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
+
+ logger.info("[Step 4] : Bring up the BGPd daemon on R1 for 30" " seconds..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r6: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying BGP RIB routes
+ dut = "r2"
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r2: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(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_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py
new file mode 100644
index 0000000000..4356c4d591
--- /dev/null
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py
@@ -0,0 +1,1216 @@
+#!/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 BGP Graceful Restart functionality.
+Basic Common Test steps for all the test case below :
+- Create topology (setup module)
+ Creating 7 routers topology
+- Bring up topology
+- Verify for bgp to converge
+- Configure BGP Graceful Restart on both the routers.
+
+TC_1_2:
+ Verify that EOR message is sent out only after initial convergence
+ Verify whether EOR message is received from all the peers after restart
+TC_3:
+ Verify the selection deferral timer functionality when EOR is not sent
+ by the helper router
+TC_11:
+ Verify that selection-deferral timer sets the maximum time to
+ avoid deadlock during which the best-path
+TC_10:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_15:
+ Test Objective : Test GR scenarios by enabling Graceful Restart
+ for multiple address families..
+TC_16:
+ Test Objective : Verify BGP-GR feature when restarting node
+ is a transit router for it's iBGP peers.
+TC_18:
+ Test Objective : Verify that GR helper router deletes stale routes
+ received from restarting node, if GR capability is not present in
+TC_19:
+ Test Objective : Verify that GR routers keeps all the routes
+ received from restarting node if both the routers are
+TC_26:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_28:
+ Test Objective : Verify if helper node goes down before restarting
+ node comes up online, helper node sets the R-bit to avoid dead-lock
+TC_29:
+ Test Objective : Change timers on the fly, and
+ verify if it takes immediate effect.
+TC_33:
+ Test Objective : Helper router receives same prefixes from two
+ different routers (GR-restarting and GR-disabled). Keeps the
+TC_34_1:
+ Test Objective : Restarting node doesn't preserve forwarding
+ state, helper router should not keep the stale entries.
+TC_34_2:
+ Test Objective : Restarting node doesn't preserve the forwarding
+ state verify the behaviour on helper node, if it still keeps the
+TC_32:
+ Test Objective : Restarting node is connected to multiple helper
+ nodes, one of them doesn't send EOR to restarting router. Verify
+TC_37:
+ Test Objective : Verify if helper node restarts before sending the
+ EOR message, restarting node doesn't wait until stale path timer
+TC_30:
+ Test Objective : Restarting node removes stale routes from Zebra
+ after receiving an EOR from helper router.
+
+"""
+
+import os
+import sys
+import time
+import pytest
+from time import sleep
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join("../"))
+sys.path.append(os.path.join("../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topojson import build_config_from_json
+from lib.bgp import (
+ clear_bgp,
+ verify_bgp_rib,
+ verify_graceful_restart,
+ create_router_bgp,
+ verify_r_bit,
+ verify_eor,
+ verify_f_bit,
+ verify_bgp_convergence,
+ verify_gr_address_family,
+ modify_bgp_config_when_bgpd_down,
+ verify_graceful_restart_timers,
+ verify_bgp_convergence_from_running_config,
+)
+
+from lib.common_config import (
+ write_test_header,
+ reset_config_on_routers,
+ start_topology,
+ kill_router_daemons,
+ start_router_daemons,
+ verify_rib,
+ check_address_types,
+ write_test_footer,
+ check_router_status,
+ step,
+ get_frr_ipv6_linklocal,
+ required_linux_kernel_version,
+)
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+BGP_CONVERGENCE = False
+GR_RESTART_TIMER = 5
+GR_SELECT_DEFER_TIMER = 5
+GR_STALEPATH_TIMER = 5
+PREFERRED_NEXT_HOP = "link_local"
+NEXT_HOP_4 = ["192.168.1.1", "192.168.4.2"]
+NEXT_HOP_6 = ["fd00:0:0:1::1", "fd00:0:0:4::2"]
+
+
+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.16")
+ 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_gr_topojson_topo2.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 deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Api call verify whether BGP is converged
+ ADDR_TYPES = check_address_types()
+
+ for addr_type in ADDR_TYPES:
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format(
+ BGP_CONVERGENCE
+ )
+
+ 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)
+
+
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
+ """
+ This function groups the repetitive function calls into one function.
+ """
+
+ logger.info("configure_gr_followed_by_clear: dut %s peer %s", dut, peer)
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][peer]["links"][dut][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][dut]["links"][peer][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ return True
+
+
+def next_hop_per_address_family(tgen, dut, peer, addr_type, next_hop_dict):
+ """
+ This function returns link_local or global next_hop per address-family
+ """
+
+ intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
+ if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
+ next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
+ else:
+ next_hop = next_hop_dict[addr_type]
+
+ return next_hop
+
+
+def test_BGP_GR_26_p2(request):
+ """
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Step 1] : Test Setup " "[Helper Mode]R3-----R1[Restart Mode] initialized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "graceful-restart": True,
+ "next_hop_self": True,
+ "activate": "ipv6",
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "graceful-restart": True,
+ "next_hop_self": True,
+ "activate": "ipv4",
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "graceful-restart-helper": True,
+ "activate": "ipv6",
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "graceful-restart-helper": True,
+ "activate": "ipv4",
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r3", peer="r1"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_topo = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ input_topo = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ input_topo = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_topo)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv4Unicast",
+ dut="r1",
+ peer="r3",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv6Unicast",
+ dut="r1",
+ peer="r3",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv4Unicast",
+ dut="r3",
+ peer="r1",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # verify multi address family
+ result = verify_gr_address_family(
+ tgen,
+ topo,
+ addr_type,
+ "ipv6Unicast",
+ dut="r3",
+ peer="r1",
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_chaos_28_p1(request):
+ """
+ Test Objective : Verify if helper node goes down before restarting
+ node comes up online, helper node sets the R-bit to avoid dead-lock
+ till SDT expiry.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "Test Case: test_BGP_GR_chaos_28 :"
+ "[Helper Mode]R3-----R1[Restart Mode] initialized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 1] : Kill BGPd daemon on R1..")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 2] : Kill BGPd daemon on R3..")
+
+ # Kill BGPd daemon on R3
+ kill_router_daemons(tgen, "r3", ["bgpd"])
+
+ logger.info("[Step 3] : Start BGPd daemon on R1..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 4] : Start BGPd daemon on R3..")
+
+ # Start BGPd daemon on R3
+ start_router_daemons(tgen, "r3", ["bgpd"])
+
+ # Verify r_bit
+ for addr_type in ADDR_TYPES:
+ result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r3", peer="r1")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_chaos_29_p1(request):
+ """
+ Test Objective : Change timers on the fly, and
+ verify if it takes immediate effect.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Test Case : test_BGP_GR_chaos_29"
+ " BGP GR [Helper Mode]R3-----R1[Restart Mode]"
+ " and [restart-time 150]R1 initialized"
+ )
+
+ # Configure graceful-restart and timers
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER}},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verify graceful-restart timers
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER + 5}}
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER}}
+ }
+ }
+ }
+
+ result = verify_graceful_restart_timers(
+ tgen, topo, addr_type, input_dict_2, dut="r3", peer="r1"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes before shutting down BGPd daemon
+ dut = "r3"
+ input_dict = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 2] : Kill BGPd daemon on R1..")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 3] : Wait for {} seconds..".format(GR_RESTART_TIMER))
+
+ # Waiting for GR_RESTART_TIMER
+ sleep(GR_RESTART_TIMER)
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes before shutting down BGPd daemon
+ input_dict = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ logger.info("[Step 4] : Start BGPd daemon on R1..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_chaos_33_p1(request):
+ """
+ Test Objective : Helper router receives same prefixes from two
+ different routers (GR-restarting and GR-disabled). Keeps the
+ stale entry only for GR-restarting node(next-hop is correct).
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Test Case : test_BGP_GR_chaos_33 "
+ "BGP GR "
+ "[Restart Mode]R1--R3[Helper Mode]--R4[Disabled Mode]"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 2] : Advertise same networks from R1 and R4..")
+
+ # Api call to delete advertised networks
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": "200.0.20.1/32",
+ "no_of_network": 2,
+ }
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": "2001::1/128", "no_of_network": 2}
+ ]
+ }
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": "200.0.20.1/32", "no_of_network": 2}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": "2001::1/128", "no_of_network": 2}
+ ]
+ }
+ },
+ }
+ }
+ },
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Verifying RIB routes
+ dut = "r3"
+ peer1 = "r1"
+ peer2 = "r4"
+ intf1 = topo["routers"][peer1]["links"][dut]["interface"]
+ intf2 = topo["routers"][peer2]["links"][dut]["interface"]
+
+ if addr_type == "ipv4":
+ next_hop_4 = NEXT_HOP_4
+ result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_4)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ if addr_type == "ipv6":
+ if "link_local" in PREFERRED_NEXT_HOP:
+ next_hop1 = get_frr_ipv6_linklocal(tgen, peer1, intf=intf1)
+ next_hop2 = get_frr_ipv6_linklocal(tgen, peer2, intf=intf2)
+
+ next_hop_6 = [next_hop1, next_hop2]
+ else:
+ next_hop_6 = NEXT_HOP_6
+
+ result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_6)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 3] : Kill BGPd daemon on R1 and R4..")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ # Kill BGPd daemon on R4
+ kill_router_daemons(tgen, "r4", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying RIB routes
+ next_hop_6 = ["fd00:0:0:1::1"]
+ if addr_type == "ipv4":
+ next_hop_4 = NEXT_HOP_4[0]
+
+ result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_4)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ if addr_type == "ipv6":
+ if "link_local" in PREFERRED_NEXT_HOP:
+ next_hop_6 = get_frr_ipv6_linklocal(tgen, peer1, intf=intf1)
+ else:
+ next_hop_6 = NEXT_HOP_6[0]
+
+ result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_6)
+
+ # Verifying RIB routes
+ if addr_type == "ipv4":
+ next_hop_4 = NEXT_HOP_4[1]
+ result = verify_rib(
+ tgen, addr_type, dut, input_dict_2, next_hop_4, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ if addr_type == "ipv6":
+ if "link_local" in PREFERRED_NEXT_HOP:
+ next_hop_6 = get_frr_ipv6_linklocal(tgen, peer2, intf=intf2)
+ else:
+ next_hop_6 = NEXT_HOP_6[1]
+
+ result = verify_rib(
+ tgen, addr_type, dut, input_dict_2, next_hop_6, expected=False
+ )
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in ZEBRA\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ logger.info("[Step 4] : Start BGPd daemon on R1 and R4..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ # Start BGPd daemon on R4
+ start_router_daemons(tgen, "r4", ["bgpd"])
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_chaos_34_2_p1(request):
+ """
+ Test Objective : Restarting node doesn't preserve the forwarding
+ state verify the behaviour on helper node, if it still keeps the
+ stale routes.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Test Case : test_BGP_GR_chaos_34 "
+ "BGP GR "
+ "[Restart Mode]R1---R3[Helper Mode]"
+ )
+
+ logger.info("[Step 1] : Configure restarting" " router R1 to prevent ")
+ logger.info("[Step 2] : Reset the session" " between R1 and R3..")
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"preserve-fw-state": True, "disable-eor": True},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verify f-bit before killing BGPd daemon
+ result = verify_f_bit(tgen, topo, addr_type, input_dict, "r3", "r1")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes after starting BGPd daemon
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 3] : Kill BGPd daemon on R1..")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 4] : Withdraw/delete the prefixes " "originated from R1..")
+
+ # Api call to delete advertised networks
+ network = {"ipv4": "101.0.20.1/32", "ipv6": "1::1/128"}
+ for addr_type in ADDR_TYPES:
+ input_dict_2 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": network[addr_type],
+ "no_of_network": 5,
+ "delete": True,
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 5] : Remove the CLI from R1's config to " "set the F-bit..")
+
+ # Modify graceful-restart config not to set f-bit
+ # and write to /etc/frr
+ input_dict_2 = {"r1": {"bgp": {"graceful-restart": {"preserve-fw-state": False}}}}
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
+
+ logger.info("[Step 6] : Bring up the BGPd daemon on R1 again..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verify f-bit after starting BGPd daemon
+ result = verify_f_bit(
+ tgen, topo, addr_type, input_dict, "r3", "r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format(
+ tc_name, result
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying BGP RIB routes after starting BGPd daemon
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(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_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py
new file mode 100644
index 0000000000..86d676dd8b
--- /dev/null
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py
@@ -0,0 +1,1367 @@
+#!/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 BGP Graceful Restart functionality.
+Basic Common Test steps for all the test case below :
+- Create topology (setup module)
+ Creating 7 routers topology
+- Bring up topology
+- Verify for bgp to converge
+- Configure BGP Graceful Restart on both the routers.
+
+TC_1_2:
+ Verify that EOR message is sent out only after initial convergence
+ Verify whether EOR message is received from all the peers after restart
+TC_3:
+ Verify the selection deferral timer functionality when EOR is not sent
+ by the helper router
+TC_11:
+ Verify that selection-deferral timer sets the maximum time to
+ avoid deadlock during which the best-path
+TC_10:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_15:
+ Test Objective : Test GR scenarios by enabling Graceful Restart
+ for multiple address families..
+TC_16:
+ Test Objective : Verify BGP-GR feature when restarting node
+ is a transit router for it's iBGP peers.
+TC_18:
+ Test Objective : Verify that GR helper router deletes stale routes
+ received from restarting node, if GR capability is not present in
+TC_19:
+ Test Objective : Verify that GR routers keeps all the routes
+ received from restarting node if both the routers are
+TC_26:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_28:
+ Test Objective : Verify if helper node goes down before restarting
+ node comes up online, helper node sets the R-bit to avoid dead-lock
+TC_29:
+ Test Objective : Change timers on the fly, and
+ verify if it takes immediate effect.
+TC_33:
+ Test Objective : Helper router receives same prefixes from two
+ different routers (GR-restarting and GR-disabled). Keeps the
+TC_34_1:
+ Test Objective : Restarting node doesn't preserve forwarding
+ state, helper router should not keep the stale entries.
+TC_34_2:
+ Test Objective : Restarting node doesn't preserve the forwarding
+ state verify the behaviour on helper node, if it still keeps the
+TC_32:
+ Test Objective : Restarting node is connected to multiple helper
+ nodes, one of them doesn't send EOR to restarting router. Verify
+TC_37:
+ Test Objective : Verify if helper node restarts before sending the
+ EOR message, restarting node doesn't wait until stale path timer
+TC_30:
+ Test Objective : Restarting node removes stale routes from Zebra
+ after receiving an EOR from helper router.
+
+"""
+
+import os
+import sys
+import time
+import pytest
+from time import sleep
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join("../"))
+sys.path.append(os.path.join("../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topojson import build_config_from_json
+from lib.bgp import (
+ clear_bgp,
+ verify_bgp_rib,
+ verify_graceful_restart,
+ create_router_bgp,
+ verify_r_bit,
+ verify_eor,
+ verify_f_bit,
+ verify_bgp_convergence,
+ verify_gr_address_family,
+ modify_bgp_config_when_bgpd_down,
+ verify_graceful_restart_timers,
+ verify_bgp_convergence_from_running_config,
+)
+
+from lib.common_config import (
+ write_test_header,
+ reset_config_on_routers,
+ start_topology,
+ kill_router_daemons,
+ start_router_daemons,
+ verify_rib,
+ check_address_types,
+ write_test_footer,
+ check_router_status,
+ step,
+ get_frr_ipv6_linklocal,
+ required_linux_kernel_version,
+)
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+BGP_CONVERGENCE = False
+GR_RESTART_TIMER = 5
+GR_SELECT_DEFER_TIMER = 5
+GR_STALEPATH_TIMER = 5
+PREFERRED_NEXT_HOP = "link_local"
+NEXT_HOP_4 = ["192.168.1.1", "192.168.4.2"]
+NEXT_HOP_6 = ["fd00:0:0:1::1", "fd00:0:0:4::2"]
+
+
+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.16")
+ 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_gr_topojson_topo2.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 deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Api call verify whether BGP is converged
+ ADDR_TYPES = check_address_types()
+
+ for addr_type in ADDR_TYPES:
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format(
+ BGP_CONVERGENCE
+ )
+
+ 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)
+
+
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
+ """
+ This function groups the repetitive function calls into one function.
+ """
+
+ logger.info("configure_gr_followed_by_clear: dut %s peer %s", dut, peer)
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][peer]["links"][dut][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][dut]["links"][peer][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ return True
+
+
+def next_hop_per_address_family(tgen, dut, peer, addr_type, next_hop_dict):
+ """
+ This function returns link_local or global next_hop per address-family
+ """
+
+ intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
+ if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
+ next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
+ else:
+ next_hop = next_hop_dict[addr_type]
+
+ return next_hop
+
+
+def test_BGP_GR_chaos_34_1_p1(request):
+ """
+ Test Objective : Restarting node doesn't preserve forwarding
+ state, helper router should not keep the stale entries.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Test Case : test_BGP_GR_chaos_31 "
+ "BGP GR "
+ "[Restart Mode]R1---R3[Helper Mode]"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "preserve-fw-state": True,
+ "timer": {"restart-time": GR_RESTART_TIMER},
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes after starting BGPd daemon
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info(
+ "[Step 1] : Remove the preserve-fw-state command"
+ " from restarting node R1's config"
+ )
+
+ # Configure graceful-restart to set f-bit as False
+ input_dict_2 = {"r1": {"bgp": {"graceful-restart": {"preserve-fw-state": False}}}}
+
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ logger.info("[Step 2] : Reset the session between R1 and R3..")
+
+ # Reset sessions
+ for addr_type in ADDR_TYPES:
+ clear_bgp(tgen, addr_type, "r1")
+
+ result = verify_bgp_convergence_from_running_config(tgen, topo)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Verify f-bit after starting BGPd daemon
+ result = verify_f_bit(
+ tgen, topo, addr_type, input_dict_2, "r3", "r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format(
+ tc_name, result
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ logger.info("[Step 3] : Kill BGPd daemon on R1..")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ # Waiting for GR_RESTART_TIMER
+ logger.info("Waiting for {} sec..".format(GR_RESTART_TIMER))
+ sleep(GR_RESTART_TIMER)
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ input_dict = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_chaos_32_p1(request):
+ """
+ Test Objective : Restarting node is connected to multiple helper
+ nodes, one of them doesn't send EOR to restarting router. Verify
+ that only after SDT restarting node send EOR to all helper peers
+ excluding the prefixes originated by faulty router.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Test Case : test_BGP_GR_chaos_32 "
+ "BGP GR "
+ "[Restart Mode]R1---R3&R5[Helper Mode]"
+ )
+
+ logger.info(
+ "[Step 1] : Change the mode on R1 be a restarting" " node on global level"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"graceful-restart": True},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"next_hop_self": True}}},
+ "r5": {"dest_link": {"r1": {"graceful-restart": True}}},
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"next_hop_self": True}}},
+ "r5": {"dest_link": {"r1": {"graceful-restart": True}}},
+ }
+ }
+ },
+ },
+ }
+ },
+ "r5": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r5": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r5": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r5")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r5"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes after starting BGPd daemon
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r5"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 2] : Kill BGPd daemon on R1..")
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 3] : Withdraw all the advertised prefixes from R5")
+
+ # Api call to delete advertised networks
+ network = {"ipv4": "105.0.20.1/32", "ipv6": "5::1/128"}
+ for addr_type in ADDR_TYPES:
+ input_dict_2 = {
+ "r5": {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": network[addr_type],
+ "no_of_network": 5,
+ "delete": True,
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ logger.info(
+ "[Step 4] : Stop the helper router R5 from sending EOR" " message using CLI"
+ )
+
+ # Modify graceful-restart config to prevent sending EOR
+ input_dict_3 = {"r5": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
+
+ result = create_router_bgp(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ logger.info("[Step 5] : Bring up the BGPd daemon on R1..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verify EOR is disabled
+ result = verify_eor(
+ tgen, topo, addr_type, input_dict_3, dut="r5", peer="r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r5: EOR is set to TRUE\n Error: {}".format(
+ tc_name, result
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying BGP RIB routes after starting BGPd daemon
+ input_dict_1 = {key: topo["routers"][key] for key in ["r5"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_chaos_37_p1(request):
+ """
+ Test Objective : Verify if helper node restarts before sending the
+ EOR message, restarting node doesn't wait until stale path timer
+ expiry to do the best path selection and sends an EOR
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Test Case : test_BGP_GR_chaos_37 "
+ "BGP GR "
+ "[Restart Mode]R1---R3[Helper Mode]"
+ )
+
+ logger.info(
+ "[Step 1] : Configure restarting router R3 to prevent " "sending an EOR.."
+ )
+
+ logger.info("[Step 2] : Reset the session between R3 and R1..")
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "graceful-restart": {"disable-eor": True},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verify EOR is disabled
+ result = verify_eor(
+ tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format(
+ tc_name, result
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying BGP RIB routes after starting BGPd daemon
+ dut = "r1"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 3] : Kill BGPd daemon on R1..")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 4] : Start BGPd daemon on R1..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 5] : Kill BGPd daemon on R3..")
+
+ # Kill BGPd daemon on R3
+ kill_router_daemons(tgen, "r3", ["bgpd"])
+
+ # Modify graceful-restart config to prevent sending EOR
+ input_dict_2 = {"r3": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
+
+ logger.info("[Step 6] : Start BGPd daemon on R3..")
+
+ # Start BGPd daemon on R3
+ start_router_daemons(tgen, "r3", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verify r_bit
+ result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r3")
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verify EOR is send from R1 to R3
+ input_dict_3 = {"r1": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
+
+ result = verify_eor(
+ tgen, topo, addr_type, input_dict_3, dut="r1", peer="r3", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_chaos_30_p1(request):
+ """
+ Test Objective : Restarting node removes stale routes from Zebra
+ after receiving an EOR from helper router.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Test Case : test_BGP_GR_chaos_30 "
+ "BGP GR [Helper Mode]R3-----R1[Restart Mode] "
+ )
+
+ # Configure graceful-restart and timers
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"preserve-fw-state": True},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes before shutting down BGPd daemon
+ dut = "r1"
+ input_dict = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 2] : Kill BGPd daemon on R1..")
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ logger.info("[Step 3] : Withdraw advertised prefixes from R3...")
+
+ # Api call to delete advertised networks
+ network = {"ipv4": "103.0.20.1/32", "ipv6": "3::1/128"}
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": network[addr_type],
+ "no_of_network": 5,
+ "delete": True,
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ logger.info("[Step 4] : Start BGPd daemon on R1..")
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes before shutting down BGPd daemon
+ input_dict = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_15_p2(request):
+ """
+ Test Objective : Test GR scenarios by enabling Graceful Restart
+ for multiple address families..
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r6": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r6": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r6": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r6")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r6"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ logger.info(
+ "[Step 2] : Test Setup "
+ "[Helper Mode]R6-----R1[Restart Mode]"
+ "--------R2[Helper Mode] Initilized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_convergence(tgen, topo)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def BGP_GR_TC_7_p1(request):
+ """
+ Verify that BGP restarting node deletes all the routes received from peer
+ if BGP Graceful capability is not present in BGP Open message from the
+ peer
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ " Verify route download to RIB: BGP_GR_TC_7 >> "
+ "BGP GR [Helper Mode]R3-----R1[Restart Mode] "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r1": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ "preserve-fw-state": True,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes received from router R1
+ dut = "r1"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ logger.info("R1 goes for reload")
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ # Change the configuration on router R1
+ input_dict_2 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ # Change the configuration on R1
+ network = {"ipv4": "103.0.20.1/32", "ipv6": "3::1/128"}
+ for addr_type in ADDR_TYPES:
+ input_dict_2 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": network[addr_type],
+ "no_of_network": 5,
+ "delete": True,
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ logger.info("R1 is about to come up now")
+ start_router_daemons(tgen, "r1", ["bgpd"])
+ logger.info("R1 is UP Now")
+
+ # Wait for RIB stale timeout
+ logger.info("Verify routes are not present" "in restart router")
+
+ for addr_type in ADDR_TYPES:
+ # Verifying RIB routes
+ dut = "r1"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
+ result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r1: routes are still present in ZEBRA\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_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py
new file mode 100644
index 0000000000..889f47f377
--- /dev/null
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py
@@ -0,0 +1,1024 @@
+#!/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 BGP Graceful Restart functionality.
+Basic Common Test steps for all the test case below :
+- Create topology (setup module)
+ Creating 7 routers topology
+- Bring up topology
+- Verify for bgp to converge
+- Configure BGP Graceful Restart on both the routers.
+
+TC_1_2:
+ Verify that EOR message is sent out only after initial convergence
+ Verify whether EOR message is received from all the peers after restart
+TC_3:
+ Verify the selection deferral timer functionality when EOR is not sent
+ by the helper router
+TC_11:
+ Verify that selection-deferral timer sets the maximum time to
+ avoid deadlock during which the best-path
+TC_10:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_15:
+ Test Objective : Test GR scenarios by enabling Graceful Restart
+ for multiple address families..
+TC_16:
+ Test Objective : Verify BGP-GR feature when restarting node
+ is a transit router for it's iBGP peers.
+TC_18:
+ Test Objective : Verify that GR helper router deletes stale routes
+ received from restarting node, if GR capability is not present in
+TC_19:
+ Test Objective : Verify that GR routers keeps all the routes
+ received from restarting node if both the routers are
+TC_26:
+ Test Objective : Test GR scenarios on helper router by enabling
+ Graceful Restart for multiple address families.
+TC_28:
+ Test Objective : Verify if helper node goes down before restarting
+ node comes up online, helper node sets the R-bit to avoid dead-lock
+TC_29:
+ Test Objective : Change timers on the fly, and
+ verify if it takes immediate effect.
+TC_33:
+ Test Objective : Helper router receives same prefixes from two
+ different routers (GR-restarting and GR-disabled). Keeps the
+TC_34_1:
+ Test Objective : Restarting node doesn't preserve forwarding
+ state, helper router should not keep the stale entries.
+TC_34_2:
+ Test Objective : Restarting node doesn't preserve the forwarding
+ state verify the behaviour on helper node, if it still keeps the
+TC_32:
+ Test Objective : Restarting node is connected to multiple helper
+ nodes, one of them doesn't send EOR to restarting router. Verify
+TC_37:
+ Test Objective : Verify if helper node restarts before sending the
+ EOR message, restarting node doesn't wait until stale path timer
+TC_30:
+ Test Objective : Restarting node removes stale routes from Zebra
+ after receiving an EOR from helper router.
+
+These tests have been broken up into 4 sub python scripts because
+the totality of run time for this script was greater than 10 minutes
+"""
+
+import os
+import sys
+import time
+import pytest
+from time import sleep
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join("../"))
+sys.path.append(os.path.join("../lib/"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.topojson import build_config_from_json
+from lib.bgp import (
+ clear_bgp,
+ verify_bgp_rib,
+ verify_graceful_restart,
+ create_router_bgp,
+ verify_r_bit,
+ verify_eor,
+ verify_f_bit,
+ verify_bgp_convergence,
+ verify_gr_address_family,
+ modify_bgp_config_when_bgpd_down,
+ verify_graceful_restart_timers,
+ verify_bgp_convergence_from_running_config,
+)
+
+from lib.common_config import (
+ write_test_header,
+ reset_config_on_routers,
+ start_topology,
+ kill_router_daemons,
+ start_router_daemons,
+ verify_rib,
+ check_address_types,
+ write_test_footer,
+ check_router_status,
+ step,
+ get_frr_ipv6_linklocal,
+ required_linux_kernel_version,
+)
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Global variables
+BGP_CONVERGENCE = False
+GR_RESTART_TIMER = 5
+GR_SELECT_DEFER_TIMER = 5
+GR_STALEPATH_TIMER = 5
+PREFERRED_NEXT_HOP = "link_local"
+NEXT_HOP_4 = ["192.168.1.1", "192.168.4.2"]
+NEXT_HOP_6 = ["fd00:0:0:1::1", "fd00:0:0:4::2"]
+
+
+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.16")
+ 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_gr_topojson_topo2.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 deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Api call verify whether BGP is converged
+ ADDR_TYPES = check_address_types()
+
+ for addr_type in ADDR_TYPES:
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format(
+ BGP_CONVERGENCE
+ )
+
+ 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)
+
+
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
+ """
+ This function groups the repetitive function calls into one function.
+ """
+
+ logger.info("configure_gr_followed_by_clear: dut %s peer %s", dut, peer)
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][peer]["links"][dut][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
+
+ for addr_type in ADDR_TYPES:
+ neighbor = topo["routers"][dut]["links"][peer][addr_type].split("/")[0]
+ clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
+
+ result = verify_bgp_convergence_from_running_config(tgen)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ return True
+
+
+def next_hop_per_address_family(tgen, dut, peer, addr_type, next_hop_dict):
+ """
+ This function returns link_local or global next_hop per address-family
+ """
+
+ intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
+ if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
+ next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
+ else:
+ next_hop = next_hop_dict[addr_type]
+
+ return next_hop
+
+
+def test_BGP_GR_TC_23_p1(request):
+ """
+ Verify that helper routers are deleting stale routes after stale route
+ timer's expiry. If all the routes are not received from restating node
+ after restart.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "Verify Stale Routes are deleted on helper: BGP_GR_TC_23 >> "
+ "BGP GR [Helper Mode]R1-----R2[Restart Mode] "
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "graceful-restart": {"timer": {"stalepath-time": GR_STALEPATH_TIMER}},
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ },
+ }
+ },
+ "r2": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ "preserve-fw-state": True,
+ },
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
+ }
+ }
+ },
+ },
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes received from router R1
+ dut = "r1"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ logger.info("R2 goes for reload")
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ # Modify configuration to delete routes and include disable-eor
+ input_dict_3 = {"r2": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
+
+ # Modify configuration to delete routes and include disable-eor
+ network = {"ipv4": "102.0.20.1/32", "ipv6": "2::1/128"}
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r2": {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "advertise_networks": [
+ {
+ "network": network[addr_type],
+ "no_of_network": 3,
+ "delete": True,
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ logger.info("BGPd comes up for r2")
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ # Wait for stalepath timer
+ logger.info("Waiting for stalepath timer({} sec..)".format(GR_STALEPATH_TIMER))
+ sleep(GR_STALEPATH_TIMER)
+
+ for addr_type in ADDR_TYPES:
+ clear_bgp(tgen, addr_type, "r2")
+
+ # Verifying RIB routes
+ dut = "r1"
+ network = {"ipv4": "102.0.20.4/32", "ipv6": "2::4/128"}
+ for addr_type in ADDR_TYPES:
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "advertise_networks": [
+ {"network": network[addr_type], "no_of_network": 2}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ # Verify EOR on helper router
+ result = verify_eor(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False
+ )
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
+ tc_name, result
+ )
+
+ # Verifying BGP RIB routes received from router R1
+ dut = "r1"
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_20_p1(request):
+ """
+ Test Objective : Verify that GR routers delete all the routes
+ received from a node if both the routers are configured as GR
+ helper node
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Step 1] : Test Setup " "[Restart Mode]R3-----R1[Restart Mode] Initilized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in BGP RIB\n Error: {}".format(
+ tc_name, result
+ )
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n "
+ "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+ )
+ logger.info(" Expected behavior: {}".format(result))
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r1", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_convergence(tgen, topo)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_21_p2(request):
+ """
+ Test Objective : VVerify BGP-GR feature when helper node is
+ a transit router for it's eBGP peers.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Step 1] : Test Setup " "[Helper Mode]R6-----R1[Restart Mode] Initilized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {
+ "r1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r6": {
+ "dest_link": {
+ "r1": {"graceful-restart-disable": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r6": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r6": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r6": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r6")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r6"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ logger.info(
+ "[Step 2] : Test Setup "
+ "[Restart Mode]R2-----[Helper Mode]R1[Disable Mode]"
+ "--------R6[Helper Mode] Initilized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {
+ "bgp": {
+ "graceful-restart": {
+ "graceful-restart": True,
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_convergence(tgen, topo)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes after bringing up BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r6"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_BGP_GR_22_p2(request):
+ """
+ Test Objective : Verify BGP-GR feature when helper node
+ is a transit router for it's iBGP peers.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Check router status
+ check_router_status(tgen)
+
+ # 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)
+
+ logger.info(
+ "[Step 1] : Test Setup " "[Helper Mode]R3-----R1[Restart Mode] Initilized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "graceful-restart-disable": True,
+ "next_hop_self": True,
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "graceful-restart-disable": True,
+ "next_hop_self": True,
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ logger.info(
+ "[Step 2] : Test Setup "
+ "[Restart Mode]R2-----[Helper Mode]R1[Disable Mode]"
+ "--------R3[Helper Mode] Initilized"
+ )
+
+ # Configure graceful-restart
+ input_dict = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {"graceful-restart-helper": True}
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
+ }
+
+ configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
+
+ for addr_type in ADDR_TYPES:
+ result = verify_graceful_restart(
+ tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
+ )
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Kill BGPd daemon on R1
+ kill_router_daemons(tgen, "r2", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Start BGPd daemon on R1
+ start_router_daemons(tgen, "r2", ["bgpd"])
+
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_convergence(tgen, topo)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying BGP RIB routes
+ dut = "r3"
+ input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+
+ # Verifying RIB routes before shutting down BGPd daemon
+ result = verify_rib(tgen, addr_type, dut, input_dict_2)
+ assert result is True, "Testcase {} :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_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py
deleted file mode 100644
index 52ad7813c5..0000000000
--- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py
+++ /dev/null
@@ -1,4358 +0,0 @@
-#!/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 BGP Graceful Restart functionality.
-Basic Common Test steps for all the test case below :
-- Create topology (setup module)
- Creating 7 routers topology
-- Bring up topology
-- Verify for bgp to converge
-- Configure BGP Graceful Restart on both the routers.
-
-TC_1_2:
- Verify that EOR message is sent out only after initial convergence
- Verify whether EOR message is received from all the peers after restart
-TC_3:
- Verify the selection deferral timer functionality when EOR is not sent
- by the helper router
-TC_11:
- Verify that selection-deferral timer sets the maximum time to
- avoid deadlock during which the best-path
-TC_10:
- Test Objective : Test GR scenarios on helper router by enabling
- Graceful Restart for multiple address families.
-TC_15:
- Test Objective : Test GR scenarios by enabling Graceful Restart
- for multiple address families..
-TC_16:
- Test Objective : Verify BGP-GR feature when restarting node
- is a transit router for it's iBGP peers.
-TC_18:
- Test Objective : Verify that GR helper router deletes stale routes
- received from restarting node, if GR capability is not present in
-TC_19:
- Test Objective : Verify that GR routers keeps all the routes
- received from restarting node if both the routers are
-TC_26:
- Test Objective : Test GR scenarios on helper router by enabling
- Graceful Restart for multiple address families.
-TC_28:
- Test Objective : Verify if helper node goes down before restarting
- node comes up online, helper node sets the R-bit to avoid dead-lock
-TC_29:
- Test Objective : Change timers on the fly, and
- verify if it takes immediate effect.
-TC_33:
- Test Objective : Helper router receives same prefixes from two
- different routers (GR-restarting and GR-disabled). Keeps the
-TC_34_1:
- Test Objective : Restarting node doesn't preserve forwarding
- state, helper router should not keep the stale entries.
-TC_34_2:
- Test Objective : Restarting node doesn't preserve the forwarding
- state verify the behaviour on helper node, if it still keeps the
-TC_32:
- Test Objective : Restarting node is connected to multiple helper
- nodes, one of them doesn't send EOR to restarting router. Verify
-TC_37:
- Test Objective : Verify if helper node restarts before sending the
- EOR message, restarting node doesn't wait until stale path timer
-TC_30:
- Test Objective : Restarting node removes stale routes from Zebra
- after receiving an EOR from helper router.
-
-"""
-
-import os
-import sys
-import time
-import pytest
-from time import sleep
-
-# Save the Current Working Directory to find configuration files.
-CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join("../"))
-sys.path.append(os.path.join("../lib/"))
-
-# pylint: disable=C0413
-# Import topogen and topotest helpers
-from lib.topogen import Topogen, get_topogen
-from lib.topolog import logger
-
-# Required to instantiate the topology builder class.
-
-# Import topoJson from lib, to create topology and initial configuration
-from lib.topojson import build_config_from_json
-from lib.bgp import (
- clear_bgp,
- verify_bgp_rib,
- verify_graceful_restart,
- create_router_bgp,
- verify_r_bit,
- verify_eor,
- verify_f_bit,
- verify_bgp_convergence,
- verify_gr_address_family,
- modify_bgp_config_when_bgpd_down,
- verify_graceful_restart_timers,
- verify_bgp_convergence_from_running_config,
-)
-
-from lib.common_config import (
- write_test_header,
- reset_config_on_routers,
- start_topology,
- kill_router_daemons,
- start_router_daemons,
- verify_rib,
- check_address_types,
- write_test_footer,
- check_router_status,
- step,
- get_frr_ipv6_linklocal,
- required_linux_kernel_version,
-)
-
-pytestmark = [pytest.mark.bgpd]
-
-
-# Global variables
-BGP_CONVERGENCE = False
-GR_RESTART_TIMER = 5
-GR_SELECT_DEFER_TIMER = 5
-GR_STALEPATH_TIMER = 5
-PREFERRED_NEXT_HOP = "link_local"
-NEXT_HOP_4 = ["192.168.1.1", "192.168.4.2"]
-NEXT_HOP_6 = ["fd00:0:0:1::1", "fd00:0:0:4::2"]
-
-
-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.16")
- 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_gr_topojson_topo2.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 deamons and then start routers
- start_topology(tgen)
-
- # Creating configuration from JSON
- build_config_from_json(tgen, topo)
-
- # Api call verify whether BGP is converged
- ADDR_TYPES = check_address_types()
-
- for addr_type in ADDR_TYPES:
- BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
- assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format(
- BGP_CONVERGENCE
- )
-
- 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)
-
-
-def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
- """
- This function groups the repetitive function calls into one function.
- """
-
- logger.info("configure_gr_followed_by_clear: dut %s peer %s", dut, peer)
-
- result = create_router_bgp(tgen, topo, input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- neighbor = topo["routers"][peer]["links"][dut][addr_type].split("/")[0]
- clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
-
- for addr_type in ADDR_TYPES:
- neighbor = topo["routers"][dut]["links"][peer][addr_type].split("/")[0]
- clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
-
- result = verify_bgp_convergence_from_running_config(tgen)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- return True
-
-
-def next_hop_per_address_family(tgen, dut, peer, addr_type, next_hop_dict):
- """
- This function returns link_local or global next_hop per address-family
- """
-
- intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
- if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
- next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
- else:
- next_hop = next_hop_dict[addr_type]
-
- return next_hop
-
-
-def test_BGP_GR_TC_1_2_p0(request):
- """
- Verify that EOR message is sent out only after initial convergence
- Verify whether EOR message is received from all the peers after restart
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "Verify EOR Sent and Received : BGP_GR_TC_1_2 >> "
- "BGP GR [Helper Mode]R3-----R1[Restart Mode] "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- "preserve-fw-state": True,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes received from router R3
- dut = "r1"
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("R1 goes for reload")
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying RIB routes
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("Starting bgpd process")
- start_router_daemons(tgen, "r1", ["bgpd"])
- logger.info("R1 is UP Now")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes received from router R3
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying EOR on restarting router
- result = verify_eor(tgen, topo, addr_type, input_dict, dut="r3", peer="r1")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_3_p0(request):
- """
- Verify the selection deferral timer functionality when EOR is not sent
- by the helper router
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Verify route download to RIB: BGP_GR_TC_3 >> "
- "BGP GR [Helper Mode]R1-----R2[Restart Mode] "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "disable-eor": True,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- },
- }
- },
- "r2": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- "preserve-fw-state": True,
- "timer": {"select-defer-time": GR_SELECT_DEFER_TIMER},
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes received from router R1
- dut = "r2"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("R2 goes for reload ")
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- logger.info("R2 is about to come up now")
- start_router_daemons(tgen, "r2", ["bgpd"])
- logger.info("R2 is UP Now")
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes received from router R1
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verify EOR on restarting router
- result = verify_eor(
- tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r2: EOR is set to True\n Error: {}".format(
- tc_name, result
- )
-
- logger.info(
- "Waiting for selection deferral timer({} sec)..".format(GR_SELECT_DEFER_TIMER)
- )
- sleep(GR_SELECT_DEFER_TIMER)
-
- for addr_type in ADDR_TYPES:
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, "r2", input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_11_p0(request):
- """
- Verify that selection-deferral timer sets the maximum time to
- avoid deadlock during which the best-path
- selection process is deferred, after a peer session was restarted
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info("Verify EOR Sent after deferral timeout : BGP_GR_TC_11")
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- "select-defer-time": GR_SELECT_DEFER_TIMER,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}},
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}},
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}},
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}},
- }
- }
- },
- },
- }
- },
- "r3": {
- "bgp": {
- "graceful-restart": {"disable-eor": True},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- },
- }
- },
- }
-
- result = create_router_bgp(tgen, topo, input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- clear_bgp(tgen, addr_type, "r1")
- clear_bgp(tgen, addr_type, "r3")
-
- result = verify_bgp_convergence_from_running_config(tgen, topo)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes received from router R1
- dut = "r1"
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("R1 goes for reload")
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("Starting bgpd process")
- start_router_daemons(tgen, "r1", ["bgpd"])
- logger.info("R1 is UP Now")
-
- for addr_type in ADDR_TYPES:
- # Verify EOR on restarting router
- result = verify_eor(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
- tc_name, result
- )
-
- logger.info(
- "Waiting for selection deferral timer({} sec).. ".format(
- GR_SELECT_DEFER_TIMER + 2
- )
- )
- sleep(GR_SELECT_DEFER_TIMER + 2)
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes received from router R1
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying EOR on restarting router
- result = verify_eor(
- tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_10_p2(request):
- """
- Test Objective : Test GR scenarios on helper router by enabling
- Graceful Restart for multiple address families.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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("Test Setup: [Helper Mode]R3-----R1[Restart Mode] initialized")
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "next_hop_self": True,
- "graceful-restart": True,
- "activate": "ipv6",
- }
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "next_hop_self": True,
- "graceful-restart": True,
- "activate": "ipv4",
- }
- }
- }
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {
- "graceful-restart-helper": True,
- "activate": "ipv6",
- }
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {
- "graceful-restart-helper": True,
- "activate": "ipv4",
- }
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- step(
- "Verifying GR config and operational state for addr_type {}".format(
- addr_type
- )
- )
-
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_topo = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv4Unicast",
- dut="r1",
- peer="r3",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv6Unicast",
- dut="r1",
- peer="r3",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv4Unicast",
- dut="r3",
- peer="r1",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv6Unicast",
- dut="r3",
- peer="r1",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- step("Killing bgpd on r1")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- input_topo = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- step("Starting bgpd on r1")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- input_topo = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def BGP_GR_16_p2(request):
- """
- Test Objective : Verify BGP-GR feature when restarting node
- is a transit router for it's iBGP peers.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Step 1] : Test Setup " "[Helper Mode]R3-----R1[Restart Mode] initialized"
- )
-
- # Configure graceful-restart and timers
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "graceful-restart": True,
- "next_hop_self": True,
- }
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "graceful-restart": True,
- "next_hop_self": True,
- }
- }
- }
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info(
- "[Step 2] : Test Setup "
- "[Helper Mode]R3-----R1[Restart Mode]"
- "--------R6[Helper Mode] initialized"
- )
-
- # Configure graceful-restart and timers
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- result = verify_bgp_convergence_from_running_config(tgen, topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_18_p1(request):
- """
- Test Objective : Verify that GR helper router deletes stale routes
- received from restarting node, if GR capability is not present in
- restarting node's OPEN message.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Step 1] : Test Setup " "[Helper Mode]R6-----R1[Restart Mode] initialized"
- )
-
- # Configure graceful-restart and timers
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r6": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r6": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r6": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r6")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r6"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info(
- "[Step 2] : Test Setup "
- "[Helper Mode]R6-----R1[Restart Mode]"
- "--------R2[Helper Mode] initialized"
- )
-
- # Configure graceful-restart and timers
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r2"
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 3] : Configure R1 to prevent sending EOR")
-
- # Modify graceful-restart config to prevent sending EOR
- input_dict_3 = {"r1": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
-
- # Modify configuration to delete routes
- network = {"ipv4": "101.0.20.1/32", "ipv6": "1::1/128"}
- for addr_type in ADDR_TYPES:
- input_dict_3 = {
- "r1": {
- "bgp": {
- "address_family": {
- addr_type: {
- "unicast": {
- "advertise_networks": [
- {
- "network": network[addr_type],
- "no_of_network": 5,
- "delete": True,
- }
- ]
- }
- }
- }
- }
- }
- }
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Modify graceful-restart config
- input_dict_3 = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-disable": True}
- }
- },
- "r6": {
- "dest_link": {
- "r1": {"graceful-restart-disable": True}
- }
- },
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-disable": True}
- }
- },
- "r6": {
- "dest_link": {
- "r1": {"graceful-restart-disable": True}
- }
- },
- }
- }
- },
- }
- }
- }
- }
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
- assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
-
- logger.info("[Step 4] : Bring up the BGPd daemon on R1 for 30" " seconds..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r6: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying BGP RIB routes
- dut = "r2"
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r2: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_26_p2(request):
- """
- Test Objective : Test GR scenarios on helper router by enabling
- Graceful Restart for multiple address families.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Step 1] : Test Setup " "[Helper Mode]R3-----R1[Restart Mode] initialized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "graceful-restart": True,
- "next_hop_self": True,
- "activate": "ipv6",
- }
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "graceful-restart": True,
- "next_hop_self": True,
- "activate": "ipv4",
- }
- }
- }
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {
- "graceful-restart-helper": True,
- "activate": "ipv6",
- }
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {
- "graceful-restart-helper": True,
- "activate": "ipv4",
- }
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r3", peer="r1"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_topo = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- input_topo = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- input_topo = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_topo)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv4Unicast",
- dut="r1",
- peer="r3",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv6Unicast",
- dut="r1",
- peer="r3",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv4Unicast",
- dut="r3",
- peer="r1",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # verify multi address family
- result = verify_gr_address_family(
- tgen,
- topo,
- addr_type,
- "ipv6Unicast",
- dut="r3",
- peer="r1",
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_28_p1(request):
- """
- Test Objective : Verify if helper node goes down before restarting
- node comes up online, helper node sets the R-bit to avoid dead-lock
- till SDT expiry.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "Test Case: test_BGP_GR_chaos_28 :"
- "[Helper Mode]R3-----R1[Restart Mode] initialized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 1] : Kill BGPd daemon on R1..")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 2] : Kill BGPd daemon on R3..")
-
- # Kill BGPd daemon on R3
- kill_router_daemons(tgen, "r3", ["bgpd"])
-
- logger.info("[Step 3] : Start BGPd daemon on R1..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 4] : Start BGPd daemon on R3..")
-
- # Start BGPd daemon on R3
- start_router_daemons(tgen, "r3", ["bgpd"])
-
- # Verify r_bit
- for addr_type in ADDR_TYPES:
- result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r3", peer="r1")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_29_p1(request):
- """
- Test Objective : Change timers on the fly, and
- verify if it takes immediate effect.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Test Case : test_BGP_GR_chaos_29"
- " BGP GR [Helper Mode]R3-----R1[Restart Mode]"
- " and [restart-time 150]R1 initialized"
- )
-
- # Configure graceful-restart and timers
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER}},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verify graceful-restart timers
- input_dict_2 = {
- "r1": {
- "bgp": {
- "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER + 5}}
- }
- }
- }
-
- result = create_router_bgp(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- input_dict_2 = {
- "r1": {
- "bgp": {
- "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER}}
- }
- }
- }
-
- result = verify_graceful_restart_timers(
- tgen, topo, addr_type, input_dict_2, dut="r3", peer="r1"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes before shutting down BGPd daemon
- dut = "r3"
- input_dict = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 2] : Kill BGPd daemon on R1..")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 3] : Wait for {} seconds..".format(GR_RESTART_TIMER))
-
- # Waiting for GR_RESTART_TIMER
- sleep(GR_RESTART_TIMER)
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes before shutting down BGPd daemon
- input_dict = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- logger.info("[Step 4] : Start BGPd daemon on R1..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_33_p1(request):
- """
- Test Objective : Helper router receives same prefixes from two
- different routers (GR-restarting and GR-disabled). Keeps the
- stale entry only for GR-restarting node(next-hop is correct).
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Test Case : test_BGP_GR_chaos_33 "
- "BGP GR "
- "[Restart Mode]R1--R3[Helper Mode]--R4[Disabled Mode]"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r4": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r4": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r4": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 2] : Advertise same networks from R1 and R4..")
-
- # Api call to delete advertised networks
- input_dict_2 = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "advertise_networks": [
- {
- "network": "200.0.20.1/32",
- "no_of_network": 2,
- }
- ]
- }
- },
- "ipv6": {
- "unicast": {
- "advertise_networks": [
- {"network": "2001::1/128", "no_of_network": 2}
- ]
- }
- },
- }
- }
- },
- "r4": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "advertise_networks": [
- {"network": "200.0.20.1/32", "no_of_network": 2}
- ]
- }
- },
- "ipv6": {
- "unicast": {
- "advertise_networks": [
- {"network": "2001::1/128", "no_of_network": 2}
- ]
- }
- },
- }
- }
- },
- }
-
- result = create_router_bgp(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- # Verifying RIB routes
- dut = "r3"
- peer1 = "r1"
- peer2 = "r4"
- intf1 = topo["routers"][peer1]["links"][dut]["interface"]
- intf2 = topo["routers"][peer2]["links"][dut]["interface"]
-
- if addr_type == "ipv4":
- next_hop_4 = NEXT_HOP_4
- result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_4)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- if addr_type == "ipv6":
- if "link_local" in PREFERRED_NEXT_HOP:
- next_hop1 = get_frr_ipv6_linklocal(tgen, peer1, intf=intf1)
- next_hop2 = get_frr_ipv6_linklocal(tgen, peer2, intf=intf2)
-
- next_hop_6 = [next_hop1, next_hop2]
- else:
- next_hop_6 = NEXT_HOP_6
-
- result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_6)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 3] : Kill BGPd daemon on R1 and R4..")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- # Kill BGPd daemon on R4
- kill_router_daemons(tgen, "r4", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying RIB routes
- next_hop_6 = ["fd00:0:0:1::1"]
- if addr_type == "ipv4":
- next_hop_4 = NEXT_HOP_4[0]
-
- result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_4)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- if addr_type == "ipv6":
- if "link_local" in PREFERRED_NEXT_HOP:
- next_hop_6 = get_frr_ipv6_linklocal(tgen, peer1, intf=intf1)
- else:
- next_hop_6 = NEXT_HOP_6[0]
-
- result = verify_rib(tgen, addr_type, dut, input_dict_2, next_hop_6)
-
- # Verifying RIB routes
- if addr_type == "ipv4":
- next_hop_4 = NEXT_HOP_4[1]
- result = verify_rib(
- tgen, addr_type, dut, input_dict_2, next_hop_4, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- if addr_type == "ipv6":
- if "link_local" in PREFERRED_NEXT_HOP:
- next_hop_6 = get_frr_ipv6_linklocal(tgen, peer2, intf=intf2)
- else:
- next_hop_6 = NEXT_HOP_6[1]
-
- result = verify_rib(
- tgen, addr_type, dut, input_dict_2, next_hop_6, expected=False
- )
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in ZEBRA\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- logger.info("[Step 4] : Start BGPd daemon on R1 and R4..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- # Start BGPd daemon on R4
- start_router_daemons(tgen, "r4", ["bgpd"])
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_34_2_p1(request):
- """
- Test Objective : Restarting node doesn't preserve the forwarding
- state verify the behaviour on helper node, if it still keeps the
- stale routes.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Test Case : test_BGP_GR_chaos_34 "
- "BGP GR "
- "[Restart Mode]R1---R3[Helper Mode]"
- )
-
- logger.info("[Step 1] : Configure restarting" " router R1 to prevent ")
- logger.info("[Step 2] : Reset the session" " between R1 and R3..")
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {"preserve-fw-state": True, "disable-eor": True},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verify f-bit before killing BGPd daemon
- result = verify_f_bit(tgen, topo, addr_type, input_dict, "r3", "r1")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes after starting BGPd daemon
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 3] : Kill BGPd daemon on R1..")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 4] : Withdraw/delete the prefixes " "originated from R1..")
-
- # Api call to delete advertised networks
- network = {"ipv4": "101.0.20.1/32", "ipv6": "1::1/128"}
- for addr_type in ADDR_TYPES:
- input_dict_2 = {
- "r1": {
- "bgp": {
- "address_family": {
- addr_type: {
- "unicast": {
- "advertise_networks": [
- {
- "network": network[addr_type],
- "no_of_network": 5,
- "delete": True,
- }
- ]
- }
- }
- }
- }
- }
- }
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 5] : Remove the CLI from R1's config to " "set the F-bit..")
-
- # Modify graceful-restart config not to set f-bit
- # and write to /etc/frr
- input_dict_2 = {"r1": {"bgp": {"graceful-restart": {"preserve-fw-state": False}}}}
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
-
- logger.info("[Step 6] : Bring up the BGPd daemon on R1 again..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verify f-bit after starting BGPd daemon
- result = verify_f_bit(
- tgen, topo, addr_type, input_dict, "r3", "r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format(
- tc_name, result
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying BGP RIB routes after starting BGPd daemon
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_34_1_p1(request):
- """
- Test Objective : Restarting node doesn't preserve forwarding
- state, helper router should not keep the stale entries.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Test Case : test_BGP_GR_chaos_31 "
- "BGP GR "
- "[Restart Mode]R1---R3[Helper Mode]"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {
- "preserve-fw-state": True,
- "timer": {"restart-time": GR_RESTART_TIMER},
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes after starting BGPd daemon
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info(
- "[Step 1] : Remove the preserve-fw-state command"
- " from restarting node R1's config"
- )
-
- # Configure graceful-restart to set f-bit as False
- input_dict_2 = {"r1": {"bgp": {"graceful-restart": {"preserve-fw-state": False}}}}
-
- result = create_router_bgp(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- logger.info("[Step 2] : Reset the session between R1 and R3..")
-
- # Reset sessions
- for addr_type in ADDR_TYPES:
- clear_bgp(tgen, addr_type, "r1")
-
- result = verify_bgp_convergence_from_running_config(tgen, topo)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- for addr_type in ADDR_TYPES:
- # Verify f-bit after starting BGPd daemon
- result = verify_f_bit(
- tgen, topo, addr_type, input_dict_2, "r3", "r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format(
- tc_name, result
- )
- logger.info(" Expected behavior: {}".format(result))
-
- logger.info("[Step 3] : Kill BGPd daemon on R1..")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- # Waiting for GR_RESTART_TIMER
- logger.info("Waiting for {} sec..".format(GR_RESTART_TIMER))
- sleep(GR_RESTART_TIMER)
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- input_dict = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_32_p1(request):
- """
- Test Objective : Restarting node is connected to multiple helper
- nodes, one of them doesn't send EOR to restarting router. Verify
- that only after SDT restarting node send EOR to all helper peers
- excluding the prefixes originated by faulty router.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Test Case : test_BGP_GR_chaos_32 "
- "BGP GR "
- "[Restart Mode]R1---R3&R5[Helper Mode]"
- )
-
- logger.info(
- "[Step 1] : Change the mode on R1 be a restarting" " node on global level"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {"graceful-restart": True},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"next_hop_self": True}}},
- "r5": {"dest_link": {"r1": {"graceful-restart": True}}},
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"next_hop_self": True}}},
- "r5": {"dest_link": {"r1": {"graceful-restart": True}}},
- }
- }
- },
- },
- }
- },
- "r5": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r5": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r5": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r5")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r5"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes after starting BGPd daemon
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r5"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 2] : Kill BGPd daemon on R1..")
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 3] : Withdraw all the advertised prefixes from R5")
-
- # Api call to delete advertised networks
- network = {"ipv4": "105.0.20.1/32", "ipv6": "5::1/128"}
- for addr_type in ADDR_TYPES:
- input_dict_2 = {
- "r5": {
- "bgp": {
- "address_family": {
- addr_type: {
- "unicast": {
- "advertise_networks": [
- {
- "network": network[addr_type],
- "no_of_network": 5,
- "delete": True,
- }
- ]
- }
- }
- }
- }
- }
- }
-
- result = create_router_bgp(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(
- tc_name, result
- )
-
- logger.info(
- "[Step 4] : Stop the helper router R5 from sending EOR" " message using CLI"
- )
-
- # Modify graceful-restart config to prevent sending EOR
- input_dict_3 = {"r5": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
-
- result = create_router_bgp(tgen, topo, input_dict_3)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- logger.info("[Step 5] : Bring up the BGPd daemon on R1..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verify EOR is disabled
- result = verify_eor(
- tgen, topo, addr_type, input_dict_3, dut="r5", peer="r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r5: EOR is set to TRUE\n Error: {}".format(
- tc_name, result
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying BGP RIB routes after starting BGPd daemon
- input_dict_1 = {key: topo["routers"][key] for key in ["r5"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_37_p1(request):
- """
- Test Objective : Verify if helper node restarts before sending the
- EOR message, restarting node doesn't wait until stale path timer
- expiry to do the best path selection and sends an EOR
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Test Case : test_BGP_GR_chaos_37 "
- "BGP GR "
- "[Restart Mode]R1---R3[Helper Mode]"
- )
-
- logger.info(
- "[Step 1] : Configure restarting router R3 to prevent " "sending an EOR.."
- )
-
- logger.info("[Step 2] : Reset the session between R3 and R1..")
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "graceful-restart": {"disable-eor": True},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- },
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verify EOR is disabled
- result = verify_eor(
- tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format(
- tc_name, result
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying BGP RIB routes after starting BGPd daemon
- dut = "r1"
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 3] : Kill BGPd daemon on R1..")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 4] : Start BGPd daemon on R1..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 5] : Kill BGPd daemon on R3..")
-
- # Kill BGPd daemon on R3
- kill_router_daemons(tgen, "r3", ["bgpd"])
-
- # Modify graceful-restart config to prevent sending EOR
- input_dict_2 = {"r3": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
-
- logger.info("[Step 6] : Start BGPd daemon on R3..")
-
- # Start BGPd daemon on R3
- start_router_daemons(tgen, "r3", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verify r_bit
- result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r3")
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verify EOR is send from R1 to R3
- input_dict_3 = {"r1": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
-
- result = verify_eor(
- tgen, topo, addr_type, input_dict_3, dut="r1", peer="r3", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
- tc_name, result
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_chaos_30_p1(request):
- """
- Test Objective : Restarting node removes stale routes from Zebra
- after receiving an EOR from helper router.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Test Case : test_BGP_GR_chaos_30 "
- "BGP GR [Helper Mode]R3-----R1[Restart Mode] "
- )
-
- # Configure graceful-restart and timers
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {"preserve-fw-state": True},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes before shutting down BGPd daemon
- dut = "r1"
- input_dict = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict)
- assert result is True, "Testcase {} : Failed \n Error {}".format(
- tc_name, result
- )
-
- logger.info("[Step 2] : Kill BGPd daemon on R1..")
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- logger.info("[Step 3] : Withdraw advertised prefixes from R3...")
-
- # Api call to delete advertised networks
- network = {"ipv4": "103.0.20.1/32", "ipv6": "3::1/128"}
- for addr_type in ADDR_TYPES:
- input_dict = {
- "r3": {
- "bgp": {
- "address_family": {
- addr_type: {
- "unicast": {
- "advertise_networks": [
- {
- "network": network[addr_type],
- "no_of_network": 5,
- "delete": True,
- }
- ]
- }
- }
- }
- }
- }
- }
-
- result = create_router_bgp(tgen, topo, input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(
- tc_name, result
- )
-
- logger.info("[Step 4] : Start BGPd daemon on R1..")
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes before shutting down BGPd daemon
- input_dict = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_15_p2(request):
- """
- Test Objective : Test GR scenarios by enabling Graceful Restart
- for multiple address families..
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r6": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r6": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r6": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r6": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r6")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r6"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- logger.info(
- "[Step 2] : Test Setup "
- "[Helper Mode]R6-----R1[Restart Mode]"
- "--------R2[Helper Mode] Initilized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- }
- }
- },
- "r2": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r2": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- result = verify_bgp_convergence(tgen, topo)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- write_test_footer(tc_name)
-
-
-def BGP_GR_TC_7_p1(request):
- """
- Verify that BGP restarting node deletes all the routes received from peer
- if BGP Graceful capability is not present in BGP Open message from the
- peer
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- " Verify route download to RIB: BGP_GR_TC_7 >> "
- "BGP GR [Helper Mode]R3-----R1[Restart Mode] "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r1": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- "preserve-fw-state": True,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes received from router R1
- dut = "r1"
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- logger.info("R1 goes for reload")
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- # Change the configuration on router R1
- input_dict_2 = {
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- }
- }
- }
- }
-
- result = create_router_bgp(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-
- # Change the configuration on R1
- network = {"ipv4": "103.0.20.1/32", "ipv6": "3::1/128"}
- for addr_type in ADDR_TYPES:
- input_dict_2 = {
- "r3": {
- "bgp": {
- "address_family": {
- addr_type: {
- "unicast": {
- "advertise_networks": [
- {
- "network": network[addr_type],
- "no_of_network": 5,
- "delete": True,
- }
- ]
- }
- }
- }
- }
- }
- }
-
- result = create_router_bgp(tgen, topo, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- logger.info("R1 is about to come up now")
- start_router_daemons(tgen, "r1", ["bgpd"])
- logger.info("R1 is UP Now")
-
- # Wait for RIB stale timeout
- logger.info("Verify routes are not present" "in restart router")
-
- for addr_type in ADDR_TYPES:
- # Verifying RIB routes
- dut = "r1"
- input_dict_1 = {key: topo["routers"][key] for key in ["r3"]}
- result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_TC_23_p1(request):
- """
- Verify that helper routers are deleting stale routes after stale route
- timer's expiry. If all the routes are not received from restating node
- after restart.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "Verify Stale Routes are deleted on helper: BGP_GR_TC_23 >> "
- "BGP GR [Helper Mode]R1-----R2[Restart Mode] "
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "graceful-restart": {"timer": {"stalepath-time": GR_STALEPATH_TIMER}},
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- },
- }
- },
- "r2": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- "preserve-fw-state": True,
- },
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {"dest_link": {"r2": {"graceful-restart": True}}}
- }
- }
- },
- },
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes received from router R1
- dut = "r1"
- input_dict_1 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- logger.info("R2 goes for reload")
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- # Modify configuration to delete routes and include disable-eor
- input_dict_3 = {"r2": {"bgp": {"graceful-restart": {"disable-eor": True}}}}
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
-
- # Modify configuration to delete routes and include disable-eor
- network = {"ipv4": "102.0.20.1/32", "ipv6": "2::1/128"}
- for addr_type in ADDR_TYPES:
- input_dict_3 = {
- "r2": {
- "bgp": {
- "address_family": {
- addr_type: {
- "unicast": {
- "advertise_networks": [
- {
- "network": network[addr_type],
- "no_of_network": 3,
- "delete": True,
- }
- ]
- }
- }
- }
- }
- }
- }
-
- result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_3)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- logger.info("BGPd comes up for r2")
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- # Wait for stalepath timer
- logger.info("Waiting for stalepath timer({} sec..)".format(GR_STALEPATH_TIMER))
- sleep(GR_STALEPATH_TIMER)
-
- for addr_type in ADDR_TYPES:
- clear_bgp(tgen, addr_type, "r2")
-
- # Verifying RIB routes
- dut = "r1"
- network = {"ipv4": "102.0.20.4/32", "ipv6": "2::4/128"}
- for addr_type in ADDR_TYPES:
- input_dict_1 = {
- "r1": {
- "bgp": {
- "address_family": {
- addr_type: {
- "unicast": {
- "advertise_networks": [
- {"network": network[addr_type], "no_of_network": 2}
- ]
- }
- }
- }
- }
- }
- }
-
- # Verify EOR on helper router
- result = verify_eor(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False
- )
- assert (
- result is not True
- ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
- tc_name, result
- )
-
- # Verifying BGP RIB routes received from router R1
- dut = "r1"
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_20_p1(request):
- """
- Test Objective : Verify that GR routers delete all the routes
- received from a node if both the routers are configured as GR
- helper node
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Step 1] : Test Setup " "[Restart Mode]R3-----R1[Restart Mode] Initilized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in BGP RIB\n Error: {}".format(
- tc_name, result
- )
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
- )
- logger.info(" Expected behavior: {}".format(result))
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r1", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- result = verify_bgp_convergence(tgen, topo)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_21_p2(request):
- """
- Test Objective : VVerify BGP-GR feature when helper node is
- a transit router for it's eBGP peers.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Step 1] : Test Setup " "[Helper Mode]R6-----R1[Restart Mode] Initilized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r6": {
- "dest_link": {
- "r1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r6": {
- "dest_link": {
- "r1": {"graceful-restart-disable": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r6": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r6": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r6": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r6")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r6"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- logger.info(
- "[Step 2] : Test Setup "
- "[Restart Mode]R2-----[Helper Mode]R1[Disable Mode]"
- "--------R6[Helper Mode] Initilized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r2": {
- "bgp": {
- "graceful-restart": {
- "graceful-restart": True,
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- result = verify_bgp_convergence(tgen, topo)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes after bringing up BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r6"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- write_test_footer(tc_name)
-
-
-def test_BGP_GR_22_p2(request):
- """
- Test Objective : Verify BGP-GR feature when helper node
- is a transit router for it's iBGP peers.
- """
-
- tgen = get_topogen()
- tc_name = request.node.name
- write_test_header(tc_name)
-
- # Check router status
- check_router_status(tgen)
-
- # 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)
-
- logger.info(
- "[Step 1] : Test Setup " "[Helper Mode]R3-----R1[Restart Mode] Initilized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "graceful-restart-disable": True,
- "next_hop_self": True,
- }
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r1": {
- "graceful-restart-disable": True,
- "next_hop_self": True,
- }
- }
- }
- }
- }
- },
- }
- }
- },
- "r3": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r1": {
- "dest_link": {
- "r3": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r3"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- logger.info(
- "[Step 2] : Test Setup "
- "[Restart Mode]R2-----[Helper Mode]R1[Disable Mode]"
- "--------R3[Helper Mode] Initilized"
- )
-
- # Configure graceful-restart
- input_dict = {
- "r1": {
- "bgp": {
- "address_family": {
- "ipv4": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- "ipv6": {
- "unicast": {
- "neighbor": {
- "r2": {
- "dest_link": {
- "r1": {"graceful-restart-helper": True}
- }
- }
- }
- }
- },
- }
- }
- },
- "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}},
- }
-
- configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
-
- for addr_type in ADDR_TYPES:
- result = verify_graceful_restart(
- tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
- )
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Kill BGPd daemon on R1
- kill_router_daemons(tgen, "r2", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Start BGPd daemon on R1
- start_router_daemons(tgen, "r2", ["bgpd"])
-
- for addr_type in ADDR_TYPES:
- result = verify_bgp_convergence(tgen, topo)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_1)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying BGP RIB routes
- dut = "r3"
- input_dict_2 = {key: topo["routers"][key] for key in ["r2"]}
- result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Verifying RIB routes before shutting down BGPd daemon
- result = verify_rib(tgen, addr_type, dut, input_dict_2)
- assert result is True, "Testcase {} :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/isis_topo1_vrf/test_isis_topo1_vrf.py b/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py
index a0cae0a40b..ff9ad6150a 100644
--- a/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py
+++ b/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py
@@ -175,11 +175,19 @@ def test_isis_route_installation():
for rname, router in tgen.routers().items():
filename = "{0}/{1}/{1}_route.json".format(CWD, rname)
expected = json.loads(open(filename, "r").read())
- actual = router.vtysh_cmd(
- "show ip route vrf {0}-cust1 json".format(rname), isjson=True
- )
- assertmsg = "Router '{}' routes mismatch".format(rname)
- assert topotest.json_cmp(actual, expected) is None, assertmsg
+
+ def compare_routing_table(router, expected):
+ "Helper function to ensure zebra rib convergence"
+
+ actual = router.vtysh_cmd(
+ "show ip route vrf {0}-cust1 json".format(rname), isjson=True
+ )
+ return topotest.json_cmp(actual, expected)
+
+ test_func = functools.partial(compare_routing_table, router, expected)
+ (result, diff) = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ assertmsg = "Router '{}' routes mismatch diff: {}".format(rname, diff)
+ assert result, assertmsg
def test_isis_linux_route_installation():
@@ -220,12 +228,18 @@ def test_isis_route6_installation():
for rname, router in tgen.routers().items():
filename = "{0}/{1}/{1}_route6.json".format(CWD, rname)
expected = json.loads(open(filename, "r").read())
- actual = router.vtysh_cmd(
- "show ipv6 route vrf {}-cust1 json".format(rname), isjson=True
- )
- assertmsg = "Router '{}' routes mismatch".format(rname)
- assert topotest.json_cmp(actual, expected) is None, assertmsg
+ def compare_routing_table(router, expected):
+ "Helper function to ensure zebra rib convergence"
+ actual = router.vtysh_cmd(
+ "show ipv6 route vrf {}-cust1 json".format(rname), isjson=True
+ )
+ return topotest.json_cmp(actual, expected)
+
+ test_func = functools.partial(compare_routing_table, router, expected)
+ (result, diff) = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ assertmsg = "Router '{}' routes mismatch diff: ".format(rname, diff)
+ assert result, assertmsg
def test_isis_linux_route6_installation():
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index cf8efdea16..c744e5bbbf 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -26,6 +26,7 @@ import socket
import subprocess
import sys
import traceback
+import functools
from collections import OrderedDict
from copy import deepcopy
from datetime import datetime, timedelta
@@ -2970,24 +2971,34 @@ def addKernelRoute(
logger.info("[DUT: {}]: Running command: [{}]".format(router, cmd))
output = rnode.run(cmd)
- # Verifying if ip route added to kernal
- result = rnode.run(verify_cmd)
- logger.debug("{}\n{}".format(verify_cmd, result))
- if "/" in grp_addr:
- ip, mask = grp_addr.split("/")
- if mask == "32" or mask == "128":
- grp_addr = ip
- else:
- mask = "32" if addr_type == "ipv4" else "128"
+ def check_in_kernel(rnode, verify_cmd, grp_addr, router):
+ # Verifying if ip route added to kernal
+ errormsg = None
+ result = rnode.run(verify_cmd)
+ logger.debug("{}\n{}".format(verify_cmd, result))
+ if "/" in grp_addr:
+ ip, mask = grp_addr.split("/")
+ if mask == "32" or mask == "128":
+ grp_addr = ip
+ else:
+ mask = "32" if addr_type == "ipv4" else "128"
- if not re_search(r"{}".format(grp_addr), result) and mask != "0":
- errormsg = (
- "[DUT: {}]: Kernal route is not added for group"
- " address {} Config output: {}".format(router, grp_addr, output)
- )
+ if not re_search(r"{}".format(grp_addr), result) and mask != "0":
+ errormsg = (
+ "[DUT: {}]: Kernal route is not added for group"
+ " address {} Config output: {}".format(
+ router, grp_addr, output
+ )
+ )
return errormsg
+ test_func = functools.partial(
+ check_in_kernel, rnode, verify_cmd, grp_addr, router
+ )
+ (result, out) = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ assert result, out
+
logger.debug("Exiting lib API: addKernelRoute()")
return True
diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py
index 52872ae1a1..92d29ad1ab 100644
--- a/tests/topotests/lib/ospf.py
+++ b/tests/topotests/lib/ospf.py
@@ -782,6 +782,16 @@ def verify_ospf6_neighbor(tgen, topo=None, dut=None, input_dict=None, lan=False)
}
result = verify_ospf6_neighbor(tgen, topo, dut, input_dict, lan=True)
+ 3. To check there are no neighbors.
+ input_dict = {
+ "r0": {
+ "ospf6": {
+ "neighbors": []
+ }
+ }
+ }
+ result = verify_ospf6_neighbor(tgen, topo, dut, input_dict)
+
Returns
-------
True or False (Error Message)
@@ -812,6 +822,19 @@ def verify_ospf6_neighbor(tgen, topo=None, dut=None, input_dict=None, lan=False)
ospf_data_list = input_dict[router]["ospf6"]
ospf_nbr_list = ospf_data_list["neighbors"]
+ # Check if looking for no neighbors
+ if ospf_nbr_list == []:
+ if show_ospf_json["neighbors"] == []:
+ logger.info("[DUT: {}] OSPF6 no neighbors found".format(router))
+ return True
+ else:
+ errormsg = (
+ "[DUT: {}] OSPF6 active neighbors found, expected None".format(
+ router
+ )
+ )
+ return errormsg
+
for ospf_nbr, nbr_data in ospf_nbr_list.items():
try:
diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py
index 944981add4..dd2f787014 100644
--- a/tests/topotests/lib/pim.py
+++ b/tests/topotests/lib/pim.py
@@ -21,8 +21,10 @@ import os
import re
import sys
import traceback
+import functools
from copy import deepcopy
from time import sleep
+from lib import topotest
# Import common_config to use commomnly used APIs
@@ -1481,24 +1483,34 @@ def verify_pim_interface_traffic(tgen, input_dict):
rnode = tgen.routers()[dut]
logger.info("[DUT: %s]: Verifying pim interface traffic", dut)
- show_pim_intf_traffic_json = run_frr_cmd(
- rnode, "show ip pim interface traffic json", isjson=True
- )
- output_dict[dut] = {}
- for intf, data in input_dict[dut].items():
- interface_json = show_pim_intf_traffic_json[intf]
- for state in data:
+ def show_pim_intf_traffic(rnode, dut, input_dict, output_dict):
+ show_pim_intf_traffic_json = run_frr_cmd(
+ rnode, "show ip pim interface traffic json", isjson=True
+ )
- # Verify Tx/Rx
- if state in interface_json:
- output_dict[dut][state] = interface_json[state]
- else:
- errormsg = (
- "[DUT %s]: %s is not present"
- "for interface %s [FAILED]!! " % (dut, state, intf)
- )
- return errormsg
+ output_dict[dut] = {}
+ for intf, data in input_dict[dut].items():
+ interface_json = show_pim_intf_traffic_json[intf]
+ for state in data:
+
+ # Verify Tx/Rx
+ if state in interface_json:
+ output_dict[dut][state] = interface_json[state]
+ else:
+ errormsg = (
+ "[DUT %s]: %s is not present"
+ "for interface %s [FAILED]!! " % (dut, state, intf)
+ )
+ return errormsg
+ return None
+
+ test_func = functools.partial(
+ show_pim_intf_traffic, rnode, dut, input_dict, output_dict
+ )
+ (result, out) = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ if not result:
+ return out
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
return output_dict
diff --git a/tests/topotests/ospfv3_basic_functionality/ospfv3_nssa.json b/tests/topotests/ospfv3_basic_functionality/ospfv3_nssa.json
new file mode 100644
index 0000000000..2b91abc9e3
--- /dev/null
+++ b/tests/topotests/ospfv3_basic_functionality/ospfv3_nssa.json
@@ -0,0 +1,86 @@
+{
+ "address_types": [
+ "ipv6"
+ ],
+ "lo_prefix": {
+ "ipv6": "2001::",
+ "v6mask": 128
+ },
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2": {
+ "ipv6": "12::1/64",
+ "ospf6": {
+ "area": "0.0.0.0",
+ "hello_interval": 1,
+ "dead_interval": 4
+ }
+ }
+ },
+ "ospf6": {
+ "router_id": "1.1.1.1",
+ "neighbors": {
+ "r2": {}
+ }
+ }
+ },
+ "r2": {
+ "links": {
+ "lo": {
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1": {
+ "ipv6": "12::2/64",
+ "ospf6": {
+ "area": "0.0.0.0",
+ "hello_interval": 1,
+ "dead_interval": 4
+ }
+ },
+ "r3": {
+ "ipv6": "23::2/64",
+ "ospf6": {
+ "area": "1.1.1.1",
+ "hello_interval": 1,
+ "dead_interval": 4
+ }
+ }
+ },
+ "ospf6": {
+ "router_id": "2.2.2.2",
+ "neighbors": {
+ "r1": {},
+ "r3": {}
+ }
+ }
+ },
+ "r3": {
+ "links": {
+ "lo": {
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2": {
+ "ipv6": "23::3/64",
+ "ospf6": {
+ "area": "1.1.1.1",
+ "hello_interval": 1,
+ "dead_interval": 4
+ }
+ }
+ },
+ "ospf6": {
+ "router_id": "3.3.3.3",
+ "neighbors": {
+ "r2": {}
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py
new file mode 100644
index 0000000000..64a067cd1a
--- /dev/null
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py
@@ -0,0 +1,162 @@
+#!/usr/bin/python
+
+from lib.topogen import Topogen, get_topogen
+from lib.common_config import (
+ start_topology,
+ write_test_header,
+ write_test_footer,
+ reset_config_on_routers,
+ step,
+ topo_daemons,
+)
+from lib.topolog import logger
+from lib.topojson import build_config_from_json
+from lib.ospf import create_router_ospf, verify_ospf6_neighbor
+import os
+import sys
+import time
+import pytest
+
+# 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
+
+pytestmark = [pytest.mark.ospfd]
+
+
+# Global variables
+topo = None
+
+"""
+TOPOOLOGY
+
+ +---+ 0.0.0.0 +---+ 1.1.1.1 +---+
+ +R1 +------------+R2 |------------+R3 |
+ +-+-+ +--++ +--++
+
+TESTCASES =
+1. OSPF Verify E-bit mismatch between R2 and R3
+2. OSPF Verify N-bit mismatch between R2 and R3
+"""
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+ 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 = "{}/ospfv3_nssa.json".format(CWD)
+ tgen = Topogen(json_file, mod.__name__)
+ global topo
+ topo = tgen.json_topo
+ # ... and here it calls Mininet initialization functions.
+
+ # get list of daemons needs to be started for this suite.
+ daemons = topo_daemons(tgen, topo)
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen, daemons)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ result = verify_ospf6_neighbor(tgen, topo)
+ assert result is True, "setup_module: Failed \n Error:" " {}".format(result)
+
+ 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)
+
+
+# ##################################
+# Test cases start here.
+# ##################################
+
+
+def test_ospfv3_bit_mismatch(request):
+ """OSPF verify E-bit and N-bit mismatch."""
+
+ 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)
+
+ global topo
+ step("Bring up the base config as per the topology")
+ reset_config_on_routers(tgen)
+
+ input_dict = {"r3": {"ospf6": {"neighbors": []}}}
+
+ step("Configure r3 as stub router")
+ stub = {"r3": {"ospf6": {"area": [{"id": "1.1.1.1", "type": "stub"}]}}}
+ result = create_router_ospf(tgen, topo, stub)
+ assert result is True, "Testcase {}: Failed \n Error: {}".format(tc_name, result)
+ # Verify r3 lost its adjacency with r2 due to E-bit mismatch
+ result = verify_ospf6_neighbor(tgen, topo, dut="r3", input_dict=input_dict)
+ assert result is True, "Testcase {}: Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure r2 as stub router")
+ stub = {"r2": {"ospf6": {"area": [{"id": "1.1.1.1", "type": "stub"}]}}}
+ result = create_router_ospf(tgen, topo, stub)
+ assert result is True, "Testcase {}: Failed \n Error: {}".format(tc_name, result)
+ # Verify r3 has an adjacency up with r2 again
+ result = verify_ospf6_neighbor(tgen, topo, dut="r3")
+ assert result is True, "Testcase {}: Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure r3 as NSSA router")
+ nssa = {"r3": {"ospf6": {"area": [{"id": "1.1.1.1", "type": "nssa"}]}}}
+ result = create_router_ospf(tgen, topo, nssa)
+ # Verify r3 lost its adjacency with r2 due to N-bit mismatch
+ result = verify_ospf6_neighbor(tgen, topo, dut="r3", input_dict=input_dict)
+ assert result is True, "Testcase {}: Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure r2 as NSSA router")
+ nssa = {"r2": {"ospf6": {"area": [{"id": "1.1.1.1", "type": "nssa"}]}}}
+ result = create_router_ospf(tgen, topo, nssa)
+ # Verify r3 has an adjacency up with r2 again
+ result = verify_ospf6_neighbor(tgen, topo, dut="r3")
+ assert result is True, "Testcase {}: 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))