]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Set aggregation mode in the configuration file
authorIgor Putovny <igor.putovny@nic.cz>
Wed, 12 Jun 2024 16:27:36 +0000 (18:27 +0200)
committerIgor Putovny <igor.putovny@nic.cz>
Wed, 12 Jun 2024 16:27:36 +0000 (18:27 +0200)
proto/aggregator/aggregator.c
proto/aggregator/aggregator.h
proto/aggregator/config.Y

index dd8e0b56040be21e8342a3fdbb452e6b04e6a67c..c38c69476b061ee72304082fd0e54a36ccfe1283 100644 (file)
@@ -1479,7 +1479,7 @@ aggregator_rt_notify(struct proto *P, struct channel *src_ch, net *net, rte *new
     rta_free(old_route->rte.attrs);
   }
 
-  if (p->net_present != 0)
+  if (NET_AGGR == p->aggr_mode)
   {
     /* Announce changes */
     if (old_bucket)
@@ -1550,10 +1550,10 @@ aggregator_init(struct proto_config *CF)
   proto_configure_channel(P, &p->src, cf->src);
   proto_configure_channel(P, &p->dst, cf->dst);
 
+  p->aggr_mode = cf->aggr_mode;
   p->aggr_on_count = cf->aggr_on_count;
   p->aggr_on_da_count = cf->aggr_on_da_count;
   p->aggr_on = cf->aggr_on;
-  p->net_present = cf->net_present;
   p->merge_by = cf->merge_by;
   p->notify_settle_cf = cf->notify_settle_cf;
 
index 8c27d4bf646f988e1102cc5f597226539140d166..cac0813f6c29cb712cbde7b8da7757a5383683e4 100644 (file)
 
 #define MAX_POTENTIAL_BUCKETS_COUNT 16
 
+enum aggr_mode {
+  NET_AGGR, PREFIX_AGGR,
+};
+
 struct aggregator_config {
   struct proto_config c;
   struct channel_config *src, *dst;
+  enum aggr_mode aggr_mode;
   uint aggr_on_count;
   uint aggr_on_da_count;
   struct aggr_item *aggr_on;
-  int net_present;
   const struct f_line *merge_by;
   struct settle_config notify_settle_cf;
 };
@@ -49,7 +53,7 @@ struct aggregator_bucket {
 struct aggregator_proto {
   struct proto p;
   struct channel *src, *dst;
-
+  enum aggr_mode aggr_mode;
 
   /* Buckets by aggregator rule */
   HASH(struct aggregator_bucket) buckets;
@@ -63,7 +67,6 @@ struct aggregator_proto {
   uint aggr_on_count;
   uint aggr_on_da_count;
   struct aggr_item *aggr_on;
-  int net_present;
 
   /* Merge filter */
   const struct f_line *merge_by;
index 6483151b6379e2e64f0f16531bae229f5d1f51c5..14b7e4b2fa59716493dac231e55ca16a183bf020 100644 (file)
@@ -36,7 +36,14 @@ 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;
+
+  /*
+   * Aggregation mode is set to prefix aggregation by default, in which case we want to receive
+   * updates with the best routes.
+   */
+  AGGREGATOR_CFG->aggr_mode = PREFIX_AGGR;
+  AGGREGATOR_CFG->src->ra_mode = RA_OPTIMAL;
+  AGGREGATOR_CFG->dst->ra_mode = RA_ANY;
 
   AGGREGATOR_CFG->notify_settle_cf = (struct settle_config) {
     .min = 10 MS_,
@@ -52,14 +59,19 @@ aggregator_proto_item:
     if (AGGREGATOR_CFG->aggr_on)
       cf_error("Only one aggregate on clause allowed");
 
-    AGGREGATOR_CFG->net_present = 0;
     int count = 0;
 
     for (const struct aggr_item_node *item = $3; item; item = item->next) {
       log(L_WARN "type %d sacode %d", item->i.type, item->i.sa.sa_code);
 
-      if (item->i.type == AGGR_ITEM_STATIC_ATTR && item->i.sa.sa_code == SA_NET)
-        AGGREGATOR_CFG->net_present = 1;
+      /*
+       * If NET attribute is present, aggregate routes within the same net
+       * and receive updates with any routes.
+       */
+      if (item->i.type == AGGR_ITEM_STATIC_ATTR && item->i.sa.sa_code == SA_NET) {
+        AGGREGATOR_CFG->aggr_mode = NET_AGGR;
+        AGGREGATOR_CFG->src->ra_mode = RA_ANY;
+      }
 
       count++;
     }
@@ -92,7 +104,7 @@ aggregator_proto: aggregator_proto_start proto_name '{' aggregator_proto_opts '}
   if (AGGREGATOR_CFG->src->table->addr_type != AGGREGATOR_CFG->dst->table->addr_type)
     cf_error("Both rtables in aggregator must have the same network type");
 
-  if (AGGREGATOR_CFG->net_present == 0)
+  if (PREFIX_AGGR == AGGREGATOR_CFG->aggr_mode)
     if (AGGREGATOR_CFG->src->table->addr_type != NET_IP4 && AGGREGATOR_CFG->src->table->addr_type != NET_IP6)
       cf_error("Trie aggregation is available only for IP4 or IPv6 networks");
 };