From 3d45539455fd92ab952fd1c92b3c630a908a53dc Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Tue, 25 Jun 2024 11:19:14 +0200 Subject: [PATCH] ROA aggregator uses its own rte source instead of recycling --- nest/proto.c | 7 +------ nest/rt-attr.c | 4 ++++ nest/rt-table.c | 42 ++++++++++++++++++++++++++++++------------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/nest/proto.c b/nest/proto.c index 85344c04..26315d0f 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -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); diff --git a/nest/rt-attr.c b/nest/rt-attr.c index d9fa7b22..6e96bc52 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -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); diff --git a/nest/rt-table.c b/nest/rt-table.c index 0b6a19d8..fbb0d985 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -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 */