]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Internal API change: passing all the rt_notify() data as a single structure.
authorMaria Matejka <mq@jmq.cz>
Tue, 25 Feb 2020 21:13:32 +0000 (22:13 +0100)
committerMaria Matejka <mq@ucw.cz>
Thu, 30 Apr 2020 14:14:26 +0000 (16:14 +0200)
13 files changed:
nest/protocol.h
nest/route.h
nest/rt-table.c
proto/babel/babel.c
proto/bgp/attrs.c
proto/bgp/bgp.h
proto/ospf/topology.c
proto/ospf/topology.h
proto/perf/perf.c
proto/pipe/pipe.c
proto/radv/radv.c
proto/rip/rip.c
sysdep/unix/krt.c

index df31d95bca5f7a586005087d8f77a9a81c04a46a..a6bf79f77b1ab0789be7d95647eb69e01819fbb9 100644 (file)
@@ -210,7 +210,7 @@ struct proto {
 
   void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
   void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
-  void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old);
+  void (*rt_notify)(struct channel *, struct rte_export *);
   void (*neigh_notify)(struct neighbor *neigh);
   int (*preexport)(struct proto *, struct rte **rt, struct linpool *pool);
   void (*reload_routes)(struct channel *);
index 688d26ff8fc60707a98b4f0860ca102048b7077b..892a1deeeafd74e858ad9afb3ab29eec8f5d893c 100644 (file)
@@ -223,6 +223,16 @@ typedef struct rte {
   btime lastmod;                       /* Last modified */
 } rte;
 
+/* Route export structure. Protocols get this structure as an information about
+ * new routes on the channel. */
+struct rte_export {
+  net *net;                            /* Network information */
+  struct rte_src *new_src;             /* New route src (NULL for withdraw) */
+  rte *new;                            /* New route (NULL for withdraw) */
+  struct rte_src *old_src;             /* Old route src */
+  rte *old;                            /* Old route */
+};
+
 #define REF_COW                1               /* Copy this rte on write */
 #define REF_FILTERED   2               /* Route is rejected by import filter */
 #define REF_STALE      4               /* Route is stale in a refresh cycle */
index f8a7990ca23aa7e490cabe2a2bd6dbbdffeb3fa9..51f0a84cb04806ffe2a6a65adc1ba7e48132b1fa 100644 (file)
@@ -543,7 +543,15 @@ do_rt_notify(struct channel *c, net *net, rte *new, rte *old, int refeed)
       rte_trace_out(D_ROUTES, p, old, "removed");
   }
 
-  p->rt_notify(p, c, net, new, old);
+  struct rte_export export = {
+    .net = net,
+    .new_src = new ? new->attrs->src : NULL,
+    .new = new,
+    .old_src = old ? old->attrs->src : NULL,
+    .old = old,
+  };
+
+  p->rt_notify(c, &export);
 
   if (c->out_table && old_exported)
     rte_free_quick(old_exported);
index 9dc0d17ec8ec635fec3d65e1c49dc4321b53348a..0cc633fa694968fa37d69fd179ab7d6955f2e518 100644 (file)
@@ -2121,38 +2121,32 @@ babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED)
  * so store it into our data structures.
  */
 static void
-babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
-               struct rte *new, struct rte *old UNUSED)
+babel_rt_notify(struct channel *c, struct rte_export *export)
 {
-  struct babel_proto *p = (void *) P;
+  struct babel_proto *p = (void *) c->proto;
   struct babel_entry *e;
 
-  if (new)
+  if (export->new)
   {
     /* Update */
-    uint rt_seqno;
-    uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0);
+    uint rt_metric = ea_get_int(export->new->attrs->eattrs, EA_BABEL_METRIC, 0);
+    uint rt_seqno = ea_get_int(export->new->attrs->eattrs, EA_BABEL_SEQNO, p->update_seqno);
     u64 rt_router_id;
 
-    if (new->attrs->src->proto == P)
-    {
-      rt_seqno = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
-      memcpy(&rt_router_id, ea_find(new->attrs->eattrs, EA_BABEL_ROUTER_ID)->u.ptr->data, sizeof(u64));
-    }
+    eattr *ea;
+    if (ea = ea_find(export->new->attrs->eattrs, EA_BABEL_ROUTER_ID))
+      memcpy(&rt_router_id, ea->u.ptr->data, sizeof(u64));
     else
-    {
-      rt_seqno = p->router_id;
-      rt_router_id = p->router_id;
-    }
+      rt_router_id = p->router_id; 
 
     if (rt_metric > BABEL_INFINITY)
     {
       log(L_WARN "%s: Invalid babel_metric value %u for route %N",
-         p->p.name, rt_metric, net->n.addr);
+         p->p.name, rt_metric, export->net->n.addr);
       rt_metric = BABEL_INFINITY;
     }
 
-    e = babel_get_entry(p, net->n.addr);
+    e = babel_get_entry(p, export->net->n.addr);
 
     /* Activate triggered updates */
     if ((e->valid != BABEL_ENTRY_VALID) ||
@@ -2170,7 +2164,7 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
   else
   {
     /* Withdraw */
-    e = babel_find_entry(p, net->n.addr);
+    e = babel_find_entry(p, export->net->n.addr);
 
     if (!e || e->valid != BABEL_ENTRY_VALID)
       return;
index 59a82f95d2d204fb0e1da9a4c140109e86bdfb25..281b98890eca373bcf7190ac3eb1d46897384981 100644 (file)
@@ -1802,31 +1802,31 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
 }
 
 void
-bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old)
+bgp_rt_notify(struct channel *C, struct rte_export *e)
 {
-  struct bgp_proto *p = (void *) P;
+  struct bgp_proto *p = (void *) C->proto;
   struct bgp_channel *c = (void *) C;
   struct bgp_bucket *buck;
   struct bgp_prefix *px;
   u32 path;
 
-  if (new)
+  if (e->new)
   {
-    struct ea_list *attrs = bgp_update_attrs(p, c, new, new->attrs->eattrs, bgp_linpool2);
+    struct ea_list *attrs = bgp_update_attrs(p, c, e->new, e->new->attrs->eattrs, bgp_linpool2);
 
     /* If attributes are invalid, we fail back to withdraw */
     buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c);
-    path = new->attrs->src->global_id;
+    path = e->new_src->global_id;
 
     lp_flush(bgp_linpool2);
   }
   else
   {
     buck = bgp_get_withdraw_bucket(c);
-    path = old->attrs->src->global_id;
+    path = e->old_src->global_id;
   }
 
-  px = bgp_get_prefix(c, n->n.addr, c->add_path_tx ? path : 0);
+  px = bgp_get_prefix(c, e->net->n.addr, c->add_path_tx ? path : 0);
   add_tail(&buck->prefixes, &px->buck_node);
 
   bgp_schedule_packet(p->conn, c, PKT_UPDATE);
index baa6cf32e4abd4af539f4c6eae44480677949c93..ef01296d17224f9e7fc71657056093d8080117f0 100644 (file)
@@ -583,7 +583,7 @@ int bgp_rte_better(struct rte *, struct rte *);
 int bgp_rte_mergable(rte *pri, rte *sec);
 int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best);
 struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
-void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old);
+void bgp_rt_notify(struct channel *C, struct rte_export *e);
 int bgp_preexport(struct proto *, struct rte **, struct linpool *);
 int bgp_get_attr(const struct eattr *e, byte *buf, int buflen);
 void bgp_get_route_info(struct rte *, byte *buf);
index c8ec730a1e44d581bb2da4827e069c35ebf78292..3822e4c02225b6c3e644d981b62943334aa9a976 100644 (file)
@@ -1303,9 +1303,9 @@ find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
 }
 
 void
-ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED)
+ospf_rt_notify(struct channel *ch, struct rte_export *e)
 {
-  struct ospf_proto *p = (struct ospf_proto *) P;
+  struct ospf_proto *p = (struct ospf_proto *) ch->proto;
   struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */
   ort *nf;
 
@@ -1320,9 +1320,9 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
   if ((p->areano == 1) && oa_is_nssa(HEAD(p->area_list)))
     oa = HEAD(p->area_list);
 
-  if (!new)
+  if (!e->new)
   {
-    nf = fib_find(&p->rtf, n->n.addr);
+    nf = fib_find(&p->rtf, e->net->n.addr);
 
     if (!nf || !nf->external_rte)
       return;
@@ -1340,7 +1340,7 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
   ASSERT(p->asbr);
 
   /* Get route attributes */
-  rta *a = new->attrs;
+  rta *a = e->new->attrs;
   eattr *m1a = ea_find(a->eattrs, EA_OSPF_METRIC1);
   eattr *m2a = ea_find(a->eattrs, EA_OSPF_METRIC2);
   uint m1 = m1a ? m1a->u.data : 0;
@@ -1349,14 +1349,14 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
   if (m1 > LSINFINITY)
   {
     log(L_WARN "%s: Invalid ospf_metric1 value %u for route %N",
-       p->p.name, m1, n->n.addr);
+       p->p.name, m1, e->net->n.addr);
     m1 = LSINFINITY;
   }
 
   if (m2 > LSINFINITY)
   {
     log(L_WARN "%s: Invalid ospf_metric2 value %u for route %N",
-       p->p.name, m2, n->n.addr);
+       p->p.name, m2, e->net->n.addr);
     m2 = LSINFINITY;
   }
 
@@ -1380,12 +1380,12 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
     if (ipa_zero(fwd))
     {
       log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %N",
-         p->p.name, n->n.addr);
+         p->p.name, e->net->n.addr);
       return;
     }
   }
 
-  nf = fib_get(&p->rtf, n->n.addr);
+  nf = fib_get(&p->rtf, e->net->n.addr);
   ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1, p->vpn_pe);
   nf->external_rte = 1;
 }
index 535d1f1bb9aa3a83e779a1e631c2c8ac1b69b44d..9df70027d97a74448ef29b7a7d65ca5afb284aa5 100644 (file)
@@ -200,7 +200,7 @@ void ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 d
 void ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode, u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit, int dn);
 void ospf_originate_gr_lsa(struct ospf_proto *p, struct ospf_iface *ifa);
 
-void ospf_rt_notify(struct proto *P, struct channel *ch, net *n, rte *new, rte *old);
+void ospf_rt_notify(struct channel *ch, struct rte_export *e);
 void ospf_update_topology(struct ospf_proto *p);
 
 struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 domain, u32 lsa, u32 rtr, u32 type);
index ec2a9014400087aa81e3d34f8ab6ee01e2fffdad..452821b8c14ca2087b94e2066a6d67ddf0b32ea8 100644 (file)
@@ -204,9 +204,9 @@ perf_loop(void *data)
 }
 
 static void
-perf_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net UNUSED, struct rte *new UNUSED, struct rte *old UNUSED)
+perf_rt_notify(struct channel *c, struct rte_export *e UNUSED)
 {
-  struct perf_proto *p = (struct perf_proto *) P;
+  struct perf_proto *p = (struct perf_proto *) c->proto;
   p->exp++;
   return;
 }
index d935d16b4fd5bf8014e32ce22098068d51a831ce..e5b27717ffc5d3bd687100b0294a63c4bea0f523 100644 (file)
 #include "pipe.h"
 
 static void
-pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old)
+pipe_rt_notify(struct channel *src_ch, struct rte_export *export)
 {
-  struct pipe_proto *p = (void *) P;
+  struct pipe_proto *p = (void *) src_ch->proto;
   struct channel *dst = (src_ch == p->pri) ? p->sec : p->pri;
-  struct rte_src *src;
-
-  rte e0 = {}, *e = &e0;
-  rta *a;
 
-  if (!new && !old)
+  if (!export->new && !export->old)
     return;
 
   if (dst->table->pipe_busy)
     {
       log(L_ERR "Pipe loop detected when sending %N to table %s",
-         n->n.addr, dst->table->name);
+         export->net->n.addr, dst->table->name);
       return;
     }
 
