summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsabella de Leon <ideleon@microsoft.com>2022-10-12 10:52:27 -0700
committerIsabella de Leon <ideleon@microsoft.com>2022-10-12 10:52:27 -0700
commit4afc783610548a47bcc115ce7f5b893658fffd1d (patch)
tree6437448dd6330165a5dc6320e845b656d316466b
parent910dab7c301694b5331ff91f00e0cdbbfbe31961 (diff)
isisd: Add expected behavior with set-overload-bit
Signed-off-by: Isabella de Leon <ideleon@microsoft.com>
-rw-r--r--doc/user/isisd.rst2
-rw-r--r--isisd/isis_lsp.c5
-rw-r--r--isisd/isis_nb_config.c2
-rw-r--r--isisd/isisd.c10
-rw-r--r--isisd/isisd.h1
-rw-r--r--tests/topotests/isis_topo1/test_isis_topo1.py119
6 files changed, 135 insertions, 4 deletions
diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst
index 8f9afd3135..2b114ad127 100644
--- a/doc/user/isisd.rst
+++ b/doc/user/isisd.rst
@@ -85,7 +85,7 @@ writing, *isisd* does not support multiple ISIS processes.
.. clicmd:: set-overload-bit on-startup (0-86400)
- Set overload bit on startup for the specified duration, in seconds.
+ Set overload bit on startup for the specified duration, in seconds. Reference: :rfc:`3277`
.. clicmd:: purge-originator
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index fbf559713f..2dc6f15c79 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -448,7 +448,10 @@ void set_overload_on_start_timer(struct thread *thread)
assert(area);
area->t_overload_on_startup_timer = NULL;
- isis_area_overload_bit_set(area, false);
+
+ /* Check if set-overload-bit is not currently configured */
+ if (!area->overload_configured)
+ isis_area_overload_bit_set(area, false);
}
static void isis_reset_attach_bit(struct isis_adjacency *adj)
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 14a66d2568..214209e647 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -350,6 +350,8 @@ int isis_instance_overload_enabled_modify(struct nb_cb_modify_args *args)
area = nb_running_get_entry(args->dnode, NULL, true);
overload = yang_dnode_get_bool(args->dnode, NULL);
+ area->overload_configured = overload;
+
isis_area_overload_bit_set(area, overload);
return NB_OK;
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 3ba00e6bf0..d59a411843 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -3190,9 +3190,15 @@ void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
if (new_overload_bit != area->overload_bit) {
area->overload_bit = new_overload_bit;
-
- if (new_overload_bit)
+ if (new_overload_bit) {
area->overload_counter++;
+ } else {
+ /* Cancel overload on startup timer if it's running */
+ if (area->t_overload_on_startup_timer) {
+ THREAD_OFF(area->t_overload_on_startup_timer);
+ area->t_overload_on_startup_timer = NULL;
+ }
+ }
#ifndef FABRICD
hook_call(isis_hook_db_overload, area);
diff --git a/isisd/isisd.h b/isisd/isisd.h
index f1f92b3651..81877f7455 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -181,6 +181,7 @@ struct isis_area {
char is_type; /* level-1 level-1-2 or level-2-only */
/* are we overloaded? */
char overload_bit;
+ bool overload_configured;
uint32_t overload_counter;
uint32_t overload_on_startup_time;
/* L1/L2 router identifier for inter-area traffic */
diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py
index bfcca5fd59..519ebba0cd 100644
--- a/tests/topotests/isis_topo1/test_isis_topo1.py
+++ b/tests/topotests/isis_topo1/test_isis_topo1.py
@@ -368,6 +368,7 @@ def test_isis_database_json():
def test_isis_overload_on_startup():
"Check that overload on startup behaves as expected"
+
tgen = get_topogen()
net = get_topogen().net
overload_time = 120
@@ -464,6 +465,124 @@ def check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
assert assertmsg is True, assertmsg
+def test_isis_overload_on_startup_cancel_timer():
+ "Check that overload on startup timer is cancelled when overload bit is set/unset"
+
+ tgen = get_topogen()
+ net = get_topogen().net
+ overload_time = 90
+
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Testing overload on startup behavior with set overload bit: cancel timer")
+
+ # Configure set-overload-bit on-startup on r3
+ r3 = tgen.gears["r3"]
+ r3.vtysh_cmd(
+ f"""
+ configure
+ router isis 1
+ set-overload-bit on-startup {overload_time}
+ set-overload-bit
+ """
+ )
+ # Restart r3
+ logger.info("Stop router")
+ stop_router(tgen, "r3")
+ logger.info("Start router")
+ start_router(tgen, "r3")
+
+ # Check that the overload bit is set in r3's LSP
+ check_lsp_overload_bit("r3", "r3.00-00", "0/0/1")
+
+ # Check that overload timer is running
+ check_overload_timer("r3", True)
+
+ # Unset overload bit while timer is running
+ r3.vtysh_cmd(
+ """
+ configure
+ router isis 1
+ no set-overload-bit
+ """
+ )
+
+ # Check that overload timer is cancelled
+ check_overload_timer("r3", False)
+
+ # Check overload bit is unset
+ check_lsp_overload_bit("r3", "r3.00-00", "0/0/0")
+
+
+def test_isis_overload_on_startup_override_timer():
+ "Check that overload bit remains set after overload timer expires if overload bit is configured"
+
+ tgen = get_topogen()
+ net = get_topogen().net
+ overload_time = 60
+
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Testing overload on startup behavior with set overload bit: override timer")
+
+ # Configure set-overload-bit on-startup on r3
+ r3 = tgen.gears["r3"]
+ r3.vtysh_cmd(
+ f"""
+ configure
+ router isis 1
+ set-overload-bit on-startup {overload_time}
+ set-overload-bit
+ """
+ )
+ # Restart r3
+ logger.info("Stop router")
+ stop_router(tgen, "r3")
+ logger.info("Start router")
+ start_router(tgen, "r3")
+
+ # Check that the overload bit is set in r3's LSP
+ check_lsp_overload_bit("r3", "r3.00-00", "0/0/1")
+
+ # Check that overload timer is running
+ check_overload_timer("r3", True)
+
+ # Check that overload timer expired
+ check_overload_timer("r3", False)
+
+ # Check overload bit is still set
+ check_lsp_overload_bit("r3", "r3.00-00", "0/0/1")
+
+
+@retry(retry_timeout=200)
+def _check_overload_timer(router, timer_expected):
+ "Verfiy overload bit in router's LSP"
+
+ tgen = get_topogen()
+ router = tgen.gears[router]
+ thread_output = router.vtysh_cmd(
+ "show thread timers"
+ )
+
+ timer_running = "set_overload_on_start_timer" in thread_output
+ if timer_running == timer_expected:
+ return True
+ return "Expected timer running status: {}".format(timer_expected)
+
+
+def check_overload_timer(router, timer_expected):
+ "Verfiy overload bit in router's LSP"
+
+ assertmsg = _check_overload_timer(
+ router, timer_expected
+ )
+ assert assertmsg is True, assertmsg
+
+
def test_memory_leak():
"Run the memory leak test and report results."
tgen = get_topogen()