From: Christian Franke Date: Wed, 24 Oct 2018 05:19:22 +0000 (+0200) Subject: isisd: delay lsp regeneration while events are still coming in X-Git-Tag: frr-7.1-dev~247^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=f93025e1a6e8249a888396efbadc98e27f217f88;p=matthieu%2Ffrr.git isisd: delay lsp regeneration while events are still coming in When there is a stream of events coming in, where IS-IS learns about a lot of updates, IS-IS would regenerate its LSPs before the updates have been processed completely. This causes suboptimal convergence because the intermediate state will be flooded. Only after the configured `lsp_gen_interval`, a new update with the correct and final state will be generated. Resolve this by holding off LSP generation while there are still events coming in. Signed-off-by: Christian Franke --- diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index e01364dfec..bb090f42ed 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -1361,6 +1361,14 @@ static int lsp_refresh(struct thread *thread) if ((area->is_type & level) == 0) return ISIS_ERROR; + if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 50000L) { + sched_debug("ISIS (%s): Still unstable, postpone LSP L%d refresh", + area->area_tag, level); + _lsp_regenerate_schedule(area, level, 0, false, + __func__, __FILE__, __LINE__); + return 0; + } + sched_debug( "ISIS (%s): LSP L%d refresh timer expired. Refreshing LSP...", area->area_tag, level); @@ -1368,8 +1376,9 @@ static int lsp_refresh(struct thread *thread) } int _lsp_regenerate_schedule(struct isis_area *area, int level, - int all_pseudo, const char *func, - const char *file, int line) + int all_pseudo, bool postpone, + const char *func, const char *file, + int line) { struct isis_lsp *lsp; uint8_t id[ISIS_SYS_ID_LEN + 2]; @@ -1397,6 +1406,10 @@ int _lsp_regenerate_schedule(struct isis_area *area, int level, if (!((level & lvl) && (area->is_type & lvl))) continue; + if (postpone) { + monotime(&area->last_lsp_refresh_event[lvl - 1]); + } + sched_debug( "ISIS (%s): Checking whether L%d needs to be scheduled", area->area_tag, lvl); diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index 209a80ee70..2b45e6994c 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -55,11 +55,11 @@ int lsp_tick(struct thread *thread); int lsp_generate(struct isis_area *area, int level); #define lsp_regenerate_schedule(area, level, all_pseudo) \ - _lsp_regenerate_schedule((area), (level), (all_pseudo), \ + _lsp_regenerate_schedule((area), (level), (all_pseudo), true, \ __func__, __FILE__, __LINE__) int _lsp_regenerate_schedule(struct isis_area *area, int level, - int all_pseudo, const char *func, - const char *file, int line); + int all_pseudo, bool postpone, + const char *func, const char *file, int line); int lsp_generate_pseudo(struct isis_circuit *circuit, int level); int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level); diff --git a/isisd/isisd.h b/isisd/isisd.h index 5c4cf3e0da..51b359aad4 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -105,6 +105,7 @@ struct isis_area { struct flags flags; struct thread *t_tick; /* LSP walker */ struct thread *t_lsp_refresh[ISIS_LEVELS]; + struct timeval last_lsp_refresh_event[ISIS_LEVELS]; /* t_lsp_refresh is used in two ways: * a) regular refresh of LSPs * b) (possibly throttled) updates to LSPs