]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: moved sender channel to the route rw structure route-storage-updates
authorMaria Matejka <mq@ucw.cz>
Fri, 1 May 2020 20:44:20 +0000 (22:44 +0200)
committerMaria Matejka <mq@ucw.cz>
Sat, 20 Mar 2021 23:28:17 +0000 (00:28 +0100)
It is needed for early pipe collision detection and it also reduces
the calling convention of rte_update() to one argument.

12 files changed:
nest/route.h
nest/rt-dev.c
nest/rt-table.c
proto/babel/babel.c
proto/bgp/packets.c
proto/ospf/rt.c
proto/perf/perf.c
proto/pipe/pipe.c
proto/rip/rip.c
proto/rpki/rpki.c
proto/static/static.c
sysdep/unix/krt.c

index 92b9cb3a7b6d827f899110736c31329340861611..0c588f66fcac77b4d72c13451263f7412efb4561 100644 (file)
@@ -231,6 +231,7 @@ typedef struct rte {
   struct rta *attrs;                   /* Attributes of this route */
   const net_addr *net;                 /* Network this RTE belongs to */
   struct rte_src *src;                 /* Route source that created the route */
+  struct channel *sender;              /* Channel used to send the route to the routing table */
   byte flags;                          /* Flags (REF_...) */
   byte pflags;                         /* Protocol-specific flags */
 } rte;
@@ -241,8 +242,8 @@ struct rte_storage {
   struct rta *attrs;                   /* Attributes of this route */
   net *net;                            /* Network this RTE belongs to */
   struct rte_src *src;                 /* Route source that created the route */
-
   struct channel *sender;              /* Channel used to send the route to the routing table */
+
   u32 id;                              /* Table specific route id */
   byte flags;                          /* Flags (REF_...) */
   byte pflags;                         /* Protocol-specific flags */
@@ -300,7 +301,6 @@ struct rte_export {
 
 /**
  * rte_update - enter a new update to a routing table
- * @c: channel doing the update
  * @rte: a &rte representing the new route
  *
  * This function imports a new route to the appropriate table (via the channel).
@@ -326,10 +326,10 @@ struct rte_export {
  * All memory used for temporary allocations is taken from a special linpool
  * @rte_update_pool and freed when rte_update() finishes.
  */
-void rte_update(struct channel *c, struct rte *rte) NONNULL(1,2);
+void rte_update(struct rte *rte) NONNULL(1);
 static inline void rte_withdraw(struct channel *c, const net_addr *net, struct rte_src *src)
 {
-  rte e = { .net = net, .src = src}; rte_update(c, &e);
+  rte e = { .sender = c, .net = net, .src = src}; rte_update(&e);
 }
 
 extern list routing_tables;
@@ -365,6 +365,7 @@ static inline rte rte_copy(const struct rte_storage *r)
     .attrs = r->attrs,
     .net = r->net->n.addr,
     .src = r->src,
+    .sender = r->sender,
     .flags = r->flags,
     .pflags = r->pflags
   } : (rte) {};
index f40c588ed8b561b699e5860a9e1aab6442ed2882..698893aa9a2fa2d3fc2e19fdf786982186317d0f 100644 (file)
@@ -87,8 +87,9 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
        .src = rt_get_source(P, ad->iface->index),
        .net = net,
        .attrs = &a0,
+       .sender = c,
       };
-      rte_update(c, &e0);
+      rte_update(&e0);
     }
 }
 
index e0898bc6b4aecaf1c67d52a4f8d0d2fbe0db0349..ad33f0a6adddc2edb4956f2fe40a23cfaf9ce69d 100644 (file)
@@ -291,6 +291,7 @@ rte_store(const rte *r, net *n)
     .attrs = r->attrs,
     .net = n,
     .src = r->src,
+    .sender = r->sender,
   };
 
   rt_lock_source(e->src);
@@ -306,7 +307,6 @@ rte_store(const rte *r, net *n)
 void
 rte_copy_metadata(struct rte_storage *dest, struct rte_storage *src)
 {
-  dest->sender = src->sender;
   dest->flags = src->flags & REF_FILTERED;
   dest->pflags = src->pflags;
   dest->lastmod = src->lastmod;
@@ -891,9 +891,10 @@ rte_same(struct rte_storage *x, rte *y, _Bool fy)
     rte_is_filtered(x) == fy;
 }
 
