]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Route import API redefinition.
authorMaria Matejka <mq@jmq.cz>
Tue, 28 Jan 2020 10:42:46 +0000 (11:42 +0100)
committerMaria Matejka <mq@jmq.cz>
Tue, 28 Jan 2020 10:42:46 +0000 (11:42 +0100)
Hidden rte_get_temp() into rte_update().
Split rte_update() / rte_withdraw().

15 files changed:
nest/protocol.h
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/bsd/krt-sock.c
sysdep/linux/netlink.c
sysdep/unix/krt.c

index e4ec7fa2f17bb1468217d9700d8d5abb4bc6a40b..76b8d084138e5e490741a001deacd714ad077f88 100644 (file)
@@ -624,18 +624,4 @@ void *channel_config_new(const struct channel_class *cc, const char *name, uint
 void *channel_config_get(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto);
 int channel_reconfigure(struct channel *c, struct channel_config *cf);
 
-
-/* Moved from route.h to avoid dependency conflicts */
-static inline void rte_update(struct proto *p, const net_addr *n, rte *new) { rte_update2(p->main_channel, n, new, p->main_source); }
-
-static inline void
-rte_update3(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
-{
-  if (c->in_table && !rte_update_in(c, n, new, src))
-    return;
-
-  rte_update2(c, n, new, src);
-}
-
-
 #endif
index d2a07f09741bf0e1714e8c02f49df6ffbbf03135..dc586f7eca8946af070d619f522e4925145d98d6 100644 (file)
@@ -280,6 +280,51 @@ static inline int rte_is_filtered(rte *r) { return !!(r->flags & REF_FILTERED);
 #define RIC_REJECT     -1              /* Rejected by protocol */
 #define RIC_DROP       -2              /* Silently dropped by protocol */
 
+/**
+ * rte_update - enter a new update to a routing table
+ * @c: channel doing the update
+ * @net: network address
+ * @rte: a &rte representing the new route
+ *
+ * This function imports a new route to the appropriate table (via the channel).
+ * Table keys are @net (obligatory) and @rte->attrs->src.
+ * Both the @net and @rte pointers can be local.
+ *
+ * The route attributes (@rte->attrs) are obligatory. They can be also allocated
+ * locally. Anyway, if you use an already-cached attribute object, you shall
+ * call rta_clone() on that object yourself. (This semantics may change in future.)
+ *
+ * If the route attributes are local, you may set @rte->attrs->src to NULL, then
+ * the protocol's default route source will be supplied.
+ *
+ * When rte_update() gets a route, it automatically validates it. This includes
+ * checking for validity of the given network and next hop addresses and also
+ * checking for host-scope or link-scope routes. Then the import filters are
+ * processed and if accepted, the route is passed to route table recalculation.
+ *
+ * The accepted routes are then inserted into the table, replacing the old route
+ * (key is the @net together with @rte->attrs->src). Then the route is announced
+ * to all the channels connected to the table using the standard export mechanism.
+ *
+ * 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, net_addr *net, struct rte *rte);
+
+/**
+ * rte_withdraw - withdraw a route from a routing table
+ * @c: channel doing the withdraw
+ * @net: network address
+ * @src: the route source identifier
+ *
+ * This function withdraws a previously announced route from the table.
+ * No import filter is called. This function is idempotent. If no route
+ * is found under the given key, it does nothing.
+ *
+ * If @src is NULL, the protocol's default route source is used.
+ */
+void rte_withdraw(struct channel *c, net_addr *net, struct rte_src *src);
+
 extern list routing_tables;
 struct config;
 
@@ -296,9 +341,6 @@ static inline net *net_get(rtable *tab, const net_addr *addr) { return (net *) f
 void *net_route(rtable *tab, const net_addr *n);
 int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
 rte *rte_find(net *net, struct rte_src *src);
-rte *rte_get_temp(struct rta *);
-void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
-/* rte_update() moved to protocol.h to avoid dependency conflicts */
 int rt_examine(rtable *t, net_addr *a, struct proto *p, const struct filter *filter);
 rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int silent);
 void rt_refresh_begin(rtable *t, struct channel *c);
@@ -308,6 +350,7 @@ void rt_schedule_prune(rtable *t);
 void rte_dump(rte *);
 void rte_free(rte *);
 rte *rte_do_cow(rte *);
+rte *rte_store(rte *);
 static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r) : r; }
 rte *rte_cow_rta(rte *r, linpool *lp);
 void rte_init_tmp_attrs(struct rte *r, linpool *lp, uint max);
@@ -318,7 +361,6 @@ void rt_dump(rtable *);
 void rt_dump_all(void);
 int rt_feed_channel(struct channel *c);
 void rt_feed_channel_abort(struct channel *c);
-int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
 int rt_reload_channel(struct channel *c);
 void rt_reload_channel_abort(struct channel *c);
 void rt_prune_sync(rtable *t, int all);
index 61f025cea8a28a974e9542dc579db83934f5184e..240cc8fc307c8a43fb4847fdea313edb0230f7c3 100644 (file)
@@ -66,34 +66,27 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
       DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
 
       /* Use iface ID as local source ID */
-      struct rte_src *src = rt_get_source(P, ad->iface->index);
-      rte_update2(c, net, NULL, src);
+      rte_withdraw(c, net, rt_get_source(P, ad->iface->index));
     }
   else if (flags & IF_CHANGE_UP)
     {
-      rta *a;
-      rte *e;
-
       DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
 
       if (cf->check_link && !(ad->iface->flags & IF_LINK_UP))
        return;
 
-      /* Use iface ID as local source ID */
-      struct rte_src *src = rt_get_source(P, ad->iface->index);
-
       rta a0 = {
-       .src = src,
+       /* Use iface ID as local source ID */
+       .src = rt_get_source(P, ad->iface->index),
        .source = RTS_DEVICE,
        .scope = SCOPE_UNIVERSE,
        .dest = RTD_UNICAST,
        .nh.iface = ad->iface,
       };
-
-      a = rta_lookup(&a0);
-      e = rte_get_temp(a);
-      e->pflags = 0;
-      rte_update2(c, net, e, src);
+      rte e0 = {
+       .attrs = rta_lookup(&a0),
+      };
+      rte_update(c, net, &e0);
     }
 }
 
