isisd: add a slight delay to lsp_regenerate_schedule

isisd implements a holdoff interval and will refrain from regenerating
an lsp if the difference between the current time and its last refresh
is less than the holdoff interval. Instead, it will schedule a timer
to regenerate the lsp after the holdoff interval has passed.

This implementation has one disadvantage in the case where there is a
succession of calls to lsp_regenerate_schedule. In such a case, the
first call will trigger an immediate regeneration of the lsp, while the
other calls will only schedule the regeneration timer. This leads to
cases where it takes holdoff interval time for information to propagate,
just because the information was only available e.g. at the second call
of lsp_regenerate_schedule in such a succession of calls.

By not immediately regenerating an lsp if the last generation time
is sufficiently long ago, but instead scheduling the regeneration with a
very small delay, we allow all information from such a succession of
calls to be considered.

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 51a72ab..96c3ba3 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -97,6 +97,17 @@
   struct flags flags;
   struct thread *t_tick;	/* LSP walker */
   struct thread *t_lsp_refresh[ISIS_LEVELS];
+  /* t_lsp_refresh is used in two ways:
+   * a) regular refresh of LSPs
+   * b) (possibly throttled) updates to LSPs
+   *
+   * The lsp_regenerate_pending flag tracks whether the timer is active
+   * for the a) or the b) case.
+   *
+   * It is of utmost importance to clear this flag when the timer is
+   * rescheduled for normal refresh, because otherwise, updates will
+   * be delayed until the next regular refresh.
+   */
   int lsp_regenerate_pending[ISIS_LEVELS];
 
   /*
@@ -167,6 +178,7 @@
 #define DEBUG_ZEBRA                      (1<<11)
 #define DEBUG_PACKET_DUMP                (1<<12)
 #define DEBUG_LSP_GEN                    (1<<13)
+#define DEBUG_LSP_SCHED                  (1<<14)
 
 #define lsp_debug(...) \
   do \
@@ -176,4 +188,12 @@
     } \
   while (0)
 
+#define sched_debug(...) \
+  do \
+    { \
+      if (isis->debugs & DEBUG_LSP_SCHED) \
+        zlog_debug(__VA_ARGS__); \
+    } \
+  while (0)
+
 #endif /* ISISD_H */