mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-13 22:58:42 +00:00
Route import API redefinition.
Hidden rte_get_temp() into rte_update(). Split rte_update() / rte_withdraw().
This commit is contained in:
parent
b8b900e803
commit
aac08f12a7
@ -637,18 +637,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);
|
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);
|
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
|
#endif
|
||||||
|
50
nest/route.h
50
nest/route.h
@ -301,6 +301,51 @@ static inline int rte_is_filtered(rte *r) { return !!(r->flags & REF_FILTERED);
|
|||||||
#define RIC_REJECT -1 /* Rejected by protocol */
|
#define RIC_REJECT -1 /* Rejected by protocol */
|
||||||
#define RIC_DROP -2 /* Silently dropped 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, const 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, const net_addr *net, struct rte_src *src);
|
||||||
|
|
||||||
extern list routing_tables;
|
extern list routing_tables;
|
||||||
struct config;
|
struct config;
|
||||||
|
|
||||||
@ -319,9 +364,6 @@ static inline net *net_get(rtable *tab, const net_addr *addr) { return (net *) f
|
|||||||
void *net_route(rtable *tab, const net_addr *n);
|
void *net_route(rtable *tab, const net_addr *n);
|
||||||
int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
|
int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
|
||||||
rte *rte_find(net *net, struct rte_src *src);
|
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);
|
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);
|
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);
|
void rt_refresh_begin(rtable *t, struct channel *c);
|
||||||
@ -331,6 +373,7 @@ void rt_schedule_prune(rtable *t);
|
|||||||
void rte_dump(rte *);
|
void rte_dump(rte *);
|
||||||
void rte_free(rte *);
|
void rte_free(rte *);
|
||||||
rte *rte_do_cow(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; }
|
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);
|
rte *rte_cow_rta(rte *r, linpool *lp);
|
||||||
void rte_init_tmp_attrs(struct rte *r, linpool *lp, uint max);
|
void rte_init_tmp_attrs(struct rte *r, linpool *lp, uint max);
|
||||||
@ -341,7 +384,6 @@ void rt_dump(rtable *);
|
|||||||
void rt_dump_all(void);
|
void rt_dump_all(void);
|
||||||
int rt_feed_channel(struct channel *c);
|
int rt_feed_channel(struct channel *c);
|
||||||
void rt_feed_channel_abort(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);
|
int rt_reload_channel(struct channel *c);
|
||||||
void rt_reload_channel_abort(struct channel *c);
|
void rt_reload_channel_abort(struct channel *c);
|
||||||
void rt_prune_sync(rtable *t, int all);
|
void rt_prune_sync(rtable *t, int all);
|
||||||
|
@ -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);
|
DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
|
||||||
|
|
||||||
/* Use iface ID as local source ID */
|
/* Use iface ID as local source ID */
|
||||||
struct rte_src *src = rt_get_source(P, ad->iface->index);
|
rte_withdraw(c, net, rt_get_source(P, ad->iface->index));
|
||||||
rte_update2(c, net, NULL, src);
|
|
||||||
}
|
}
|
||||||
else if (flags & IF_CHANGE_UP)
|
else if (flags & IF_CHANGE_UP)
|
||||||
{
|
{
|
||||||
rta *a;
|
|
||||||
rte *e;
|
|
||||||
|
|
||||||
DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
|
DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
|
||||||
|
|
||||||
if (cf->check_link && !(ad->iface->flags & IF_LINK_UP))
|
if (cf->check_link && !(ad->iface->flags & IF_LINK_UP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Use iface ID as local source ID */
|
|
||||||
struct rte_src *src = rt_get_source(P, ad->iface->index);
|
|
||||||
|
|
||||||
rta a0 = {
|
rta a0 = {
|
||||||
.src = src,
|
/* Use iface ID as local source ID */
|
||||||
|
.src = rt_get_source(P, ad->iface->index),
|
||||||
.source = RTS_DEVICE,
|
.source = RTS_DEVICE,
|
||||||
.scope = SCOPE_UNIVERSE,
|
.scope = SCOPE_UNIVERSE,
|
||||||
.dest = RTD_UNICAST,
|
.dest = RTD_UNICAST,
|
||||||
.nh.iface = ad->iface,
|
.nh.iface = ad->iface,
|
||||||
};
|
};
|
||||||
|
rte e0 = {
|
||||||
a = rta_lookup(&a0);
|
.attrs = rta_lookup(&a0),
|
||||||
e = rte_get_temp(a);
|
};
|
||||||
e->pflags = 0;
|
rte_update(c, net, &e0);
|
||||||
rte_update2(c, net, e, src);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
102
nest/rt-table.c
102
nest/rt-table.c
@ -269,27 +269,6 @@ rte_find(net *net, struct rte_src *src)
|
|||||||
return e;
|
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 *e = sl_alloc(rte_slab);
|
|
||||||
|
|
||||||
e->attrs = a;
|
|
||||||
e->id = 0;
|
|
||||||
e->flags = 0;
|
|
||||||
e->pref = 0;
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
rte *
|
rte *
|
||||||
rte_do_cow(rte *r)
|
rte_do_cow(rte *r)
|
||||||
{
|
{
|
||||||
@ -301,6 +280,18 @@ rte_do_cow(rte *r)
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rte *
|
||||||
|
rte_store(rte *r)
|
||||||
|
{
|
||||||
|
rte *e = sl_alloc(rte_slab);
|
||||||
|
memcpy(e, r, sizeof(rte));
|
||||||
|
if (e->attrs->aflags & RTAF_CACHED)
|
||||||
|
e->attrs = rta_clone(r->attrs);
|
||||||
|
else
|
||||||
|
e->attrs = rta_lookup(r->attrs);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rte_cow_rta - get a private writable copy of &rte with writable &rta
|
* rte_cow_rta - get a private writable copy of &rte with writable &rta
|
||||||
* @r: a route entry to be copied
|
* @r: a route entry to be copied
|
||||||
@ -1397,49 +1388,7 @@ rte_unhide_dummy_routes(net *net, rte **dummy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* 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
|
|
||||||
rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
||||||
{
|
{
|
||||||
// struct proto *p = c->proto;
|
// struct proto *p = c->proto;
|
||||||
@ -1543,6 +1492,29 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
rte_update_unlock();
|
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, const net_addr *n, struct rte_src *src)
|
||||||
|
{
|
||||||
|
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, const net_addr *n, struct rte *new)
|
||||||
|
{
|
||||||
|
ASSERT(new);
|
||||||
|
ASSERT(new->attrs);
|
||||||
|
ASSERT(new->attrs->src);
|
||||||
|
|
||||||
|
rte *e = sl_alloc(rte_slab);
|
||||||
|
*e = *new;
|
||||||
|
|
||||||
|
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
|
/* Independent call to rte_announce(), used from next hop
|
||||||
recalculation, outside of rte_update(). new must be non-NULL */
|
recalculation, outside of rte_update(). new must be non-NULL */
|
||||||
static inline void
|
static inline void
|
||||||
@ -2507,7 +2479,7 @@ rt_feed_channel_abort(struct channel *c)
|
|||||||
* Import table
|
* Import table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
static int
|
||||||
rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
||||||
{
|
{
|
||||||
struct rtable *tab = c->in_table;
|
struct rtable *tab = c->in_table;
|
||||||
|
@ -647,15 +647,18 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
|
|||||||
if (!neigh_find(&p->p, r->next_hop, r->neigh->ifa->iface, 0))
|
if (!neigh_find(&p->p, r->next_hop, r->neigh->ifa->iface, 0))
|
||||||
a0.nh.flags = RNF_ONLINK;
|
a0.nh.flags = RNF_ONLINK;
|
||||||
|
|
||||||
rta *a = rta_lookup(&a0);
|
rte e0 = {
|
||||||
rte *rte = rte_get_temp(a);
|
.attrs = rta_lookup(&a0),
|
||||||
rte->u.babel.seqno = r->seqno;
|
.u.babel = {
|
||||||
rte->u.babel.metric = r->metric;
|
.seqno = r->seqno,
|
||||||
rte->u.babel.router_id = r->router_id;
|
.metric = r->metric,
|
||||||
rte->pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID);
|
.router_id = r->router_id,
|
||||||
|
},
|
||||||
|
.pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID),
|
||||||
|
};
|
||||||
|
|
||||||
e->unreachable = 0;
|
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))
|
else if (e->valid && (e->router_id != p->router_id))
|
||||||
{
|
{
|
||||||
@ -667,20 +670,19 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
|
|||||||
.dest = RTD_UNREACHABLE,
|
.dest = RTD_UNREACHABLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
rta *a = rta_lookup(&a0);
|
rte e0 = {
|
||||||
rte *rte = rte_get_temp(a);
|
.attrs = &a0,
|
||||||
memset(&rte->u.babel, 0, sizeof(rte->u.babel));
|
.pref = 1,
|
||||||
rte->pflags = 0;
|
};
|
||||||
rte->pref = 1;
|
|
||||||
|
|
||||||
e->unreachable = 1;
|
e->unreachable = 1;
|
||||||
rte_update2(c, e->n.addr, rte, p->p.main_source);
|
rte_update(c, e->n.addr, &e0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Retraction */
|
/* Retraction */
|
||||||
e->unreachable = 0;
|
e->unreachable = 0;
|
||||||
rte_update2(c, e->n.addr, NULL, p->p.main_source);
|
rte_withdraw(c, e->n.addr, p->p.main_source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,7 +692,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;
|
struct channel *c = (e->n.addr->type == NET_IP4) ? p->ip4_channel : p->ip6_channel;
|
||||||
e->unreachable = 0;
|
e->unreachable = 0;
|
||||||
rte_update2(c, e->n.addr, NULL, p->p.main_source);
|
rte_withdraw(c, e->n.addr, p->p.main_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1348,7 +1348,7 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
|
|||||||
if (!a0)
|
if (!a0)
|
||||||
{
|
{
|
||||||
/* Route withdraw */
|
/* Route withdraw */
|
||||||
rte_update3(&s->channel->c, n, NULL, s->last_src);
|
rte_withdraw(&(s->channel->c), n, s->last_src);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1363,13 +1363,12 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
|
|||||||
a0->eattrs = ea;
|
a0->eattrs = ea;
|
||||||
}
|
}
|
||||||
|
|
||||||
rta *a = rta_clone(s->cached_rta);
|
rte e0 = {
|
||||||
rte *e = rte_get_temp(a);
|
.attrs = rta_clone(s->cached_rta),
|
||||||
|
.u.bgp.stale = -1,
|
||||||
|
};
|
||||||
|
|
||||||
e->pflags = 0;
|
rte_update(&(s->channel->c), n, &e0);
|
||||||
e->u.bgp.suppressed = 0;
|
|
||||||
e->u.bgp.stale = -1;
|
|
||||||
rte_update3(&s->channel->c, n, e, s->last_src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2056,27 +2056,29 @@ again1:
|
|||||||
|
|
||||||
if (reload || ort_changed(nf, &a0))
|
if (reload || ort_changed(nf, &a0))
|
||||||
{
|
{
|
||||||
rta *a = rta_lookup(&a0);
|
rte e0 = {
|
||||||
rte *e = rte_get_temp(a);
|
.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);
|
rta_free(nf->old_rta);
|
||||||
nf->old_rta = rta_clone(a);
|
nf->old_rta = rta_clone(e0.attrs);
|
||||||
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);
|
|
||||||
|
|
||||||
if (nf->n.type == RTS_OSPF_EXT2)
|
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? */
|
/* Perhaps onfly if tag is non-zero? */
|
||||||
if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
|
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",
|
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);
|
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)
|
else if (nf->old_rta)
|
||||||
@ -2085,7 +2087,7 @@ again1:
|
|||||||
rta_free(nf->old_rta);
|
rta_free(nf->old_rta);
|
||||||
nf->old_rta = NULL;
|
nf->old_rta = NULL;
|
||||||
|
|
||||||
rte_update(&p->p, nf->fn.addr, NULL);
|
rte_withdraw(p->p.main_channel, nf->fn.addr, p->p.main_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove unused rt entry, some special entries are persistent */
|
/* Remove unused rt entry, some special entries are persistent */
|
||||||
@ -2101,7 +2103,6 @@ again1:
|
|||||||
}
|
}
|
||||||
FIB_ITERATE_END;
|
FIB_ITERATE_END;
|
||||||
|
|
||||||
|
|
||||||
WALK_LIST(oa, p->area_list)
|
WALK_LIST(oa, p->area_list)
|
||||||
{
|
{
|
||||||
/* Cleanup ASBR hash tables */
|
/* Cleanup ASBR hash tables */
|
||||||
|
@ -160,18 +160,17 @@ perf_loop(void *data)
|
|||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts_generated);
|
clock_gettime(CLOCK_MONOTONIC, &ts_generated);
|
||||||
|
|
||||||
for (uint i=0; i<N; i++) {
|
for (uint i=0; i<N; i++)
|
||||||
rte *e = rte_get_temp(p->data[i].a);
|
{
|
||||||
e->pflags = 0;
|
rte e0 = { .attrs = p->data[i].a, };
|
||||||
|
rte_update(P->main_channel, &(p->data[i].net), &e0);
|
||||||
rte_update(P, &(p->data[i].net), e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts_update);
|
clock_gettime(CLOCK_MONOTONIC, &ts_update);
|
||||||
|
|
||||||
if (!p->keep)
|
if (!p->keep)
|
||||||
for (uint i=0; i<N; i++)
|
for (uint i=0; i<N; i++)
|
||||||
rte_update(P, &(p->data[i].net), NULL);
|
rte_withdraw(P->main_channel, &(p->data[i].net), p->p.main_source);
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts_withdraw);
|
clock_gettime(CLOCK_MONOTONIC, &ts_withdraw);
|
||||||
|
|
||||||
|
@ -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 channel *dst = (src_ch == p->pri) ? p->sec : p->pri;
|
||||||
struct rte_src *src;
|
struct rte_src *src;
|
||||||
|
|
||||||
rte *e;
|
rte e0 = {}, *e = &e0;
|
||||||
rta *a;
|
rta *a;
|
||||||
|
|
||||||
if (!new && !old)
|
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->aflags = 0;
|
||||||
a->hostentry = NULL;
|
a->hostentry = NULL;
|
||||||
e = rte_get_temp(a);
|
|
||||||
|
e->attrs = rta_lookup(a);
|
||||||
e->pflags = 0;
|
e->pflags = 0;
|
||||||
|
|
||||||
/* Copy protocol specific embedded attributes. */
|
/* 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;
|
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;
|
src_ch->table->pipe_busy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,21 +188,20 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
|
|||||||
a0.nh.iface = rt->from->ifa->iface;
|
a0.nh.iface = rt->from->ifa->iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
rta *a = rta_lookup(&a0);
|
rte e0 = {
|
||||||
rte *e = rte_get_temp(a);
|
.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)
|
||||||
|
};
|
||||||
|
|
||||||
e->u.rip.from = a0.nh.iface;
|
rte_update(p->p.main_channel, en->n.addr, &e0);
|
||||||
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_update(&p->p, en->n.addr, e);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
rte_withdraw(p->p.main_channel, en->n.addr, p->p.main_source);
|
||||||
/* Withdraw */
|
|
||||||
rte_update(&p->p, en->n.addr, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,19 +127,16 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_
|
|||||||
.dest = RTD_NONE,
|
.dest = RTD_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
rta *a = rta_lookup(&a0);
|
rte e0 = { .attrs = rta_lookup(&a0) };
|
||||||
rte *e = rte_get_temp(a);
|
|
||||||
|
|
||||||
e->pflags = 0;
|
rte_update(channel, &pfxr->n, &e0);
|
||||||
|
|
||||||
rte_update2(channel, &pfxr->n, e, a0.src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
|
rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
|
||||||
{
|
{
|
||||||
struct rpki_proto *p = cache->p;
|
struct rpki_proto *p = cache->p;
|
||||||
rte_update2(channel, &pfxr->n, NULL, p->p.main_source);
|
rte_withdraw(channel, &pfxr->n, p->p.main_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,8 +102,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* We skip rta_lookup() here */
|
/* We skip rta_lookup() here */
|
||||||
rte *e = rte_get_temp(a);
|
rte e0 = { .attrs = a }, *e = &e0;
|
||||||
e->pflags = 0;
|
|
||||||
|
|
||||||
if (r->cmds)
|
if (r->cmds)
|
||||||
{
|
{
|
||||||
@ -119,7 +118,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
|
|||||||
e->net = NULL;
|
e->net = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rte_update2(p->p.main_channel, r->net, e, a->src);
|
rte_update(p->p.main_channel, r->net, e);
|
||||||
r->state = SRS_CLEAN;
|
r->state = SRS_CLEAN;
|
||||||
|
|
||||||
if (r->cmds)
|
if (r->cmds)
|
||||||
@ -131,7 +130,7 @@ withdraw:
|
|||||||
if (r->state == SRS_DOWN)
|
if (r->state == SRS_DOWN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rte_update2(p->p.main_channel, r->net, NULL, a->src);
|
rte_withdraw(p->p.main_channel, r->net, p->p.main_source);
|
||||||
r->state = SRS_DOWN;
|
r->state = SRS_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +296,7 @@ static void
|
|||||||
static_remove_rte(struct static_proto *p, struct static_route *r)
|
static_remove_rte(struct static_proto *p, struct static_route *r)
|
||||||
{
|
{
|
||||||
if (r->state)
|
if (r->state)
|
||||||
rte_update2(p->p.main_channel, r->net, NULL, static_get_source(p, r->index));
|
rte_withdraw(p->p.main_channel, r->net, static_get_source(p, r->index));
|
||||||
|
|
||||||
static_reset_rte(p, r);
|
static_reset_rte(p, r);
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
/* p is NULL iff KRT_SHARED_SOCKET and !scan */
|
||||||
|
|
||||||
int ipv6;
|
int ipv6;
|
||||||
rte *e;
|
|
||||||
net *net;
|
net *net;
|
||||||
sockaddr dst, gate, mask;
|
sockaddr dst, gate, mask;
|
||||||
ip_addr idst, igate, imask;
|
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);
|
net = net_get(p->p.main_channel->table, &ndst);
|
||||||
|
|
||||||
rta a = {
|
rta a = {
|
||||||
.src = p->p.main_source,
|
|
||||||
.source = RTS_INHERIT,
|
.source = RTS_INHERIT,
|
||||||
.scope = SCOPE_UNIVERSE,
|
.scope = SCOPE_UNIVERSE,
|
||||||
};
|
};
|
||||||
@ -549,14 +547,12 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:;
|
||||||
e = rte_get_temp(&a);
|
rte e0 = {}, *e = &e0;
|
||||||
|
e->attrs = &a;
|
||||||
e->net = net;
|
e->net = net;
|
||||||
e->u.krt.src = src;
|
e->u.krt.src = src;
|
||||||
e->u.krt.proto = src2;
|
e->u.krt.proto = src2;
|
||||||
e->u.krt.seen = 0;
|
|
||||||
e->u.krt.best = 0;
|
|
||||||
e->u.krt.metric = 0;
|
|
||||||
|
|
||||||
if (scan)
|
if (scan)
|
||||||
krt_got_route(p, e);
|
krt_got_route(p, e);
|
||||||
|
@ -1488,12 +1488,11 @@ nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint
|
|||||||
static void
|
static void
|
||||||
nl_announce_route(struct nl_parse_state *s)
|
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->net = s->net;
|
||||||
e->u.krt.src = s->krt_src;
|
e->u.krt.src = s->krt_src;
|
||||||
e->u.krt.proto = s->krt_proto;
|
e->u.krt.proto = s->krt_proto;
|
||||||
e->u.krt.seen = 0;
|
|
||||||
e->u.krt.best = 0;
|
|
||||||
e->u.krt.metric = s->krt_metric;
|
e->u.krt.metric = s->krt_metric;
|
||||||
|
|
||||||
if (s->scan)
|
if (s->scan)
|
||||||
@ -1659,7 +1658,6 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
|
|||||||
nl_announce_route(s);
|
nl_announce_route(s);
|
||||||
|
|
||||||
rta *ra = lp_allocz(s->pool, RTA_MAX_SIZE);
|
rta *ra = lp_allocz(s->pool, RTA_MAX_SIZE);
|
||||||
ra->src = p->p.main_source;
|
|
||||||
ra->source = RTS_INHERIT;
|
ra->source = RTS_INHERIT;
|
||||||
ra->scope = SCOPE_UNIVERSE;
|
ra->scope = SCOPE_UNIVERSE;
|
||||||
|
|
||||||
|
@ -298,18 +298,19 @@ krt_uptodate(rte *a, rte *b)
|
|||||||
static void
|
static void
|
||||||
krt_learn_announce_update(struct krt_proto *p, rte *e)
|
krt_learn_announce_update(struct krt_proto *p, rte *e)
|
||||||
{
|
{
|
||||||
net *n = e->net;
|
rte e0 = {
|
||||||
rta *aa = rta_clone(e->attrs);
|
.attrs = rta_clone(e->attrs),
|
||||||
rte *ee = rte_get_temp(aa);
|
.pflags = EA_ID_FLAG(EA_KRT_SOURCE) | EA_ID_FLAG(EA_KRT_METRIC),
|
||||||
ee->pflags = EA_ID_FLAG(EA_KRT_SOURCE) | EA_ID_FLAG(EA_KRT_METRIC);
|
.u.krt = e->u.krt,
|
||||||
ee->u.krt = e->u.krt;
|
};
|
||||||
rte_update(&p->p, n->n.addr, ee);
|
|
||||||
|
rte_update(p->p.main_channel, e->net->n.addr, &e0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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, p->p.main_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when alien route is discovered during scan */
|
/* 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);
|
net *n = net_get(&p->krt_table, n0->n.addr);
|
||||||
rte *m, **mm;
|
rte *m, **mm;
|
||||||
|
|
||||||
e->attrs = rta_lookup(e->attrs);
|
e = rte_store(e);
|
||||||
|
|
||||||
for(mm=&n->routes; m = *mm; mm=&m->next)
|
for(mm=&n->routes; m = *mm; mm=&m->next)
|
||||||
if (krt_same_key(m, e))
|
if (krt_same_key(m, e))
|
||||||
@ -401,7 +402,7 @@ again:
|
|||||||
{
|
{
|
||||||
DBG("%I/%d: deleting\n", n->n.prefix, n->n.pxlen);
|
DBG("%I/%d: deleting\n", n->n.prefix, n->n.pxlen);
|
||||||
if (old_best)
|
if (old_best)
|
||||||
krt_learn_announce_delete(p, n);
|
krt_learn_announce_delete(p, n->n.addr);
|
||||||
|
|
||||||
FIB_ITERATE_PUT(&fit);
|
FIB_ITERATE_PUT(&fit);
|
||||||
fib_delete(fib, n);
|
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);
|
net *n = net_get(&p->krt_table, n0->n.addr);
|
||||||
rte *g, **gg, *best, **bestp, *old_best;
|
rte *g, **gg, *best, **bestp, *old_best;
|
||||||
|
|
||||||
e->attrs = rta_lookup(e->attrs);
|
e = rte_store(e);
|
||||||
|
|
||||||
old_best = n->routes;
|
old_best = n->routes;
|
||||||
for(gg=&n->routes; g = *gg; gg = &g->next)
|
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)
|
if (best)
|
||||||
krt_learn_announce_update(p, best);
|
krt_learn_announce_update(p, best);
|
||||||
else
|
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)
|
if (KRT_CF->learn)
|
||||||
krt_learn_scan(p, e);
|
krt_learn_scan(p, e);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
krt_trace_in_rl(&rl_alien, p, e, "[alien] ignored");
|
krt_trace_in_rl(&rl_alien, p, e, "[alien] ignored");
|
||||||
rte_free(e);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -700,8 +698,6 @@ delete:
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
rte_free(e);
|
|
||||||
|
|
||||||
if (rt_free)
|
if (rt_free)
|
||||||
rte_free(rt_free);
|
rte_free(rt_free);
|
||||||
|
|
||||||
@ -779,7 +775,6 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
rte_free(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user