index f95afccd71fce2b0ab179ceab7f70eea91bc2d6a..213418020201e899b83ddf25a319be677d3b2aa9 100644 (file)
@@ -267,35 +267,26 @@ rte_find(net *net, struct rte_src *src)
   return e;
 }
 
-/**
- * rte_get_temp - get a temporary &rte
- * @a: attributes to assign to the new route (a &rta; in case it's
- * un-cached, rte_update() will create a cached copy automatically)
- *
- * Create a temporary &rte and bind it with the attributes @a.
- * Also set route preference to the default preference set for
- * the protocol.
- */
 rte *
-rte_get_temp(rta *a)
+rte_do_cow(rte *r)
 {
   rte *e = sl_alloc(rte_slab);
 
-  e->attrs = a;
-  e->id = 0;
+  memcpy(e, r, sizeof(rte));
+  e->attrs = rta_clone(r->attrs);
   e->flags = 0;
-  e->pref = 0;
   return e;
 }
 
 rte *
-rte_do_cow(rte *r)
+rte_store(rte *r)
 {
   rte *e = sl_alloc(rte_slab);
-
   memcpy(e, r, sizeof(rte));
-  e->attrs = rta_clone(r->attrs);
-  e->flags = 0;
+  if (e->attrs->aflags & RTAF_CACHED)
+    e->attrs = rta_clone(r->attrs);
+  else
+    e->attrs = rta_lookup(r->attrs);
   return e;
 }
 
@@ -1382,49 +1373,7 @@ rte_unhide_dummy_routes(net *net, rte **dummy)
   }
 }
 
