summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--isisd/isis_lsp.c27
-rw-r--r--isisd/isisd.c98
-rw-r--r--isisd/isisd.h5
-rw-r--r--tests/topotests/isis_topo1/test_isis_topo1.py74
5 files changed, 152 insertions, 53 deletions
diff --git a/configure.ac b/configure.ac
index 8c1fab0ea..00251fa38 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2631,6 +2631,7 @@ AC_DEFINE_UNQUOTED([ZEBRA_SERV_PATH], ["$frr_statedir%s%s/zserv.api"], [zebra ap
AC_DEFINE_UNQUOTED([BFDD_CONTROL_SOCKET], ["$frr_statedir%s%s/bfdd.sock"], [bfdd control socket])
AC_DEFINE_UNQUOTED([OSPFD_GR_STATE], ["$frr_statedir%s/ospfd-gr.json"], [ospfd GR state information])
AC_DEFINE_UNQUOTED([OSPF6D_GR_STATE], ["$frr_statedir/ospf6d-gr.json"], [ospf6d GR state information])
+AC_DEFINE_UNQUOTED([ISISD_RESTART], ["$frr_statedir%s/isid-restart.json"], [isisd restart information])
AC_DEFINE_UNQUOTED([OSPF6_AUTH_SEQ_NUM_FILE], ["$frr_statedir/ospf6d-at-seq-no.dat"], [ospf6d AT Sequence number information])
AC_DEFINE_UNQUOTED([DAEMON_VTY_DIR], ["$frr_statedir%s%s"], [daemon vty directory])
AC_DEFINE_UNQUOTED([DAEMON_DB_DIR], ["$frr_statedir"], [daemon database directory])
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 2dc6f15c7..63b4edb1e 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -1372,6 +1372,7 @@ int lsp_generate(struct isis_area *area, int level)
uint32_t seq_num = 0;
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
uint16_t rem_lifetime, refresh_time;
+ uint32_t overload_time;
if ((area == NULL) || (area->is_type & level) != level)
return ISIS_ERROR;
@@ -1380,6 +1381,18 @@ int lsp_generate(struct isis_area *area, int level)
memcpy(&lspid, area->isis->sysid, ISIS_SYS_ID_LEN);
+ /* Check if device should be overloaded on startup */
+ if (device_startup) {
+ overload_time = isis_restart_read_overload_time(area);
+ if (overload_time > 0) {
+ isis_area_overload_bit_set(area, true);
+ thread_add_timer(master, set_overload_on_start_timer,
+ area, overload_time,
+ &area->t_overload_on_startup_timer);
+ }
+ device_startup = false;
+ }
+
/* only builds the lsp if the area shares the level */
oldlsp = lsp_search(&area->lspdb[level - 1], lspid);
if (oldlsp) {
@@ -1448,20 +1461,6 @@ static int lsp_regenerate(struct isis_area *area, int level)
if ((area == NULL) || (area->is_type & level) != level)
return ISIS_ERROR;
- /*
- * Check if the device is initializing and set overload bit on startup
- * is configured.
- */
- if (device_startup) {
- if (area->overload_on_startup_time > 0) {
- isis_area_overload_bit_set(area, true);
- thread_add_timer(master, set_overload_on_start_timer,
- area, area->overload_on_startup_time,
- &area->t_overload_on_startup_timer);
- }
- device_startup = false;
- }
-
head = &area->lspdb[level - 1];
memset(lspid, 0, ISIS_SYS_ID_LEN + 2);
memcpy(lspid, area->isis->sysid, ISIS_SYS_ID_LEN);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index d59a41184..7dd08cb13 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -3214,8 +3214,104 @@ void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
void isis_area_overload_on_startup_set(struct isis_area *area,
uint32_t startup_time)
{
- if (area->overload_on_startup_time != startup_time)
+ if (area->overload_on_startup_time != startup_time) {
area->overload_on_startup_time = startup_time;
+ isis_restart_write_overload_time(area, startup_time);
+ }
+}
+
+/*
+ * Returns the path of the file (non-volatile memory) that contains restart
+ * information.
+ */
+char *isis_restart_filepath()
+{
+ static char filepath[MAXPATHLEN];
+ snprintf(filepath, sizeof(filepath), ISISD_RESTART, "");
+ return filepath;
+}
+
+/*
+ * Record in non-volatile memory the overload on startup time.
+ */
+void isis_restart_write_overload_time(struct isis_area *isis_area,
+ uint32_t overload_time)
+{
+ char *filepath;
+ const char *area_name;
+ json_object *json;
+ json_object *json_areas;
+ json_object *json_area;
+
+ filepath = isis_restart_filepath();
+ area_name = isis_area->area_tag;
+
+ json = json_object_from_file(filepath);
+ if (json == NULL)
+ json = json_object_new_object();
+
+ json_object_object_get_ex(json, "areas", &json_areas);
+ if (!json_areas) {
+ json_areas = json_object_new_object();
+ json_object_object_add(json, "areas", json_areas);
+ }
+
+ json_object_object_get_ex(json_areas, area_name, &json_area);
+ if (!json_area) {
+ json_area = json_object_new_object();
+ json_object_object_add(json_areas, area_name, json_area);
+ }
+
+ json_object_int_add(json_area, "overload_time",
+ isis_area->overload_on_startup_time);
+ json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
+ json_object_free(json);
+}
+
+/*
+ * Fetch from non-volatile memory the overload on startup time.
+ */
+uint32_t isis_restart_read_overload_time(struct isis_area *isis_area)
+{
+ char *filepath;
+ const char *area_name;
+ json_object *json;
+ json_object *json_areas;
+ json_object *json_area;
+ json_object *json_overload_time;
+ uint32_t overload_time = 0;
+
+ filepath = isis_restart_filepath();
+ area_name = isis_area->area_tag;
+
+ json = json_object_from_file(filepath);
+ if (json == NULL)
+ json = json_object_new_object();
+
+ json_object_object_get_ex(json, "areas", &json_areas);
+ if (!json_areas) {
+ json_areas = json_object_new_object();
+ json_object_object_add(json, "areas", json_areas);
+ }
+
+ json_object_object_get_ex(json_areas, area_name, &json_area);
+ if (!json_area) {
+ json_area = json_object_new_object();
+ json_object_object_add(json_areas, area_name, json_area);
+ }
+
+ json_object_object_get_ex(json_area, "overload_time",
+ &json_overload_time);
+ if (json_overload_time) {
+ overload_time = json_object_get_int(json_overload_time);
+ }
+
+ json_object_object_del(json_areas, area_name);
+
+ json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
+ json_object_free(json);
+
+ return overload_time;
}
void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit)
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 81877f745..bc1aa1295 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -319,7 +319,10 @@ void show_isis_database_lspdb_json(struct json_object *json,
void show_isis_database_lspdb_vty(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *argv, int ui_level);
-
+char *isis_restart_filepath(void);
+void isis_restart_write_overload_time(struct isis_area *isis_area,
+ uint32_t overload_time);
+uint32_t isis_restart_read_overload_time(struct isis_area *isis_area);
/* YANG paths */
#define ISIS_INSTANCE "/frr-isisd:isis/instance"
#define ISIS_SR "/frr-isisd:isis/instance/segment-routing"
diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py
index 519ebba0c..8b6c3772b 100644
--- a/tests/topotests/isis_topo1/test_isis_topo1.py
+++ b/tests/topotests/isis_topo1/test_isis_topo1.py
@@ -436,35 +436,6 @@ def test_isis_overload_on_startup():
assert result
-@retry(retry_timeout=200)
-def _check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
- "Verfiy overload bit in router's LSP"
-
- tgen = get_topogen()
- router = tgen.gears[router]
- logger.info(f"check_overload_bit {router}")
- isis_database_output = router.vtysh_cmd(
- "show isis database {} json".format(overloaded_router_lsp)
- )
-
- database_json = json.loads(isis_database_output)
- att_p_ol = database_json["areas"][0]["levels"][1]["att-p-ol"]
- if att_p_ol == att_p_ol_expected:
- return True
- return "{} peer with expected att_p_ol {} got {} ".format(
- router.name, att_p_ol_expected, att_p_ol
- )
-
-
-def check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
- "Verfiy overload bit in router's LSP"
-
- assertmsg = _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"
@@ -476,7 +447,9 @@ def test_isis_overload_on_startup_cancel_timer():
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
- logger.info("Testing overload on startup behavior with set overload bit: cancel timer")
+ 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"]
@@ -527,7 +500,9 @@ def test_isis_overload_on_startup_override_timer():
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
- logger.info("Testing overload on startup behavior with set overload bit: override timer")
+ 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"]
@@ -559,14 +534,41 @@ def test_isis_overload_on_startup_override_timer():
@retry(retry_timeout=200)
-def _check_overload_timer(router, timer_expected):
+def _check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
"Verfiy overload bit in router's LSP"
tgen = get_topogen()
router = tgen.gears[router]
- thread_output = router.vtysh_cmd(
- "show thread timers"
+ logger.info(f"check_overload_bit {router}")
+ isis_database_output = router.vtysh_cmd(
+ "show isis database {} json".format(overloaded_router_lsp)
+ )
+
+ database_json = json.loads(isis_database_output)
+ att_p_ol = database_json["areas"][0]["levels"][1]["att-p-ol"]
+ if att_p_ol == att_p_ol_expected:
+ return True
+ return "{} peer with expected att_p_ol {} got {} ".format(
+ router.name, att_p_ol_expected, att_p_ol
+ )
+
+
+def check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
+ "Verfiy overload bit in router's LSP"
+
+ assertmsg = _check_lsp_overload_bit(
+ router, overloaded_router_lsp, att_p_ol_expected
)
+ assert assertmsg is True, assertmsg
+
+
+@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:
@@ -577,9 +579,7 @@ def _check_overload_timer(router, timer_expected):
def check_overload_timer(router, timer_expected):
"Verfiy overload bit in router's LSP"
- assertmsg = _check_overload_timer(
- router, timer_expected
- )
+ assertmsg = _check_overload_timer(router, timer_expected)
assert assertmsg is True, assertmsg