]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: Add JSON object functions to save overload status between restarts. 11980/head
authorIsabella de Leon <ideleon@microsoft.com>
Wed, 12 Oct 2022 23:03:29 +0000 (16:03 -0700)
committerIsabella de Leon <ideleon@microsoft.com>
Wed, 12 Oct 2022 23:57:32 +0000 (16:57 -0700)
Signed-off-by: Isabella de Leon <ideleon@microsoft.com>
configure.ac
isisd/isis_lsp.c
isisd/isisd.c
isisd/isisd.h
tests/topotests/isis_topo1/test_isis_topo1.py

index 8c1fab0eabedf8f643edd6b99f75ec54027fbb45..00251fa38b43e0dd70c8fc927cd155cc800b8add 100644 (file)
@@ -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])
index 2dc6f15c79a467f4b57fce5b2961e54aecd34892..63b4edb1e191a167139e4232280bf327d1f469a5 100644 (file)
@@ -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);
index d59a411843508cf90b8ce634a9712bc801af9daf..7dd08cb13b3d1024af980901c13de608c6a2c1f4 100644 (file)
@@ -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)
index 81877f7455ffa0feec3659f0c9ff209c15903f91..bc1aa12956a3b5dcdb9821c5fcfbe5a42296b0c7 100644 (file)
@@ -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"
index 519ebba0cdefae30579b6cc801add657d4d97c9d..8b6c3772b8d9406a11831f5d892a191938027997 100644 (file)
@@ -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