-/**
- * rte_update - enter a new update to a routing table
- * @table: table to be updated
- * @c: channel doing the update
- * @net: network node
- * @p: protocol submitting the update
- * @src: protocol originating the update
- * @new: a &rte representing the new route or %NULL for route removal.
- *
- * This function is called by the routing protocols whenever they discover
- * a new route or wish to update/remove an existing route. The right announcement
- * sequence is to build route attributes first (either un-cached with @aflags set
- * to zero or a cached one using rta_lookup(); in this case please note that
- * you need to increase the use count of the attributes yourself by calling
- * rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all
- * the appropriate data and finally submit the new &rte by calling rte_update().
- *
- * @src specifies the protocol that originally created the route and the meaning
- * of protocol-dependent data of @new. If @new is not %NULL, @src have to be the
- * same value as @new->attrs->proto. @p specifies the protocol that called
- * rte_update(). In most cases it is the same protocol as @src. rte_update()
- * stores @p in @new->sender;
- *
- * When rte_update() gets any route, it automatically validates it (checks,
- * whether the network and next hop address are valid IP addresses and also
- * whether a normal routing protocol doesn't try to smuggle a host or link
- * scope route to the table), converts all protocol dependent attributes stored
- * in the &rte to temporary extended attributes, consults import filters of the
- * protocol to see if the route should be accepted and/or its attributes modified,
- * stores the temporary attributes back to the &rte.
- *
- * Now, having a "public" version of the route, we
- * automatically find any old route defined by the protocol @src
- * for network @n, replace it by the new one (or removing it if @new is %NULL),
- * recalculate the optimal route for this destination and finally broadcast
- * the change (if any) to all routing protocols by calling rte_announce().
- *
- * All memory used for attribute lists and other temporary allocations is taken
- * from a special linear pool @rte_update_pool and freed when rte_update()
- * finishes.
- */
-
-void
+static void
 rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
 {
   struct proto *p = c->proto;
@@ -1528,6 +1477,37 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
   rte_update_unlock();
 }
 
+static int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
+
+void
+rte_withdraw(struct channel *c, net_addr *n, struct rte_src *src)
+{
+  if (!src)
+    src = c->proto->main_source;
+
+  if (!c->in_table || rte_update_in(c, n, NULL, src))
+    rte_update2(c, n, NULL, src ?: c->proto->main_source);
+}
+
+void
+rte_update(struct channel *c, net_addr *n, struct rte *new)
+{
+  ASSERT(new);
+  ASSERT(new->attrs);
+
+  rte *e = sl_alloc(rte_slab);
+  *e = *new;
+
+  if (!e->attrs->src)
+  {
+    ASSERT(!rta_is_cached(e->attrs));
+    e->attrs->src = c->proto->main_source;
+  }
+
+  if (!c->in_table || rte_update_in(c, n, e, e->attrs->src))
+    rte_update2(c, n, e, e->attrs->src);
+}
+
 /* Independent call to rte_announce(), used from next hop
    recalculation, outside of rte_update(). new must be non-NULL */
 static inline void
@@ -2415,7 +2395,7 @@ rt_feed_channel_abort(struct channel *c)
  *     Import table
  */
 
-int
+static int
 rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
 {
   struct rtable *tab = c->in_table;
index 177ff3a3ed9b924a8b0346a8a8c3ff20865b1602..889528a6c2a616c58882b3bb6d5ddfc13741d59a 100644 (file)
@@ -640,15 +640,18 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
       .nh.iface = r->neigh->ifa->iface,
     };
 
-    rta *a = rta_lookup(&a0);
-    rte *rte = rte_get_temp(a);
-    rte->u.babel.seqno = r->seqno;
-    rte->u.babel.metric = r->metric;
-    rte->u.babel.router_id = r->router_id;
-    rte->pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID);
+    rte e0 = {
+      .attrs = rta_lookup(&a0),
+      .u.babel = {
+       .seqno = r->seqno,
+       .metric = r->metric,
+       .router_id = r->router_id,
+      },
+      .pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID),
+    };
 
     e->unreachable = 0;
-    rte_update2(c, e->n.addr, rte, p->p.main_source);
+    rte_update(c, e->n.addr, &e0);
   }
   else if (e->valid && (e->router_id != p->router_id))
   {
@@ -660,20 +663,19 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
       .dest = RTD_UNREACHABLE,
     };
 