-static void NONNULL(1,2,3)
-rte_recalculate(struct channel *c, net *net, rte *new, _Bool filtered)
+static void NONNULL(1,2)
+rte_recalculate(net *net, rte *new, _Bool filtered)
 {
+  struct channel *c = new->sender;
   struct proto *p = c->proto;
   struct rtable *table = c->table;
   struct proto_stats *stats = &c->stats;
@@ -1028,7 +1029,6 @@ rte_recalculate(struct channel *c, net *net, rte *new, _Bool filtered)
 
   if (new->attrs) {
     new_stored = rte_store(new, net);
-    new_stored->sender = c;
 
     if (filtered)
       new_stored->flags |= REF_FILTERED;
@@ -1184,31 +1184,33 @@ rte_update_unlock(void)
     lp_flush(rte_update_pool);
 }
 
-static int NONNULL(1,2) rte_update_in(struct channel *c, rte *new);
-static void NONNULL(1,2) rte_update2(struct channel *c, rte *new);
+static int NONNULL(1) rte_update_in(rte *new);
+static void NONNULL(1) rte_update2(rte *new);
 
-void NONNULL(1,2)
-rte_update(struct channel *c, rte *new)
+void NONNULL(1)
+rte_update(rte *new)
 {
-  ASSERT(c->channel_state == CS_UP);
+  ASSERT(new->sender);
+  ASSERT(new->sender->channel_state == CS_UP);
   ASSERT(new->net);
   ASSERT(new->src);
 
   if (new->attrs && !new->attrs->pref)
   {
     ASSERT(!new->attrs->cached);
-    new->attrs->pref = c->preference;
+    new->attrs->pref = new->sender->preference;
   }
 
-  if (c->in_table && !rte_update_in(c, new))
+  if (new->sender->in_table && !rte_update_in(new))
     return;
 
-  rte_update2(c, new);
+  rte_update2(new);
 }
 
-static void NONNULL(1,2)
-rte_update2(struct channel *c, rte *new)
+static void NONNULL(1)
+rte_update2(rte *new)
 {
+  struct channel *c = new->sender;
   // struct proto *p = c->proto;
   struct proto_stats *stats = &c->stats;
   const struct filter *filter = c->in_filter;
@@ -1288,7 +1290,7 @@ rte_update2(struct channel *c, rte *new)
   }
 
   /* And recalculate the best route */
-  rte_recalculate(c, nn, new, filtered);
+  rte_recalculate(nn, new, filtered);
   rte_update_unlock();
   return;
 
@@ -1327,10 +1329,11 @@ rte_modify(struct rte_storage *old)
     .net = old->net->n.addr,
     .src = old->src,
     .attrs = old->sender->proto->rte_modify(old, rte_update_pool),
+    .sender = old->sender,
   };
 
   if (new.attrs != old->attrs)
-    rte_recalculate(old->sender, old->net, &new, old->src);
+    rte_recalculate(old->net, &new, old->src);
 
   rte_update_unlock();
 }
@@ -1682,8 +1685,8 @@ again:
 
            /* Discard the route */
            rte_update_lock();
-           rte ew = { .net = e->net->n.addr, .src = e->src };
-           rte_recalculate(e->sender, e->net, &ew, 0);
+           rte ew = { .net = e->net->n.addr, .src = e->src, .sender = e->sender, };
+           rte_recalculate(e->net, &ew, 0);
            rte_update_unlock();
 
            limit--;
@@ -1880,6 +1883,7 @@ rt_next_hop_update_rte(struct rte_storage *old)
     .attrs = a,
     .net = old->net->n.addr,
     .src = old->src,
+    .sender = old->sender,
   };
 
   rte_trace_in(D_ROUTES, old->sender, &e, "updated");
@@ -2240,8 +2244,9 @@ rt_feed_channel_abort(struct channel *c)
  */
 
 static int
-rte_update_in(struct channel *c, rte *new)
+rte_update_in(rte *new)
 {
+  struct channel *c = new->sender;
   struct rtable *tab = c->in_table;
   struct rte_storage *old, **pos;
   net *net;
@@ -2312,7 +2317,6 @@ rte_update_in(struct channel *c, rte *new)
 
   /* Insert the new rte */
   struct rte_storage *e = rte_store(new, net);
-  e->sender = c;
   e->lastmod = current_time();
   e->next = *pos;
   *pos = e;
@@ -2356,7 +2360,7 @@ rt_reload_channel(struct channel *c)
       }
 
       rte eloc = rte_copy(e);
-      rte_update2(c, &eloc);
+      rte_update2(&eloc);
     }
 
     c->reload_next_rte = NULL;
@@ -2508,7 +2512,6 @@ rte_update_out(struct channel *c, struct rte_export_internal *e)
   if (new->attrs)
   {
     struct rte_storage *es = rte_store(new, net);
-    es->sender = c;
     es->lastmod = current_time();
     es->id = e->new->id;
     es->next = *pos;
index 95e9e1ee22ad2568d39bf193f1036aaca0b996a1..01a74655d7f63178e66059d555ab8a6a238cdd17 100644 (file)
@@ -674,10 +674,11 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
       .net = e->n.addr,
       .src = p->p.main_source,
       .attrs = &a0,
+      .sender = c,
     };
 
     e->unreachable = 0;
-    rte_update(c, &e0);
+    rte_update(&e0);
   }
   else if (e->valid && (e->router_id != p->router_id))
   {
@@ -693,10 +694,11 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
       .net = e->n.addr,
       .src = p->p.main_source,
       .attrs = &a0,
+      .sender = c,
     };
 
     e->unreachable = 1;
