]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Settle timer generalization
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Tue, 26 Jul 2022 08:47:41 +0000 (10:47 +0200)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Tue, 26 Jul 2022 08:47:41 +0000 (10:47 +0200)
Settle timer was moved from nest/rt-table.c to lib/timer.c.

lib/timer.c
lib/timer.h
nest/rt-table.c
nest/rt.h

index c47e0bbc8b78d9797a61754b612cd1ee1df12bf3..ec8dd3e350b481adaad4cb505a13b0f4eaf65844 100644 (file)
@@ -376,3 +376,74 @@ tm_format_real_time(char *x, size_t max, const char *fmt, btime t)
 
   return 1;
 }
+
+
+/*
+ *  Settle timer
+ */
+
+static btime
+settled_time(struct settle_timer *st)
+{
+  return MIN_(st->last_change + *(st->min_settle_time),
+             st->base_settle_time + *(st->max_settle_time));
+}
+
+void
+settle_timer_changed(struct settle_timer *st)
+{
+  st->last_change = current_time();
+}
+
+void
+settle_timer(timer *t)
+{
+  log(L_INFO "settle_timer()");
+  struct settle_timer *st = (void *) t;
+
+  if (!st->base_settle_time)
+    return;
+
+  btime settled_t = settled_time(st);
+  if (current_time() < settled_t)
+  {
+    tm_set((timer *) st, settled_t);
+    return;
+  }
+
+  /* Settled */
+  st->base_settle_time = 0;
+
+  if (st->class->action)
+    st->class->action(st);
+}
+
+struct settle_timer *
+stm_new_timer(pool *p, void *data, struct settle_timer_class *class)
+{
+  log(L_INFO "stm_new_timer() creating new timer");
+  struct settle_timer *st;
+  st = mb_allocz(p, sizeof(struct settle_timer));
+  st->class = class;
+
+  /* timer option randomize and recurrent are set to zero */
+  timer *t = (void *) st;
+  t->index = -1;
+  t->hook = settle_timer;
+  t->data = data;
+
+  return st;
+}
+
+void
+kick_settle_timer(struct settle_timer *st)
+{
+  log(L_INFO "kick_settle_timer()");
+  ASSUME(st != NULL);
+
+  st->base_settle_time = current_time();
+
+  timer *t = (void *) st;
+  if (!tm_active(t))
+    tm_set(t, settled_time(st));
+}
index c5ea430cdb81fe858c819eab697ff753a3674d78..89663ec4a74a5c194ec44130accc818c6822219b 100644 (file)
@@ -124,4 +124,26 @@ btime tm_parse_time(const char *x);
 void tm_format_time(char *x, struct timeformat *fmt, btime t);
 int tm_format_real_time(char *x, size_t max, const char *fmt, btime t);
 
+/*
+ *   Settle timer
+ */
+
+struct settle_timer {
+  timer tm;
+  btime *min_settle_time;
+  btime *max_settle_time;
+  btime base_settle_time;
+  btime last_change;
+  const struct settle_timer_class *class;
+};
+
+struct settle_timer_class {
+  void (*action)(struct settle_timer *st);
+  void (*changed)(struct settle_timer *st);
+  void (*kick)(struct settle_timer *st);
+};
+
+struct settle_timer *stm_new_timer(pool *p, void *data, struct settle_timer_class *class);
+void kick_settle_timer(struct settle_timer *st);
+
 #endif
index ed294c39034f9a1789f7e2986f1d6d25e675b8fa..3d11c7dc817956a136a94b9e15d8a612907b3078 100644 (file)
@@ -1365,7 +1365,7 @@ rte_recalculate(struct rt_import_hook *c, net *net, rte *new, struct rte_src *sr
     stats->withdraws_ignored++;
 
   if (old_ok || new_ok)
-    table->last_rt_change = current_time();
+    table->settle_timer->last_change = current_time();
 
   if (table->config->sorted)
     {
@@ -2019,7 +2019,7 @@ rt_dump_hooks(rtable *tab)
   debug("  nhu_state=%u hcu_scheduled=%u use_count=%d rt_count=%u\n",
       tab->nhu_state, tab->hcu_scheduled, tab->use_count, tab->rt_count);
   debug("  last_rt_change=%t gc_time=%t gc_counter=%d prune_state=%u\n",
-      tab->last_rt_change, tab->gc_time, tab->gc_counter, tab->prune_state);
+      tab->settle_timer->last_change, tab->gc_time, tab->gc_counter, tab->prune_state);
 
   struct rt_import_hook *ih;
   WALK_LIST(ih, tab->imports)
@@ -2133,50 +2133,21 @@ rt_kick_prune_timer(rtable *tab)
   tm_start(tab->prune_timer, gc_period);
 }
 