-    rta *a = rta_lookup(&a0);
-    rte *rte = rte_get_temp(a);
-    memset(&rte->u.babel, 0, sizeof(rte->u.babel));
-    rte->pflags = 0;
-    rte->pref = 1;
+    rte e0 = {
+      .attrs = &a0,
+      .pref = 1,
+    };
 
     e->unreachable = 1;
-    rte_update2(c, e->n.addr, rte, p->p.main_source);
+    rte_update(c, e->n.addr, &e0);
   }
   else
   {
     /* Retraction */
     e->unreachable = 0;
-    rte_update2(c, e->n.addr, NULL, p->p.main_source);
+    rte_withdraw(c, e->n.addr, NULL);
   }
 }
 
@@ -683,7 +685,7 @@ babel_announce_retraction(struct babel_proto *p, struct babel_entry *e)
 {
   struct channel *c = (e->n.addr->type == NET_IP4) ? p->ip4_channel : p->ip6_channel;
   e->unreachable = 0;
-  rte_update2(c, e->n.addr, NULL, p->p.main_source);
+  rte_withdraw(c, e->n.addr, NULL);
 }
 
 
index ed878e41597d826a5fcab46aff2ef5810031ad2f..534d723e00873cf742d4097f437003ecb25c6d4b 100644 (file)
@@ -1304,7 +1304,7 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
   if (!a0)
   {
     /* Route withdraw */
-    rte_update3(&s->channel->c, n, NULL, s->last_src);
+    rte_withdraw(&(s->channel->c), n, s->last_src);
     return;
   }
 
@@ -1319,13 +1319,12 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
     a0->eattrs = ea;
   }
 
-  rta *a = rta_clone(s->cached_rta);
-  rte *e = rte_get_temp(a);
+  rte e0 = {
+    .attrs = rta_clone(s->cached_rta),
+    .u.bgp.stale = -1,
+  };
 
-  e->pflags = 0;
-  e->u.bgp.suppressed = 0;
-  e->u.bgp.stale = -1;
-  rte_update3(&s->channel->c, n, e, s->last_src);
+  rte_update(&(s->channel->c), n, &e0);
 }
 
 static void
index b5787b540d6f9f104e213fc17d91ea7ea25b9f7a..16cf60f3c1c36b00e9f9c66d3af90e72ffa9524c 100644 (file)
@@ -2052,27 +2052,29 @@ again1:
 
       if (reload || ort_changed(nf, &a0))
       {
-       rta *a = rta_lookup(&a0);
-       rte *e = rte_get_temp(a);
+       rte e0 = {
+         .attrs = rta_lookup(&a0),
+         .u.ospf.metric1 = nf->old_metric1 = nf->n.metric1,
+         .u.ospf.metric2 = nf->old_metric2 = nf->n.metric2,
+         .u.ospf.tag = nf->old_tag = nf->n.tag,
+         .u.ospf.router_id = nf->old_rid = nf->n.rid,
+         .pflags = EA_ID_FLAG(EA_OSPF_METRIC1) | EA_ID_FLAG(EA_OSPF_ROUTER_ID),
+       };
 
        rta_free(nf->old_rta);
-       nf->old_rta = rta_clone(a);
-       e->u.ospf.metric1 = nf->old_metric1 = nf->n.metric1;
-       e->u.ospf.metric2 = nf->old_metric2 = nf->n.metric2;
-       e->u.ospf.tag = nf->old_tag = nf->n.tag;
-       e->u.ospf.router_id = nf->old_rid = nf->n.rid;
-       e->pflags = EA_ID_FLAG(EA_OSPF_METRIC1) | EA_ID_FLAG(EA_OSPF_ROUTER_ID);
+       nf->old_rta = rta_clone(e0.attrs);
 
        if (nf->n.type == RTS_OSPF_EXT2)
-         e->pflags |= EA_ID_FLAG(EA_OSPF_METRIC2);
+         e0.pflags |= EA_ID_FLAG(EA_OSPF_METRIC2);
 
        /* Perhaps onfly if tag is non-zero? */
        if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
-         e->pflags |= EA_ID_FLAG(EA_OSPF_TAG);
+         e0.pflags |= EA_ID_FLAG(EA_OSPF_TAG);
 
        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, nf->fn.addr, e);