-    rte_update(c, &e0);
+    rte_update(&e0);
   }
   else
   {
index f5411f9f7ca8057e516ecd7e5134962d0b671990..073108a3d5f27d5653dc23c9b902d661fe36378c 100644 (file)
@@ -1362,9 +1362,10 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
     .net = n,
     .src = s->last_src,
     .attrs = s->cached_rta,
+    .sender = &(s->channel->c),
   };
 
-  rte_update(&(s->channel->c), &e0);
+  rte_update(&e0);
 }
 
 static void
index f3b7e20bc4695339d8fd9a97303364363a5f00a6..2601cfcaf59807538053d555a050d053177e23c2 100644 (file)
@@ -2098,7 +2098,8 @@ again1:
        rte e0 = {
          .attrs = rta_lookup(&a0),
          .src = p->p.main_source,
-         .net = nf->fn.addr, 
+         .net = nf->fn.addr,
+         .sender = p->p.main_channel,
        };
 
        rta_free(nf->old_rta);
@@ -2107,7 +2108,7 @@ again1:
        DBG("Mod rte type %d - %N via %I on iface %s, met %d\n",
            a0.source, nf->fn.addr, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);
 
-       rte_update(p->p.main_channel, &e0);
+       rte_update(&e0);
       }
     }
     else if (nf->old_rta)
index 15ffd109c8c5ad0b890f12722e76f00003068d53..0f847d1bc3c6facc15481c8a2a01ef33b87cccfb 100644 (file)
@@ -166,8 +166,9 @@ perf_loop(void *data)
       .attrs = p->data[i].a,
       .src = p->p.main_source,
       .net = &(p->data[i].net),
+      .sender = P->main_channel,
     };
-    rte_update(P->main_channel, &e0);
+    rte_update(&e0);
   }
 
   clock_gettime(CLOCK_MONOTONIC, &ts_update);
index f6fe7e697af4955206848682d3691296b4bbf6d7..8d45782180b4ed44df950091e59ee7ea788b2dbc 100644 (file)
@@ -78,10 +78,11 @@ pipe_rt_notify(struct channel *src_ch, struct rte_export *export)
        .attrs = a,
        .src = export->new.src,
        .net = net,
+       .sender = dst,
       };
 
       src_ch->table->pipe_busy = 1;
-      rte_update(dst, &e0);
+      rte_update(&e0);
       src_ch->table->pipe_busy = 0;
     }
   else
@@ -93,7 +94,7 @@ pipe_rt_notify(struct channel *src_ch, struct rte_export *export)
 }
 
 static int
-pipe_preexport(struct channel *src_ch, rte *e UNUSED)
+pipe_preexport(struct channel *src_ch, rte *e)
 {
   struct pipe_proto *p = (void *) src_ch->proto;
   struct channel *dst = (src_ch == p->pri) ? p->sec : p->pri;
@@ -102,6 +103,10 @@ pipe_preexport(struct channel *src_ch, rte *e UNUSED)
   if (dst->table->pipe_busy)
     return -1;
 
+  /* Avoid direct loopbacks */
+  if (e->sender == src_ch)
+    return -1;
+
   return 0;
 }
 
index 53696af0383af57952a9ae967039102a852ac24f..9567cb8005d6c9e4a07cfa4f28581829f7dea65c 100644 (file)
@@ -210,10 +210,11 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
     rte e0 = {
       .attrs = &a0,
       .src = p->p.main_source,
-      .net = en->n.addr, 
+      .net = en->n.addr,
+      .sender = p->p.main_channel,
     };
 
-    rte_update(p->p.main_channel, &e0);
+    rte_update(&e0);
   }
   else
     rte_withdraw(p->p.main_channel, en->n.addr, p->p.main_source);
index 79204387e4f9f785ba4d12d171263ccd3fa30f19..a5de7e3f779f5e1171a8c004138341a94f6a92b7 100644 (file)
@@ -130,10 +130,11 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_
   rte e0 = {
     .attrs = &a0,
     .src = p->p.main_source,
-    .net = &pfxr->n, 
+    .net = &pfxr->n,
+    .sender = channel,
   };
 
-  rte_update(channel, &e0);
+  rte_update(&e0);
 }
 
 void
index 9c5886d5558cb2d2c32c6af528c3cd98721c46ce..a46c74646fb4b72755d55d30650184062b363077 100644 (file)
@@ -105,12 +105,13 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
     .attrs = a,
     .src = static_get_source(p, r->index),
     .net = r->net,
+    .sender = p->p.main_channel,
   };
 
   if (r->cmds)
     f_eval_rte(r->cmds, &e0, static_lp);
 
-  rte_update(p->p.main_channel, &e0);
+  rte_update(&e0);
   r->state = SRS_CLEAN;
 
   if (r->cmds)
index e3421ce429d05d001fc61344a851928af09990a9..c9e37a3c51568395e9e783976c6a72286ead35d5 100644 (file)
@@ -303,9 +303,10 @@ krt_learn_announce_update(struct krt_proto *p, struct rte_storage *e)
     .attrs = e->attrs,
     .src = p->p.main_source,
     .net = e->net->n.addr,
+    .sender = p->p.main_channel,
   };
 
-  rte_update(p->p.main_channel, &e0);
+  rte_update(&e0);
 }
 
 static void