-  if (new)
+  if (export->new)
     {
-      a = alloca(rta_size(new->attrs));
-      memcpy(a, new->attrs, rta_size(new->attrs));
+      rta *a = alloca(rta_size(export->new->attrs));
+      memcpy(a, export->new->attrs, rta_size(export->new->attrs));
 
       a->cached = 0;
+      a->uc = 0;
       a->hostentry = NULL;
 
-      e->attrs = rta_lookup(a);
-      e->pflags = 0;
+      rte e0 = {
+       .attrs = rta_lookup(a),
+      };
 
-      src = a->src;
+      src_ch->table->pipe_busy = 1;
+      rte_update(dst, export->net->n.addr, &e0);
+      src_ch->table->pipe_busy = 0;
     }
   else
     {
-      e = NULL;
-      src = old->attrs->src;
+      src_ch->table->pipe_busy = 1;
+      rte_withdraw(dst, export->net->n.addr, export->old_src);
+      src_ch->table->pipe_busy = 0;
     }
-
-  src_ch->table->pipe_busy = 1;
-  if (e)
-    rte_update(dst, n->n.addr, e);
-  else
-    rte_withdraw(dst, n->n.addr, src);
-  src_ch->table->pipe_busy = 0;
 }
 
 static int
index b4235917053365b80b116ef4742002502df3610c..042d37696494e81613d87078edd6148c6de9d435 100644 (file)
@@ -406,17 +406,17 @@ radv_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
 }
 
 static void
-radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED)
+radv_rt_notify(struct channel *ch, struct rte_export *e)
 {
-  struct radv_proto *p = (struct radv_proto *) P;
-  struct radv_config *cf = (struct radv_config *) (P->cf);
+  struct radv_proto *p = (struct radv_proto *) ch->proto;
+  struct radv_config *cf = (struct radv_config *) (ch->proto->cf);
   struct radv_route *rt;
   eattr *ea;
 
-  if (radv_net_match_trigger(cf, n))
+  if (radv_net_match_trigger(cf, e->net))
   {
     u8 old_active = p->active;
-    p->active = !!new;
+    p->active = !!e->new;
 
     if (p->active == old_active)
       return;
@@ -440,15 +440,15 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
    * And yes, we exclude the trigger route on purpose.
    */
 
-  if (new)
+  if (e->new)
   {
     /* Update */
 
-    ea = ea_find(new->attrs->eattrs, EA_RA_PREFERENCE);
+    ea = ea_find(e->new->attrs->eattrs, EA_RA_PREFERENCE);
     uint preference = ea ? ea->u.data : RA_PREF_MEDIUM;
     uint preference_set = !!ea;
 
-    ea = ea_find(new->attrs->eattrs, EA_RA_LIFETIME);
+    ea = ea_find(e->new->attrs->eattrs, EA_RA_LIFETIME);
     uint lifetime = ea ? ea->u.data : 0;
     uint lifetime_set = !!ea;
 
@@ -457,14 +457,14 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
        (preference != RA_PREF_HIGH))
     {
       log(L_WARN "%s: Invalid ra_preference value %u on route %N",
-         p->p.name, preference, n->n.addr);
+         p->p.name, preference, e->net->n.addr);
       preference = RA_PREF_MEDIUM;
       preference_set = 1;
       lifetime = 0;
       lifetime_set = 1;
     }
 
-    rt = fib_get(&p->routes, n->n.addr);
+    rt = fib_get(&p->routes, e->net->n.addr);
 
     /* Ignore update if nothing changed */
     if (rt->valid &&
@@ -487,7 +487,7 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
   else
   {
     /* Withdraw */
-    rt = fib_find(&p->routes, n->n.addr);
+    rt = fib_find(&p->routes, e->net->n.addr);
 
     if (!rt || !rt->valid)
       return;
index f56fb6c4dff8f81ed1bbd394cf459b2069310cf3..5ac8a10668bfcf22684a324fef0f13749904913e 100644 (file)
@@ -309,31 +309,31 @@ rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from)
  * it into our data structures.
  */
 static void
-rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, struct rte *new,
-             struct rte *old UNUSED)
+rip_rt_notify(struct channel *ch, struct rte_export *e)
 {
-  struct rip_proto *p = (struct rip_proto *) P;
+  struct rip_proto *p = (struct rip_proto *) ch->proto;
   struct rip_entry *en;
   int old_metric;
 
-  if (new)
+  if (e->new)
   {
     /* Update */
-    u32 rt_tag = ea_get_int(new->attrs->eattrs, EA_RIP_TAG, 0);
-    u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1);
-    struct iface *rt_from = (struct iface *) ea_get_int(new->attrs->eattrs, EA_RIP_FROM, 0);
+    rta *a = e->new->attrs;
+    u32 rt_tag = ea_get_int(a->eattrs, EA_RIP_TAG, 0);
+    u32 rt_metric = ea_get_int(a->eattrs, EA_RIP_METRIC, 1);
+    struct iface *rt_from = (struct iface *) ea_get_int(a->eattrs, EA_RIP_FROM, 0);
 
     if (rt_metric > p->infinity)
     {
       log(L_WARN "%s: Invalid rip_metric value %u for route %N",
-         p->p.name, rt_metric, net->n.addr);
+         p->p.name, rt_metric, e->net->n.addr);
       rt_metric = p->infinity;
     }
 
     if (rt_tag > 0xffff)
     {
       log(L_WARN "%s: Invalid rip_tag value %u for route %N",
-         p->p.name, rt_tag, net->n.addr);
+         p->p.name, rt_tag, e->net->n.addr);
       rt_metric = p->infinity;
       rt_tag = 0;
     }
