]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: delay lsp regeneration while events are still coming in
authorChristian Franke <chris@opensourcerouting.org>
Wed, 24 Oct 2018 05:19:22 +0000 (07:19 +0200)
committerChristian Franke <chris@opensourcerouting.org>
Wed, 24 Oct 2018 05:53:23 +0000 (07:53 +0200)
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>
isisd/isis_lsp.c
isisd/isis_lsp.h
isisd/isisd.h

index e01364dfecbd2ed26fa593be0ae4c2a0fb0dab57..bb090f42edda55fef18c9956f2d8331108d1b2fb 100644 (file)
@@ -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);
index 209a80ee701e4248a25a73bc9854fd9ae7015c91..2b45e6994ce1179887156cc90233e90876a0e531 100644 (file)
@@ -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);
 
index 5c4cf3e0da81b4f0acac9b001b40ee8600b35bf2..51b359aad462dfd082f7d741bff7e82cdbf7a705 100644 (file)
@@ -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