+
+       rte_update(p->p.main_channel, nf->fn.addr, &e0);
       }
     }
     else if (nf->old_rta)
@@ -2081,7 +2083,7 @@ again1:
       rta_free(nf->old_rta);
       nf->old_rta = NULL;
 
-      rte_update(&p->p, nf->fn.addr, NULL);
+      rte_withdraw(p->p.main_channel, nf->fn.addr, NULL);
     }
 
     /* Remove unused rt entry, some special entries are persistent */
@@ -2097,7 +2099,6 @@ again1:
   }
   FIB_ITERATE_END;
 
-
   WALK_LIST(oa, p->area_list)
   {
     /* Cleanup ASBR hash tables */
index ba401a8a321278e59703c51249eb53b9cc28d005..c0136c37f07a53644cac926081d786623da0c4e3 100644 (file)
@@ -160,18 +160,17 @@ perf_loop(void *data)
 
   clock_gettime(CLOCK_MONOTONIC, &ts_generated);
 
-  for (uint i=0; i<N; i++) {
-    rte *e = rte_get_temp(p->data[i].a);
-    e->pflags = 0;
-
-    rte_update(P, &(p->data[i].net), e);
+  for (uint i=0; i<N; i++)
+  {
+    rte e0 = { .attrs = p->data[i].a, };
+    rte_update(P->main_channel, &(p->data[i].net), &e0);
   }
 
   clock_gettime(CLOCK_MONOTONIC, &ts_update);
 
   if (!p->keep)
     for (uint i=0; i<N; i++)
-      rte_update(P, &(p->data[i].net), NULL);
+      rte_withdraw(P->main_channel, &(p->data[i].net), NULL);
 
   clock_gettime(CLOCK_MONOTONIC, &ts_withdraw);
 
index efb992cab7315924e59f0016116f39e99085d417..e09e2c2749255cebdcfbee9b5db9a9d6a0451382 100644 (file)
@@ -50,7 +50,7 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o
   struct channel *dst = (src_ch == p->pri) ? p->sec : p->pri;
   struct rte_src *src;
 
-  rte *e;
+  rte e0 = {}, *e = &e0;
   rta *a;
 
   if (!new && !old)
@@ -70,7 +70,8 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o
 
       a->aflags = 0;
       a->hostentry = NULL;
-      e = rte_get_temp(a);
+
+      e->attrs = rta_lookup(a);
       e->pflags = 0;
 
       /* Copy protocol specific embedded attributes. */
@@ -93,7 +94,10 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o
     }
 
   src_ch->table->pipe_busy = 1;
-  rte_update2(dst, n->n.addr, e, src);
+  if (e)
+    rte_update(dst, n->n.addr, e);
+  else
+    rte_withdraw(dst, n->n.addr, src);
   src_ch->table->pipe_busy = 0;
 }
 
index 4559310ebb0ff6b0db342677e1b508080c9d9125..05045698e020a6e855610efadbeed307b4bc9c77 100644 (file)
@@ -187,21 +187,20 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
       a0.nh.iface = rt->from->nbr->iface;
     }
 
-    rta *a = rta_lookup(&a0);
-    rte *e = rte_get_temp(a);
-
-    e->u.rip.from = a0.nh.iface;
-    e->u.rip.metric = rt_metric;
-    e->u.rip.tag = rt_tag;
-    e->pflags = EA_ID_FLAG(EA_RIP_METRIC) | EA_ID_FLAG(EA_RIP_TAG);
+    rte e0 = {
+      .attrs = rta_lookup(&a0),
+      .u.rip = {
+       .from = a0.nh.iface,
+       .metric = rt_metric,
+       .tag = rt_tag,
+      },
+      .pflags = EA_ID_FLAG(EA_RIP_METRIC) | EA_ID_FLAG(EA_RIP_TAG)
+    };
 
