mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 16:17:38 +00:00
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 <chris@opensourcerouting.org>
This commit is contained in:
parent
9196731f9d
commit
f93025e1a6
@ -1361,6 +1361,14 @@ static int lsp_refresh(struct thread *thread)
|
|||||||
if ((area->is_type & level) == 0)
|
if ((area->is_type & level) == 0)
|
||||||
return ISIS_ERROR;
|
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(
|
sched_debug(
|
||||||
"ISIS (%s): LSP L%d refresh timer expired. Refreshing LSP...",
|
"ISIS (%s): LSP L%d refresh timer expired. Refreshing LSP...",
|
||||||
area->area_tag, level);
|
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 _lsp_regenerate_schedule(struct isis_area *area, int level,
|
||||||
int all_pseudo, const char *func,
|
int all_pseudo, bool postpone,
|
||||||
const char *file, int line)
|
const char *func, const char *file,
|
||||||
|
int line)
|
||||||
{
|
{
|
||||||
struct isis_lsp *lsp;
|
struct isis_lsp *lsp;
|
||||||
uint8_t id[ISIS_SYS_ID_LEN + 2];
|
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)))
|
if (!((level & lvl) && (area->is_type & lvl)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (postpone) {
|
||||||
|
monotime(&area->last_lsp_refresh_event[lvl - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
sched_debug(
|
sched_debug(
|
||||||
"ISIS (%s): Checking whether L%d needs to be scheduled",
|
"ISIS (%s): Checking whether L%d needs to be scheduled",
|
||||||
area->area_tag, lvl);
|
area->area_tag, lvl);
|
||||||
|
@ -55,11 +55,11 @@ int lsp_tick(struct thread *thread);
|
|||||||
|
|
||||||
int lsp_generate(struct isis_area *area, int level);
|
int lsp_generate(struct isis_area *area, int level);
|
||||||
#define lsp_regenerate_schedule(area, level, all_pseudo) \
|
#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__)
|
__func__, __FILE__, __LINE__)
|
||||||
int _lsp_regenerate_schedule(struct isis_area *area, int level,
|
int _lsp_regenerate_schedule(struct isis_area *area, int level,
|
||||||
int all_pseudo, const char *func,
|
int all_pseudo, bool postpone,
|
||||||
const char *file, int line);
|
const char *func, const char *file, int line);
|
||||||
int lsp_generate_pseudo(struct isis_circuit *circuit, int level);
|
int lsp_generate_pseudo(struct isis_circuit *circuit, int level);
|
||||||
int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
|
int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ struct isis_area {
|
|||||||
struct flags flags;
|
struct flags flags;
|
||||||
struct thread *t_tick; /* LSP walker */
|
struct thread *t_tick; /* LSP walker */
|
||||||
struct thread *t_lsp_refresh[ISIS_LEVELS];
|
struct thread *t_lsp_refresh[ISIS_LEVELS];
|
||||||
|
struct timeval last_lsp_refresh_event[ISIS_LEVELS];
|
||||||
/* t_lsp_refresh is used in two ways:
|
/* t_lsp_refresh is used in two ways:
|
||||||
* a) regular refresh of LSPs
|
* a) regular refresh of LSPs
|
||||||
* b) (possibly throttled) updates to LSPs
|
* b) (possibly throttled) updates to LSPs
|
||||||
|
Loading…
Reference in New Issue
Block a user