From e83a52698b31fde2532b4a5a8c5223ba5e858ef2 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 19 May 2022 15:09:46 +0200 Subject: [PATCH] topotests: isis-tilfa add a switchover test after BFD down Add a switchover test that consists in: - Setting up ISIS BFD between rt5 and rt6 - Setting no link-detect on rt6 eth-rt5 so that zebra does not take account linkdown events on this interface. - Shutting down rt6 eth-rt5 from the switch side Check that the switchover between primary and backup happens before the SPF re-computation. Signed-off-by: Louis Scalbert --- .../topotests/isis_tilfa_topo1/rt5/bfdd.conf | 14 ++ .../topotests/isis_tilfa_topo1/rt6/bfdd.conf | 14 ++ .../isis_tilfa_topo1/test_isis_tilfa_topo1.py | 207 +++++++++++++++++- 3 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf diff --git a/tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf b/tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf new file mode 100644 index 0000000000..d27625ff35 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/bfdd.conf @@ -0,0 +1,14 @@ +hostname rt5 +! +#debug bfd network +#debug bfd peer +#debug bfd zebra +! +bfd + peer 10.0.8.6 interface eth-rt6 + detect-multiplier 3 + receive-interval 300 + transmit-interval 300 + no shutdown + ! +! \ No newline at end of file diff --git a/tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf b/tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf new file mode 100644 index 0000000000..0c8ba7268c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/bfdd.conf @@ -0,0 +1,14 @@ +hostname rt6 +! +#debug bfd network +#debug bfd peer +#debug bfd zebra +! +bfd + peer 10.0.8.5 interface eth-rt5 + detect-multiplier 3 + receive-interval 300 + transmit-interval 300 + no shutdown + ! +! \ No newline at end of file diff --git a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py index 171a36d3e7..3f34a87793 100755 --- a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py +++ b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py @@ -188,6 +188,9 @@ def setup_module(mod): router.load_config( TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) ) + router.load_config( + TopoRouter.RD_BFD, os.path.join(CWD, "/dev/null".format(rname)) + ) tgen.start_router() @@ -200,7 +203,7 @@ def teardown_module(mod): tgen.stop_topology() -def router_compare_json_output(rname, command, reference, count=120): +def router_compare_json_output(rname, command, reference, count=120, wait=0.5): "Compare router JSON output" logger.info('Comparing router "%s" "%s" output', rname, command) @@ -210,7 +213,7 @@ def router_compare_json_output(rname, command, reference, count=120): # Run test function until we get an result. Wait at most 60 seconds. test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) - _, diff = topotest.run_and_expect(test_func, None, count=count, wait=0.5) + _, diff = topotest.run_and_expect(test_func, None, count=count, wait=wait) assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) assert diff is None, assertmsg @@ -901,6 +904,206 @@ def test_mpls_lib_step12(): ) +# +# Step 13 +# +# Action(s): +# - shut / unshut a rt6 interface +# - Setup BFD +# +# Expected changes: +# - All route tables go back to previous state situation +# - At the end of test, next SPF is scheduled in approximatively 15s +# +def test_rib_ipv4_step13(): + logger.info("Test (step 13): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Unsetting spf-delay-ietf init-delay of 15s") + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "router isis 1" -c "no spf-delay-ietf"') + + logger.info( + "Unshut the rt6 interface to rt5 from the switch side and check fast-reroute" + ) + tgen.net.cmd_raises("ip link set %s up" % tgen.net["s8"].intfs[1]) + + logger.info("Setup BFD on rt5 and rt6") + for rname in ["rt5", "rt6"]: + conf_file = os.path.join(CWD, "{}/bfdd.conf".format(rname)) + tgen.net[rname].cmd("vtysh -f {}".format(conf_file)) + + expect = ( + '[{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"up"}]' + ) + router_compare_json_output("rt6", "show bfd peers json", expect) + + logger.info("Unset link-detect on rt6 eth-rt5") + # Unset link detection. We want zebra to consider linkdow as operationaly up + # in order that BFD triggers LFA instead of the interface down + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "int eth-rt5" -c "no link-detect"') + + # reset spf-interval + logger.info("Shut/unshut a rt6 eth-rt5 interface and set spf-interval to 15s") + tgen.net["rt6"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"' + ) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"] + ) + + logger.info("Set ISIS BFD") + tgen.net["rt5"].cmd('vtysh -c "conf t" -c "int eth-rt6" -c "isis bfd"') + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "int eth-rt5" -c "isis bfd"') + + +def test_rib_ipv6_step13(): + logger.info("Test (step 13): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show ipv6 route isis json", + outputs[rname][10]["show_ipv6_route.ref"], + ) + + +def test_mpls_lib_step13(): + logger.info("Test (step 13): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show mpls table json", outputs[rname][10]["show_mpls_table.ref"] + ) + + +# +# Step 14 +# +# Action(s): +# - shut the eth-rt5 interface on rt6 +# +# Expected changes: +# - Route switchover of routes via eth-rt5 +# +def test_rt6_step14(): + logger.info("Test (step 14): verify IPv4/6 RIB and MPLS table") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info( + "Shut a rt6 interface to rt5 from the switch side and check fast-reroute" + ) + tgen.net.cmd_raises("ip link set %s down" % tgen.net["s8"].intfs[1]) + + rname = "rt6" + + expect = ( + '[{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"down"}]' + ) + router_compare_json_output( + rname, + "show bfd peers json", + expect, + count=20, + wait=0.05, + ) + + router_compare_json_output( + rname, + "show ip route isis json", + outputs[rname][11]["show_ip_route.ref"], + count=1, + ) + router_compare_json_output( + rname, + "show ipv6 route isis json", + outputs[rname][11]["show_ipv6_route.ref"], + count=1, + ) + router_compare_json_output( + rname, + "show mpls table json", + outputs[rname][11]["show_mpls_table.ref"], + count=1, + ) + + +# +# Step 15 +# +# Action(s): wait for the convergence and SPF computation on rt6 +# +# Expected changes: +# - convergence of IPv4/6 RIB and MPLS table +# +def test_rib_ipv4_step15(): + logger.info("Test (step 15): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Check SPF convergence") + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show ip route isis json", + outputs[rname][12]["show_ip_route.ref"], + ) + + +def test_rib_ipv6_step15(): + logger.info("Test (step 15): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show ipv6 route isis json", + outputs[rname][12]["show_ipv6_route.ref"], + ) + + +def test_mpls_lib_step15(): + logger.info("Test (step 15): verify MPLS LIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show mpls table json", + outputs[rname][12]["show_mpls_table.ref"], + ) + + # Memory leak test template def test_memory_leak(): "Run the memory leak test and report results." -- 2.39.5