]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
ROA aggregator uses its own rte source instead of recycling
authorMaria Matejka <mq@ucw.cz>
Tue, 25 Jun 2024 09:19:14 +0000 (11:19 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 26 Jun 2024 09:29:43 +0000 (11:29 +0200)
nest/proto.c
nest/rt-attr.c
nest/rt-table.c

index 85344c04bc853352f881348300b9f4ff93bf4a1d..26315d0f0a93dd96068acb93dbe6abd919df0016 100644 (file)
@@ -2206,18 +2206,13 @@ channel_reset_limit(struct channel *c, struct limit *l, int dir)
   c->limit_active &= ~(1 << dir);
 }
 
-static struct rte_owner_class default_rte_owner_class;
-
 static inline void
 proto_do_start(struct proto *p)
 {
   p->active = 1;
 
-  rt_init_sources(&p->sources, p->name, proto_event_list(p));
-  if (!p->sources.class)
-    p->sources.class = &default_rte_owner_class;
-
   p->sources.debug = p->debug;
+  rt_init_sources(&p->sources, p->name, proto_event_list(p));
 
   if (!p->cf->late_if_feed)
     iface_subscribe(&p->iface_sub);
index d9fa7b22b858b89b3ad7bdf308b788574422961d..6e96bc5219fc9d3cb34658ec620be717a43728ef 100644 (file)
@@ -401,6 +401,8 @@ rt_dump_sources(struct rte_owner *o)
   debug("\n");
 }
 
+static struct rte_owner_class default_rte_owner_class;
+
 void
 rt_init_sources(struct rte_owner *o, const char *name, event_list *list)
 {
@@ -412,6 +414,8 @@ rt_init_sources(struct rte_owner *o, const char *name, event_list *list)
   o->prune = ev_new_init(rta_pool, rt_prune_sources, o);
   o->stop = NULL;
   o->list = list;
+  if (!o->class)
+    o->class = &default_rte_owner_class;
   RTA_UNLOCK;
   if (o->debug & D_EVENTS)
     log(L_TRACE "%s: initialized rte_src owner", o->name);
index 0b6a19d8137ce9df87bde90aa9526d7dfbd8d81d..fbb0d985e63b3e57e4a9965430fceabf6e61f052 100644 (file)
@@ -413,6 +413,8 @@ net_route(struct rtable_reading *tr, const net_addr *n)
 
 struct rt_roa_aggregator {
   struct rt_stream stream;
+  struct rte_owner sources;
+  struct rte_src *main_source;
   struct rt_export_request src;
   event event;
 };
@@ -479,8 +481,8 @@ rt_aggregate_roa(void *_rag)
 
   RT_EXPORT_WALK(&rag->src, u) TMP_SAVED
   {
+    _Bool withdraw = 0;
     const net_addr *nroa = NULL;
-    struct rte_src *src = NULL;
     switch (u->kind)
     {
       case RT_EXPORT_STOP:
@@ -489,12 +491,12 @@ rt_aggregate_roa(void *_rag)
 
       case RT_EXPORT_FEED:
        nroa = u->feed->ni->addr;
-       src = (u->feed->count_routes > 0) ? u->feed->block[0].src : NULL;
+       withdraw = (u->feed->count_routes == 0);
        break;
 
       case RT_EXPORT_UPDATE:
        nroa = u->update->new ? u->update->new->net : u->update->old->net;
-       src = u->update->new ? u->update->new->src : NULL;
+       withdraw = !u->update->new;
        break;
     }
 
@@ -541,22 +543,22 @@ rt_aggregate_roa(void *_rag)
 
       if ((rad->u[p].asn == asn) && (rad->u[p].max_pxlen))
        /* Found */
-       if (src)
-         continue;
-       else
+       if (withdraw)
          memcpy(&rad_new->u[p], &rad->u[p+1], (--count - p) * sizeof rad->u[p]);
+       else
+         continue;
       else
        /* Not found */
-       if (src)
+       if (withdraw)
+         continue;
+       else
        {
          rad_new->u[p].asn = asn;
          rad_new->u[p].max_pxlen = max_pxlen;
          memcpy(&rad_new->u[p+1], &rad->u[p], (count++ - p) * sizeof rad->u[p]);
        }
-       else
-         continue;
     }
-    else if (src)
+    else if (!withdraw)
     {
       count = 1;
       rad_new = tmp_alloc(sizeof *rad_new + sizeof rad_new->u[0]);
@@ -569,12 +571,12 @@ rt_aggregate_roa(void *_rag)
     rad_new->ad.length = (byte *) &rad_new->u[count] - rad_new->ad.data;
 
     rte r = {
-      .src = src ?: prev.src,
+      .src = rag->main_source,
     };
 
     ea_set_attr(&r.attrs, EA_LITERAL_DIRECT_ADATA(&ea_roa_aggregated, 0, &rad_new->ad));
 
-    rte_import(&rag->stream.dst, &nip.n, &r, prev.src ?: src);
+    rte_import(&rag->stream.dst, &nip.n, &r, rag->main_source);
 
 #if 0
     /* Do not split ROA aggregator, we want this to be finished asap */
@@ -620,6 +622,9 @@ rt_setup_roa_aggregator(rtable *t)
       },
     };
 
+    rt_init_sources(&rag->sources, ragname, birdloop_event_list(t->loop));
+    rag->main_source = rt_get_source_o(&rag->sources, 0);
+
     tab->master = &rag->stream;
   }
 
@@ -627,13 +632,26 @@ rt_setup_roa_aggregator(rtable *t)
   rt_export_subscribe(src, best, &rag->src);
 }
 
+static void
+rt_roa_aggregator_sources_gone(void *t)
+{
+  rt_unlock_table((rtable *) t);
+}
+
 static void
 rt_stop_roa_aggregator(rtable *t)
 {
   struct rt_roa_aggregator *rag;
   RT_LOCKED(t, tab)
+  {
     rag = SKIP_BACK(struct rt_roa_aggregator, stream, tab->master);
 
+    rt_lock_table(tab);
+    rt_destroy_sources(&rag->sources, ev_new_init(tab->rp,
+         rt_roa_aggregator_sources_gone, tab));
+    rt_unlock_source(rag->main_source);
+  }
+
   /* Stopping both import and export.
    * All memory will be freed with table shutdown,
    * no need to do anything from import done callback */