@@ -345,7 +345,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
      * collection.
      */
 
-    en = fib_get(&p->rtable, net->n.addr);
+    en = fib_get(&p->rtable, e->net->n.addr);
 
     old_metric = en->valid ? en->metric : -1;
 
@@ -353,13 +353,13 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
     en->metric = rt_metric;
     en->tag = rt_tag;
     en->from = rt_from;
-    en->iface = new->attrs->nh.iface;
-    en->next_hop = new->attrs->nh.gw;
+    en->iface = a->nh.iface;
+    en->next_hop = a->nh.gw;
   }
   else
   {
     /* Withdraw */
-    en = fib_find(&p->rtable, net->n.addr);
+    en = fib_find(&p->rtable, e->net->n.addr);
 
     if (!en || en->valid != RIP_ENTRY_VALID)
       return;
index 7e89a5900004b16ccbc4f12b2ea18e75864cc9ac..16b3d2e147b8ad1b91ecb0b3bbe7ea1fb6c40bfb 100644 (file)
@@ -889,10 +889,9 @@ krt_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
 }
 
 static void
-krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net,
-             rte *new, rte *old)
+krt_rt_notify(struct channel *ch, struct rte_export *e)
 {
-  struct krt_proto *p = (struct krt_proto *) P;
+  struct krt_proto *p = (struct krt_proto *) ch->proto;
 
   if (config->shutdown)
     return;
@@ -904,13 +903,13 @@ krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net,
    * but if we processed the update as usual, we would send withdraw to the
    * kernel, which would remove the new imported route instead.
    */
-  rte *best = net->routes;
-  if (!new && best && (best->attrs->src->proto == P))
+  rte *best = e->net->routes;
+  if (!e->new && best && (best->attrs->src->proto == ch->proto))
     return;
 #endif
 
   if (p->initialized)          /* Before first scan we don't touch the routes */
-    krt_replace_rte(p, net, new, old);
+    krt_replace_rte(p, e->net, e->new, e->old);
 }
 
 static void