-    rte_update(&p->p, en->n.addr, e);
+    rte_update(p->p.main_channel, en->n.addr, &e0);
   }
   else
-  {
-    /* Withdraw */
-    rte_update(&p->p, en->n.addr, NULL);
-  }
+    rte_withdraw(p->p.main_channel, en->n.addr, NULL);
 }
 
 /**
index 70cd0cdd1060bec03851466abc9e213a36022661..48a6d07cfb8179aa7668e4f1ac804e1412ec7322 100644 (file)
@@ -127,19 +127,16 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_
     .dest = RTD_NONE,
   };
 
-  rta *a = rta_lookup(&a0);
-  rte *e = rte_get_temp(a);
+  rte e0 = { .attrs = rta_lookup(&a0) };
 
-  e->pflags = 0;
-
-  rte_update2(channel, &pfxr->n, e, a0.src);
+  rte_update(channel, &pfxr->n, &e0);
 }
 
 void
 rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
 {
   struct rpki_proto *p = cache->p;
-  rte_update2(channel, &pfxr->n, NULL, p->p.main_source);
+  rte_withdraw(channel, &pfxr->n, NULL);
 }
 
 
index c899cc87e7ba45c1805c778ec25e1d9014550c4c..b977dfa737db5373ae77b2ffc4293a36e00ef9cf 100644 (file)
@@ -99,13 +99,12 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
     return;
 
   /* We skip rta_lookup() here */
-  rte *e = rte_get_temp(a);
-  e->pflags = 0;
+  rte e0 = { .attrs = a }, *e = &e0;
 
   if (r->cmds)
     f_eval_rte(r->cmds, &e, static_lp);
 
-  rte_update(&p->p, r->net, e);
+  rte_update(p->p.main_channel, r->net, e);
   r->state = SRS_CLEAN;
 
   if (r->cmds)
@@ -117,7 +116,7 @@ withdraw:
   if (r->state == SRS_DOWN)
     return;
 
-  rte_update(&p->p, r->net, NULL);
+  rte_withdraw(p->p.main_channel, r->net, NULL);
   r->state = SRS_DOWN;
 }
 
@@ -250,7 +249,7 @@ static void
 static_remove_rte(struct static_proto *p, struct static_route *r)
 {
   if (r->state)
-    rte_update(&p->p, r->net, NULL);
+    rte_withdraw(p->p.main_channel, r->net, NULL);
 
   static_reset_rte(p, r);
 }
index c2faa23dd44f0ae95be43561b0b4dbcd916790b1..b55df047a3e15b85a2165f03e56bd541f96940a2 100644 (file)
@@ -374,7 +374,6 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
   /* p is NULL iff KRT_SHARED_SOCKET and !scan */
 
   int ipv6;
-  rte *e;
   net *net;
   sockaddr dst, gate, mask;
   ip_addr idst, igate, imask;
@@ -495,7 +494,6 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
   net = net_get(p->p.main_channel->table, &ndst);
 
   rta a = {
-    .src = p->p.main_source,
     .source = RTS_INHERIT,
     .scope = SCOPE_UNIVERSE,
   };
@@ -549,14 +547,12 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
       }
   }
 
- done:
-  e = rte_get_temp(&a);
+ done:;
+  rte e0 = {}, *e = &e0;
+  e->attrs = &a;
   e->net = net;
   e->u.krt.src = src;
   e->u.krt.proto = src2;
-  e->u.krt.seen = 0;
-  e->u.krt.best = 0;
-  e->u.krt.metric = 0;
 
   if (scan)
     krt_got_route(p, e);
