]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Add settle timer
authorIgor Putovny <igor.putovny@nic.cz>
Fri, 17 May 2024 13:28:08 +0000 (15:28 +0200)
committerIgor Putovny <igor.putovny@nic.cz>
Thu, 30 May 2024 10:30:00 +0000 (12:30 +0200)
conf/conf.h
proto/aggregator/aggregator.c
proto/aggregator/aggregator.h
proto/aggregator/config.Y

index 56bde0395972a5861ac024c016898e1d3e4a8f8b..19a115b643ab406eea4130bcc09eb1504a476762 100644 (file)
@@ -14,6 +14,7 @@
 #include "lib/hash.h"
 #include "lib/resource.h"
 #include "lib/timer.h"
+#include "lib/settle.h"
 
 /* Configuration structure */
 struct config {
index 65f558ae83c5a2636f7cdd0e905e2b9cd586a870..a4c20856956c1b96453e676a23e27a2f00ddc63b 100644 (file)
 #include "nest/iface.h"
 #include "filter/filter.h"
 #include "proto/aggregator/aggregator.h"
+#include "lib/settle.h"
 
 #include <stdlib.h>
 #include <assert.h>
+
 /*
 #include "nest/route.h"
 #include "nest/iface.h"
@@ -928,6 +930,13 @@ aggregate_on_feed_end(struct channel *C)
     run_aggregation(p);
 }
 
+static void
+aggregate_on_settle_timer(struct settle *timer)
+{
+  struct aggregator_proto *p = SKIP_BACK(struct aggregator_proto, p, timer);
+  run_aggregation(p);
+}
+
 /*
  * Set static attribute in @rta from static attribute in @old according to @sa.
  */
@@ -1477,6 +1486,8 @@ aggregator_rt_notify(struct proto *P, struct channel *src_ch, net *net, rte *new
     HASH_REMOVE2(p->buckets, AGGR_BUCK, p->p.pool, old_bucket);
     sl_free(old_bucket);
   }
+
+  settle_kick(&p->aggr_timer);
 }
 
 static int
@@ -1534,6 +1545,7 @@ aggregator_init(struct proto_config *CF)
   p->aggr_on = cf->aggr_on;
   p->net_present = cf->net_present;
   p->merge_by = cf->merge_by;
+  p->aggr_timer_cf = cf->aggr_timer_cf;
 
   P->rt_notify = aggregator_rt_notify;
   P->preexport = aggregator_preexport;
@@ -1608,6 +1620,8 @@ aggregator_start(struct proto *P)
   /* Assign default route to the root */
   p->root->bucket = new_bucket;
 
+  settle_init(&p->aggr_timer, &p->aggr_timer_cf, aggregate_on_settle_timer, p);
+
   return PS_UP;
 }
 
@@ -1634,6 +1648,8 @@ aggregator_shutdown(struct proto *P)
   }
   HASH_WALK_END;
 
+  settle_cancel(&p->aggr_timer);
+
   delete_trie(p->root);
   p->root = NULL;
 
@@ -1648,6 +1664,10 @@ aggregator_reconfigure(struct proto *P, struct proto_config *CF)
 
   TRACE(D_EVENTS, "Reconfiguring");
 
+  /* Compare timer configuration */
+  if (cf->aggr_timer_cf.min != p->aggr_timer_cf.min || cf->aggr_timer_cf.max != p->aggr_timer_cf.max)
+    return 0;
+
   /* Compare numeric values (shortcut) */
   if (cf->aggr_on_count != p->aggr_on_count)
     return 0;
index cf5b605c196eac9787aea6eb1fc13e4c129bfb0c..26a18c7996fa5ec1200299052fe3822c5cf8eeb0 100644 (file)
@@ -16,6 +16,7 @@
 #include "nest/bird.h"
 #include "nest/protocol.h"
 #include "lib/hash.h"
+#include "lib/settle.h"
 
 #define MAX_POTENTIAL_BUCKETS_COUNT 16
 
@@ -27,6 +28,7 @@ struct aggregator_config {
   struct aggr_item *aggr_on;
   int net_present;
   const struct f_line *merge_by;
+  struct settle_config aggr_timer_cf;
 };
 
 struct aggregator_route {
@@ -70,6 +72,8 @@ struct aggregator_proto {
   uint addr_type;
   slab *trie_slab;
   struct trie_node *root;
+  struct settle_config aggr_timer_cf;
+  struct settle aggr_timer;
   int before_count;
   int after_count;
 };
index f37d842c61cd13658e7cc21452c8f8ae3868f10f..4d6651c2ce1ac356e10f7f18ce2b71b396d5d530 100644 (file)
@@ -11,6 +11,7 @@
 CF_HDR
 
 #include "proto/aggregator/aggregator.h"
+#include "lib/settle.h"
 
 CF_DEFINES
 
@@ -20,7 +21,7 @@ CF_DEFINES
 
 CF_DECLS
 
-CF_KEYWORDS(AGGREGATOR, AGGREGATE, ON, MERGE, BY)
+CF_KEYWORDS(AGGREGATOR, AGGREGATE, ON, MERGE, BY, RELOAD, AFTER)
 
 %type <ai> aggr_item aggr_list
 
@@ -35,8 +36,12 @@ aggregator_proto_start: proto_start AGGREGATOR
   this_proto = proto_config_new(&proto_aggregator, $1);
   this_channel = AGGREGATOR_CFG->src = channel_config_new(NULL, "source", 0, this_proto);
   AGGREGATOR_CFG->dst = channel_config_new(NULL, "destination", 0, this_proto);
-
   AGGREGATOR_CFG->src->ra_mode = AGGREGATOR_CFG->dst->ra_mode = RA_ANY;
+
+  AGGREGATOR_CFG->aggr_timer_cf = (struct settle_config) {
+    .min = 10 MS_,
+    .max = 100 MS_,
+  };
 };
 
 aggregator_proto_item:
@@ -79,6 +84,7 @@ aggregator_proto_item:
    $4->args++;
    AGGREGATOR_CFG->merge_by = $4;
  }
+ | RELOAD AFTER settle { AGGREGATOR_CFG->aggr_timer_cf = $3; }
 ;
 
 aggregator_proto_opts: /* empty */ | aggregator_proto_opts aggregator_proto_item ';' ;
@@ -136,6 +142,16 @@ aggr_item:
     }
   ;
 
+/* Settle timer configuration */
+settle:
+   expr_us expr_us {
+     if ($1 > $2)
+       cf_error("Minimum settle time %t is bigger than maximum settle time %t", $1, $2);
+     $$.min = $1 MS_;
+     $$.max = $2 MS_;
+   }
+ ;
+
 CF_CODE
 
 CF_END