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 <ideleon@microsoft.com>
This commit is contained in:
Isabella de Leon 2023-02-15 15:42:09 -08:00
parent bf9bc2e5f2
commit 3b0e97e150
4 changed files with 56 additions and 0 deletions

View File

@ -1377,6 +1377,10 @@ int lsp_generate(struct isis_area *area, int level)
if ((area == NULL) || (area->is_type & level) != level) if ((area == NULL) || (area->is_type & level) != level)
return ISIS_ERROR; 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); memset(&lspid, 0, ISIS_SYS_ID_LEN + 2);
memcpy(&lspid, area->isis->sysid, ISIS_SYS_ID_LEN); memcpy(&lspid, area->isis->sysid, ISIS_SYS_ID_LEN);

View File

@ -181,6 +181,40 @@ static const struct frr_yang_module_info *const isisd_yang_modules[] = {
}; };
/* clang-format on */ /* 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 #ifdef FABRICD
FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT, FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT,
@ -244,6 +278,7 @@ int main(int argc, char **argv, char **envp)
/* /*
* initializations * initializations
*/ */
cmd_init_config_callbacks(isis_config_start, isis_config_end);
isis_error_init(); isis_error_init();
access_list_init(); access_list_init();
access_list_add_hook(isis_filter_update); access_list_add_hook(isis_filter_update);

View File

@ -100,6 +100,9 @@ static struct isis_master isis_master;
/* ISIS process wide configuration pointer to export. */ /* ISIS process wide configuration pointer to export. */
struct isis_master *im; struct isis_master *im;
/* ISIS config processing thread */
struct thread *t_isis_cfg;
#ifndef FABRICD #ifndef FABRICD
DEFINE_HOOK(isis_hook_db_overload, (const struct isis_area *area), (area)); DEFINE_HOOK(isis_hook_db_overload, (const struct isis_area *area), (area));
#endif /* ifndef FABRICD */ #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 * Returns the path of the file (non-volatile memory) that contains restart
* information. * information.

View File

@ -112,6 +112,8 @@ struct isis {
extern struct isis_master *im; extern struct isis_master *im;
extern struct thread *t_isis_cfg;
enum spf_tree_id { enum spf_tree_id {
SPFTREE_IPV4 = 0, SPFTREE_IPV4 = 0,
SPFTREE_IPV6, SPFTREE_IPV6,
@ -327,6 +329,8 @@ char *isis_restart_filepath(void);
void isis_restart_write_overload_time(struct isis_area *isis_area, void isis_restart_write_overload_time(struct isis_area *isis_area,
uint32_t overload_time); uint32_t overload_time);
uint32_t isis_restart_read_overload_time(struct isis_area *isis_area); uint32_t isis_restart_read_overload_time(struct isis_area *isis_area);
void config_end_lsp_generate(struct isis_area *area);
/* YANG paths */ /* YANG paths */
#define ISIS_INSTANCE "/frr-isisd:isis/instance" #define ISIS_INSTANCE "/frr-isisd:isis/instance"
#define ISIS_SR "/frr-isisd:isis/instance/segment-routing" #define ISIS_SR "/frr-isisd:isis/instance/segment-routing"