return;
THREAD_TIMER_OFF(adj->t_expire);
- if (adj->adj_state != ISIS_ADJ_DOWN) {
+ if (adj->adj_state != ISIS_ADJ_DOWN)
adj->adj_state = ISIS_ADJ_DOWN;
- hook_call(isis_adj_state_change_hook, adj);
- }
/* remove from SPF trees */
spftree_area_adj_del(adj->circuit->area, adj);
+ hook_call(isis_adj_state_change_hook, adj);
+
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses);
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses);
if ((area->is_type & level) == 0)
return ISIS_ERROR;
- if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 100000L) {
+ /*
+ * Throttle regeneration of LSPs (but not when BFD signalled a 'down'
+ * message)
+ */
+ if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL)
+ < 100000L
+ && !(area->bfd_force_spf_refresh)) {
sched_debug("ISIS (%s): Still unstable, postpone LSP L%d refresh",
area->area_tag, level);
_lsp_regenerate_schedule(area, level, 0, false,
"ISIS (%s): Checking whether L%d needs to be scheduled",
area->area_tag, lvl);
- if (area->lsp_regenerate_pending[lvl - 1]) {
+ if (area->lsp_regenerate_pending[lvl - 1]
+ && !(area->bfd_signalled_down)) {
+ /*
+ * Note: in case of a BFD 'down' message the refresh is
+ * scheduled once again just to be sure
+ */
struct timeval remain = thread_timer_remain(
area->t_lsp_refresh[lvl - 1]);
sched_debug(
(long long)now);
THREAD_TIMER_OFF(area->t_lsp_refresh[lvl - 1]);
diff = now - lsp->last_generated;
- if (diff < area->lsp_gen_interval[lvl - 1]) {
+ if (diff < area->lsp_gen_interval[lvl - 1]
+ && !(area->bfd_signalled_down)) {
timeout =
1000 * (area->lsp_gen_interval[lvl - 1] - diff);
sched_debug(
area->area_tag, timeout);
} else {
/*
- * lsps are not regenerated if lsp_regenerate function
- * is called
- * directly. However if the lsp_regenerate call is
- * queued for
- * later execution it works.
+ * Schedule LSP refresh ASAP
*/
- timeout = 100;
- sched_debug(
- "ISIS (%s): Last generation was more than lsp_gen_interval ago."
- " Scheduling for execution in %ld ms.",
- area->area_tag, timeout);
+ timeout = 0;
+
+ if (area->bfd_signalled_down) {
+ sched_debug(
+ "ISIS (%s): Scheduling immediately due to BDF 'down' message.",
+ area->area_tag);
+ area->bfd_signalled_down = false;
+ area->bfd_force_spf_refresh = true;
+ } else {
+ sched_debug(
+ "ISIS (%s): Last generation was more than lsp_gen_interval ago. Scheduling for execution now.",
+ area->area_tag);
+ }
}
area->lsp_regenerate_pending[lvl - 1] = 1;
/* wait configured min_spf_interval before doing the SPF */
long timer;
- if (diff >= area->min_spf_interval[level - 1]) {
- /* Last run is more than min interval ago, schedule immediate run */
+ if (diff >= area->min_spf_interval[level - 1]
+ || area->bfd_force_spf_refresh) {
+ /*
+ * Last run is more than min interval ago or BFD signalled a
+ * 'down' message, schedule immediate run
+ */
timer = 0;
+
+ if (area->bfd_force_spf_refresh) {
+ zlog_debug(
+ "ISIS-Spf (%s) L%d SPF scheduled immediately due to BFD 'down' message",
+ area->area_tag, level);
+ area->bfd_force_spf_refresh = false;
+ }
} else {
timer = area->min_spf_interval[level - 1] - diff;
}