]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: Fix isisd to generate lsps after config processing is complete 12819/head
authorIsabella de Leon <ideleon@microsoft.com>
Wed, 15 Feb 2023 23:42:09 +0000 (15:42 -0800)
committerIsabella de Leon <ideleon@microsoft.com>
Tue, 21 Feb 2023 16:49:34 +0000 (08:49 -0800)
Before:
isisd generates its initial lsp before fully processing the written config. Ex: lsp_generate() is called in isis_instance_area_address_create(), before other configs that may affect the lsp are loaded in, like set-overload-bit.

After:
isisd generates its initial lsp as soon as the config is fully processed. This was done by utilizing the initialization config callbacks, similar to bgp's implementation.

Signed-off-by: Isabella de Leon <ideleon@microsoft.com>
isisd/isis_lsp.c
isisd/isis_main.c
isisd/isisd.c
isisd/isisd.h

index 63b4edb1e191a167139e4232280bf327d1f469a5..595144147a6db5033ce30aac22655608ca87100a 100644 (file)
@@ -1377,6 +1377,10 @@ int lsp_generate(struct isis_area *area, int level)
        if ((area == NULL) || (area->is_type & level) != level)
                return ISIS_ERROR;
 
+       /* Check if config is still being processed */
+       if (thread_is_scheduled(t_isis_cfg))
+               return ISIS_OK;
+
        memset(&lspid, 0, ISIS_SYS_ID_LEN + 2);
 
        memcpy(&lspid, area->isis->sysid, ISIS_SYS_ID_LEN);
index 607661b540a5ab2f6b8be8cfd382c7a80a5816f3..ebd8eb28effba585996b0bdfe45aac8224fc210a 100644 (file)
@@ -181,6 +181,40 @@ static const struct frr_yang_module_info *const isisd_yang_modules[] = {
 };
 /* clang-format on */
 
+
+static void isis_config_finish(struct thread *t)
+{
+       struct listnode *node, *inode;
+       struct isis *isis;
+       struct isis_area *area;
+
+       for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
+               for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
+                       config_end_lsp_generate(area);
+       }
+}
+
+static void isis_config_start(void)
+{
+       /* Max wait time for config to load before generating lsp */
+#define ISIS_PRE_CONFIG_MAX_WAIT_SECONDS 600
+       THREAD_OFF(t_isis_cfg);
+       thread_add_timer(im->master, isis_config_finish, NULL,
+                        ISIS_PRE_CONFIG_MAX_WAIT_SECONDS, &t_isis_cfg);
+}
+
+static void isis_config_end(void)
+{
+       /* If ISIS config processing thread isn't running, then
+        * we can return and rely it's properly handled.
+        */
+       if (!thread_is_scheduled(t_isis_cfg))
+               return;
+
+       THREAD_OFF(t_isis_cfg);
+       isis_config_finish(t_isis_cfg);
+}
+
 #ifdef FABRICD
 FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT,
 
@@ -244,6 +278,7 @@ int main(int argc, char **argv, char **envp)
        /*
         *  initializations
         */
+       cmd_init_config_callbacks(isis_config_start, isis_config_end);
        isis_error_init();
        access_list_init();
        access_list_add_hook(isis_filter_update);
index 7e40c21a0dbba6f1de0002fb61a41b1d8267c24d..9c62c6b4f08aa5eb69088a84b28cddffecc6c7e6 100644 (file)
@@ -100,6 +100,9 @@ static struct isis_master isis_master;
 /* ISIS process wide configuration pointer to export. */
 struct isis_master *im;
 
+/* ISIS config processing thread */
+struct thread *t_isis_cfg;
+
 #ifndef FABRICD
 DEFINE_HOOK(isis_hook_db_overload, (const struct isis_area *area), (area));
 #endif /* ifndef FABRICD */
@@ -3247,6 +3250,16 @@ void isis_area_overload_on_startup_set(struct isis_area *area,
        }
 }
 
+void config_end_lsp_generate(struct isis_area *area)
+{
+       if (listcount(area->area_addrs) > 0) {
+               if (CHECK_FLAG(area->is_type, IS_LEVEL_1))
+                       lsp_generate(area, IS_LEVEL_1);
+               if (CHECK_FLAG(area->is_type, IS_LEVEL_2))
+                       lsp_generate(area, IS_LEVEL_2);
+       }
+}
+
 /*
  * Returns the path of the file (non-volatile memory) that contains restart
  * information.
index 38f20b21135bfda3cc4ab1169b1330ef9ec20735..dae512c15979858eb95bba5fea96bd280975ba20 100644 (file)
@@ -112,6 +112,8 @@ struct isis {
 
 extern struct isis_master *im;
 
+extern struct thread *t_isis_cfg;
+
 enum spf_tree_id {
        SPFTREE_IPV4 = 0,
        SPFTREE_IPV6,
@@ -327,6 +329,8 @@ 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);
+void config_end_lsp_generate(struct isis_area *area);
+
 /* YANG paths */
 #define ISIS_INSTANCE  "/frr-isisd:isis/instance"
 #define ISIS_SR                "/frr-isisd:isis/instance/segment-routing"