From 3b0e97e15016039206ef92c97c6b995cd7093a15 Mon Sep 17 00:00:00 2001 From: Isabella de Leon Date: Wed, 15 Feb 2023 15:42:09 -0800 Subject: [PATCH] isisd: Fix isisd to generate lsps after config processing is complete 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 --- isisd/isis_lsp.c | 4 ++++ isisd/isis_main.c | 35 +++++++++++++++++++++++++++++++++++ isisd/isisd.c | 13 +++++++++++++ isisd/isisd.h | 4 ++++ 4 files changed, 56 insertions(+) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 63b4edb1e1..595144147a 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -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); diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 607661b540..ebd8eb28ef 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -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); diff --git a/isisd/isisd.c b/isisd/isisd.c index 7e40c21a0d..9c62c6b4f0 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -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. diff --git a/isisd/isisd.h b/isisd/isisd.h index 38f20b2113..dae512c159 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -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" -- 2.39.5