-
-static inline btime
-rt_settled_time(rtable *tab)
-{
-  ASSUME(tab->base_settle_time != 0);
-
-  return MIN(tab->last_rt_change + tab->config->min_settle_time,
-            tab->base_settle_time + tab->config->max_settle_time);
-}
-
 static void
-rt_settle_timer(timer *t)
+rt_settle_timer(struct settle_timer *st)
 {
+  timer *t = (void *) st;
   rtable *tab = t->data;
 
-  if (!tab->base_settle_time)
-    return;
-
-  btime settled_time = rt_settled_time(tab);
-  if (current_time() < settled_time)
-  {
-    tm_set(tab->settle_timer, settled_time);
-    return;
-  }
-
-  /* Settled */
-  tab->base_settle_time = 0;
-
   struct rt_subscription *s;
   WALK_LIST(s, tab->subscribers)
     s->hook(s);
 }
 
-static void
-rt_kick_settle_timer(rtable *tab)
-{
-  tab->base_settle_time = current_time();
-
-  if (!tab->settle_timer)
-    tab->settle_timer = tm_new_init(tab->rp, rt_settle_timer, tab, 0, 0);
-
-  if (!tm_active(tab->settle_timer))
-    tm_set(tab->settle_timer, rt_settled_time(tab));
-}
+static struct settle_timer_class rt_settle_class = {
+  .action = rt_settle_timer,
+  .kick = NULL,
+};
 
 static inline void
 rt_schedule_notify(rtable *tab)
@@ -2184,10 +2155,10 @@ rt_schedule_notify(rtable *tab)
   if (EMPTY_LIST(tab->subscribers))
     return;
 
-  if (tab->base_settle_time)
+  if (tab->settle_timer->base_settle_time)
     return;
 
-  rt_kick_settle_timer(tab);
+  kick_settle_timer(tab->settle_timer);
 }
 
 void
@@ -2373,7 +2344,9 @@ rt_setup(pool *pp, struct rtable_config *cf)
 
   t->rt_event = ev_new_init(p, rt_event, t);
   t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
-  t->last_rt_change = t->gc_time = current_time();
+  t->settle_timer = stm_new_timer(p, t, &rt_settle_class);
+
+  t->settle_timer->last_change = t->gc_time = current_time();
 
   t->rl_pipe = (struct tbf) TBF_DEFAULT_LOG_LIMITS;
 
index b13c06bea1d17a49b66ceef8159df42862d4270d..6c19677bf00b861d962cb0ae9c524cc875ec031c 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -17,6 +17,7 @@
 #include "lib/type.h"
 #include "lib/fib.h"
 #include "lib/route.h"
+#include "lib/timer.h"
 
 struct ea_list;
 struct protocol;
@@ -90,8 +91,6 @@ typedef struct rtable {
                                         */
   struct event *rt_event;              /* Routing table event */
   struct timer *prune_timer;           /* Timer for periodic pruning / GC */
-  btime last_rt_change;                        /* Last time when route changed */
-  btime base_settle_time;              /* Start time of rtable settling interval */
   btime gc_time;                       /* Time of last GC */
   uint gc_counter;                     /* Number of operations since last GC */
   byte prune_state;                    /* Table prune state, 1 -> scheduled, 2-> running */
@@ -107,7 +106,7 @@ typedef struct rtable {
   struct tbf rl_pipe;                  /* Rate limiting token buffer for pipe collisions */
 
   list subscribers;                    /* Subscribers for notifications */
-  struct timer *settle_timer;          /* Settle time for notifications */
+  struct settle_timer *settle_timer;   /* Settle time for notifications */
   list flowspec_links;                 /* List of flowspec links, src for NET_IPx and dst for NET_FLOWx */
   struct f_trie *flowspec_trie;                /* Trie for evaluation of flowspec notifications */
 } rtable;