index 25c078c17cc7e75e985d7b6435d01d3451a2b5cf..57a4c922ce3301533ea6ae36e4e4e4fba31baa3c 100644 (file)
@@ -1458,12 +1458,11 @@ nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint
 static void
 nl_announce_route(struct nl_parse_state *s)
 {
-  rte *e = rte_get_temp(s->attrs);
+  rte e0 = {}, *e = &e0;
+  e->attrs = s->attrs;
   e->net = s->net;
   e->u.krt.src = s->krt_src;
   e->u.krt.proto = s->krt_proto;
-  e->u.krt.seen = 0;
-  e->u.krt.best = 0;
   e->u.krt.metric = s->krt_metric;
 
   if (s->scan)
@@ -1629,7 +1628,6 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
     nl_announce_route(s);
 
   rta *ra = lp_allocz(s->pool, RTA_MAX_SIZE);
-  ra->src = p->p.main_source;
   ra->source = RTS_INHERIT;
   ra->scope = SCOPE_UNIVERSE;
 
index 42dd12f6e22f250835f4a9ac14b54ebde5ca0d58..75d3f0b4924336f83067bc816ab366b4465e9249 100644 (file)
@@ -298,18 +298,19 @@ krt_uptodate(rte *a, rte *b)
 static void
 krt_learn_announce_update(struct krt_proto *p, rte *e)
 {
-  net *n = e->net;
-  rta *aa = rta_clone(e->attrs);
-  rte *ee = rte_get_temp(aa);
-  ee->pflags = EA_ID_FLAG(EA_KRT_SOURCE) | EA_ID_FLAG(EA_KRT_METRIC);
-  ee->u.krt = e->u.krt;
-  rte_update(&p->p, n->n.addr, ee);
+  rte e0 = {
+    .attrs = rta_clone(e->attrs),
+    .pflags = EA_ID_FLAG(EA_KRT_SOURCE) | EA_ID_FLAG(EA_KRT_METRIC),
+    .u.krt = e->u.krt,
+  };
+
+  rte_update(p->p.main_channel, e->net->n.addr, &e0);
 }
 
 static void
-krt_learn_announce_delete(struct krt_proto *p, net *n)
+krt_learn_announce_delete(struct krt_proto *p, net_addr *n)
 {
-  rte_update(&p->p, n->n.addr, NULL);
+  rte_withdraw(p->p.main_channel, n, NULL);
 }
 
 /* Called when alien route is discovered during scan */
@@ -320,7 +321,7 @@ krt_learn_scan(struct krt_proto *p, rte *e)
   net *n = net_get(&p->krt_table, n0->n.addr);
   rte *m, **mm;
 
-  e->attrs = rta_lookup(e->attrs);
+  e = rte_store(e);
 
   for(mm=&n->routes; m = *mm; mm=&m->next)
     if (krt_same_key(m, e))
@@ -401,7 +402,7 @@ again:
        {
          DBG("%I/%d: deleting\n", n->n.prefix, n->n.pxlen);
          if (old_best)
-           krt_learn_announce_delete(p, n);
+           krt_learn_announce_delete(p, n->n.addr);
 
          FIB_ITERATE_PUT(&fit);
          fib_delete(fib, n);
@@ -433,7 +434,7 @@ krt_learn_async(struct krt_proto *p, rte *e, int new)
   net *n = net_get(&p->krt_table, n0->n.addr);
   rte *g, **gg, *best, **bestp, *old_best;
 
-  e->attrs = rta_lookup(e->attrs);
+  e = rte_store(e);
 
   old_best = n->routes;
   for(gg=&n->routes; g = *gg; gg = &g->next)
@@ -499,7 +500,7 @@ krt_learn_async(struct krt_proto *p, rte *e, int new)
       if (best)
        krt_learn_announce_update(p, best);
       else
-       krt_learn_announce_delete(p, n);
+       krt_learn_announce_delete(p, n->n.addr);
     }
 }
 
@@ -641,10 +642,7 @@ krt_got_route(struct krt_proto *p, rte *e)
       if (KRT_CF->learn)
        krt_learn_scan(p, e);
       else
-       {
-         krt_trace_in_rl(&rl_alien, p, e, "[alien] ignored");
-         rte_free(e);
-       }
+       krt_trace_in_rl(&rl_alien, p, e, "[alien] ignored");
       return;
     }
 #endif
@@ -700,8 +698,6 @@ delete:
   goto done;
 
 done:
-  rte_free(e);
-
   if (rt_free)
     rte_free(rt_free);
 
@@ -779,7 +775,6 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new)
        }
 #endif
     }
-  rte_free(e);
 }
 
 /*