0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-03-21 13:57:04 +00:00

Route: moved rte_src pointer from rta to rte

It is an auxiliary key in the routing table, not a route attribute.
This commit is contained in:
Maria Matejka 2020-04-10 17:08:29 +02:00
parent 7d67c21b12
commit 415d6e299c
17 changed files with 79 additions and 71 deletions

View File

@ -526,7 +526,7 @@
case SA_FROM: RESULT(sa.f_type, ip, rta->from); break; case SA_FROM: RESULT(sa.f_type, ip, rta->from); break;
case SA_GW: RESULT(sa.f_type, ip, rta->nh.gw); break; case SA_GW: RESULT(sa.f_type, ip, rta->nh.gw); break;
case SA_NET: RESULT(sa.f_type, net, (*fs->rte)->net->n.addr); break; case SA_NET: RESULT(sa.f_type, net, (*fs->rte)->net->n.addr); break;
case SA_PROTO: RESULT(sa.f_type, s, rta->src->proto->name); break; case SA_PROTO: RESULT(sa.f_type, s, (*fs->rte)->src->proto->name); break;
case SA_SOURCE: RESULT(sa.f_type, i, rta->source); break; case SA_SOURCE: RESULT(sa.f_type, i, rta->source); break;
case SA_SCOPE: RESULT(sa.f_type, i, rta->scope); break; case SA_SCOPE: RESULT(sa.f_type, i, rta->scope); break;
case SA_DEST: RESULT(sa.f_type, i, rta->dest); break; case SA_DEST: RESULT(sa.f_type, i, rta->dest); break;
@ -561,7 +561,7 @@
{ {
ip_addr ip = v1.val.ip; ip_addr ip = v1.val.ip;
struct iface *ifa = ipa_is_link_local(ip) ? rta->nh.iface : NULL; struct iface *ifa = ipa_is_link_local(ip) ? rta->nh.iface : NULL;
neighbor *n = neigh_find(rta->src->proto, ip, ifa, 0); neighbor *n = neigh_find((*fs->rte)->src->proto, ip, ifa, 0);
if (!n || (n->scope == SCOPE_HOST)) if (!n || (n->scope == SCOPE_HOST))
runtime( "Invalid gw address" ); runtime( "Invalid gw address" );

View File

@ -230,6 +230,7 @@ struct hostentry {
typedef struct rte { typedef struct rte {
struct rte *next; struct rte *next;
net *net; /* Network this RTE belongs to */ 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 */ struct channel *sender; /* Channel used to send the route to the routing table */
struct rta *attrs; /* Attributes of this route */ struct rta *attrs; /* Attributes of this route */
u32 id; /* Table specific route id */ u32 id; /* Table specific route id */
@ -446,7 +447,6 @@ typedef struct rta {
u32 uc; /* Use count */ u32 uc; /* Use count */
u32 hash_key; /* Hash over important fields */ u32 hash_key; /* Hash over important fields */
struct ea_list *eattrs; /* Extended Attribute chain */ struct ea_list *eattrs; /* Extended Attribute chain */
struct rte_src *src; /* Route source that created the route */
struct hostentry *hostentry; /* Hostentry for recursive next-hops */ struct hostentry *hostentry; /* Hostentry for recursive next-hops */
ip_addr from; /* Advertising router */ ip_addr from; /* Advertising router */
u32 igp_metric; /* IGP metric to next hop (for iBGP routes) */ u32 igp_metric; /* IGP metric to next hop (for iBGP routes) */

View File

@ -1099,7 +1099,6 @@ rta_hash(rta *a)
mem_hash_init(&h); mem_hash_init(&h);
#define MIX(f) mem_hash_mix(&h, &(a->f), sizeof(a->f)); #define MIX(f) mem_hash_mix(&h, &(a->f), sizeof(a->f));
#define BMIX(f) mem_hash_mix_num(&h, a->f); #define BMIX(f) mem_hash_mix_num(&h, a->f);
MIX(src);
MIX(hostentry); MIX(hostentry);
MIX(from); MIX(from);
MIX(igp_metric); MIX(igp_metric);
@ -1115,8 +1114,7 @@ rta_hash(rta *a)
static inline int static inline int
rta_same(rta *x, rta *y) rta_same(rta *x, rta *y)
{ {
return (x->src == y->src && return (x->source == y->source &&
x->source == y->source &&
x->scope == y->scope && x->scope == y->scope &&
x->dest == y->dest && x->dest == y->dest &&
x->igp_metric == y->igp_metric && x->igp_metric == y->igp_metric &&
@ -1206,7 +1204,6 @@ rta_lookup(rta *o)
r = rta_copy(o); r = rta_copy(o);
r->hash_key = h; r->hash_key = h;
r->cached = 1; r->cached = 1;
rt_lock_source(r->src);
rt_lock_hostentry(r->hostentry); rt_lock_hostentry(r->hostentry);
rta_insert(r); rta_insert(r);
@ -1225,7 +1222,6 @@ rta__free(rta *a)
if (a->next) if (a->next)
a->next->pprev = a->pprev; a->next->pprev = a->pprev;
rt_unlock_hostentry(a->hostentry); rt_unlock_hostentry(a->hostentry);
rt_unlock_source(a->src);
if (a->nh.next) if (a->nh.next)
nexthop_free(a->nh.next); nexthop_free(a->nh.next);
ea_free(a->eattrs); ea_free(a->eattrs);
@ -1264,8 +1260,8 @@ rta_dump(rta *a)
"RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" }; "RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" };
static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" }; static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" };
debug("p=%s pref=%d uc=%d %s %s%s h=%04x", debug("pref=%d uc=%d %s %s%s h=%04x",
a->src->proto->name, a->pref, a->uc, rts[a->source], ip_scope_text(a->scope), a->pref, a->uc, rts[a->source], ip_scope_text(a->scope),
rtd[a->dest], a->hash_key); rtd[a->dest], a->hash_key);
if (!a->cached) if (!a->cached)
debug(" !CACHED"); debug(" !CACHED");

View File

@ -77,7 +77,6 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
rta a0 = { rta a0 = {
/* Use iface ID as local source ID */ /* Use iface ID as local source ID */
.src = rt_get_source(P, ad->iface->index),
.pref = c->preference, .pref = c->preference,
.source = RTS_DEVICE, .source = RTS_DEVICE,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
@ -85,6 +84,7 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
.nh.iface = ad->iface, .nh.iface = ad->iface,
}; };
rte e0 = { rte e0 = {
.src = rt_get_source(P, ad->iface->index),
.attrs = &a0, .attrs = &a0,
}; };
rte_update(c, net, &e0); rte_update(c, net, &e0);

View File

@ -56,7 +56,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
if (d->verbose && !rta_is_cached(a) && a->eattrs) if (d->verbose && !rta_is_cached(a) && a->eattrs)
ea_normalize(a->eattrs); ea_normalize(a->eattrs);
get_route_info = a->src->proto->proto->get_route_info; get_route_info = e->src->proto->proto->get_route_info;
if (get_route_info) if (get_route_info)
get_route_info(e, info); get_route_info(e, info);
else else
@ -66,7 +66,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
rt_show_table(c, d); rt_show_table(c, d);
cli_printf(c, -1007, "%-20s %s [%s %s%s]%s%s", ia, rta_dest_name(a->dest), cli_printf(c, -1007, "%-20s %s [%s %s%s]%s%s", ia, rta_dest_name(a->dest),
a->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info); e->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info);
if (a->dest == RTD_UNICAST) if (a->dest == RTD_UNICAST)
for (nh = &(a->nh); nh; nh = nh->next) for (nh = &(a->nh); nh; nh = nh->next)
@ -179,7 +179,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
} }
} }
if (d->show_protocol && (d->show_protocol != e->attrs->src->proto)) if (d->show_protocol && (d->show_protocol != e->src->proto))
goto skip; goto skip;
if (f_run(d->filter, &e, c->show_pool, 0) > F_ACCEPT) if (f_run(d->filter, &e, c->show_pool, 0) > F_ACCEPT)

View File

@ -276,7 +276,7 @@ rte_find(net *net, struct rte_src *src)
{ {
rte *e = net->routes; rte *e = net->routes;
while (e && e->attrs->src != src) while (e && e->src != src)
e = e->next; e = e->next;
return e; return e;
} }
@ -289,6 +289,7 @@ rte_do_cow(rte *r)
memcpy(e, r, sizeof(rte)); memcpy(e, r, sizeof(rte));
e->attrs = rta_clone(r->attrs); e->attrs = rta_clone(r->attrs);
e->flags = 0; e->flags = 0;
rt_lock_source(e->src);
return e; return e;
} }
@ -297,6 +298,8 @@ rte_store(rte *r)
{ {
rte *e = sl_alloc(rte_slab); rte *e = sl_alloc(rte_slab);
memcpy(e, r, sizeof(rte)); memcpy(e, r, sizeof(rte));
rt_lock_source(e->src);
if (e->attrs->cached) if (e->attrs->cached)
e->attrs = rta_clone(r->attrs); e->attrs = rta_clone(r->attrs);
else else
@ -345,6 +348,7 @@ rte_cow_rta(rte *r, linpool *lp)
void void
rte_free(rte *e) rte_free(rte *e)
{ {
rt_unlock_source(e->src);
if (rta_is_cached(e->attrs)) if (rta_is_cached(e->attrs))
rta_free(e->attrs); rta_free(e->attrs);
sl_free(rte_slab, e); sl_free(rte_slab, e);
@ -353,6 +357,7 @@ rte_free(rte *e)
static inline void static inline void
rte_free_quick(rte *e) rte_free_quick(rte *e)
{ {
rt_unlock_source(e->src);
rta_free(e->attrs); rta_free(e->attrs);
sl_free(rte_slab, e); sl_free(rte_slab, e);
} }
@ -379,16 +384,16 @@ rte_better(rte *new, rte *old)
return 1; return 1;
if (new->attrs->pref < old->attrs->pref) if (new->attrs->pref < old->attrs->pref)
return 0; return 0;
if (new->attrs->src->proto->proto != old->attrs->src->proto->proto) if (new->src->proto->proto != old->src->proto->proto)
{ {
/* /*
* If the user has configured protocol preferences, so that two different protocols * If the user has configured protocol preferences, so that two different protocols
* have the same preference, try to break the tie by comparing addresses. Not too * have the same preference, try to break the tie by comparing addresses. Not too
* useful, but keeps the ordering of routes unambiguous. * useful, but keeps the ordering of routes unambiguous.
*/ */
return new->attrs->src->proto->proto > old->attrs->src->proto->proto; return new->src->proto->proto > old->src->proto->proto;
} }
if (better = new->attrs->src->proto->rte_better) if (better = new->src->proto->rte_better)
return better(new, old); return better(new, old);
return 0; return 0;
} }
@ -404,10 +409,10 @@ rte_mergable(rte *pri, rte *sec)
if (pri->attrs->pref != sec->attrs->pref) if (pri->attrs->pref != sec->attrs->pref)
return 0; return 0;
if (pri->attrs->src->proto->proto != sec->attrs->src->proto->proto) if (pri->src->proto->proto != sec->src->proto->proto)
return 0; return 0;
if (mergable = pri->attrs->src->proto->rte_mergable) if (mergable = pri->src->proto->rte_mergable)
return mergable(pri, sec); return mergable(pri, sec);
return 0; return 0;
@ -520,13 +525,13 @@ rt_notify_basic(struct channel *c, struct rte_export_internal *e)
if (e->new) if (e->new)
{ {
ep->new = export_filter(c, e->new, &e->rt_free, 0); ep->new = export_filter(c, e->new, &e->rt_free, 0);
ep->new_src = e->new->attrs->src; ep->new_src = e->new->src;
} }
if (e->old && bmap_test(&c->export_map, e->old->id)) if (e->old && bmap_test(&c->export_map, e->old->id))
{ {
ep->old = e->old; ep->old = e->old;
ep->old_src = e->old->attrs->src; ep->old_src = e->old->src;
} }
return (ep->new || ep->old); return (ep->new || ep->old);
@ -603,9 +608,9 @@ rt_notify_accepted(struct channel *c, struct rte_export_internal *e)
e->pub = (struct rte_export) { e->pub = (struct rte_export) {
.new = new_best, .new = new_best,
.new_src = new_best ? new_best->attrs->src : NULL, .new_src = new_best ? new_best->src : NULL,
.old = old_best, .old = old_best,
.old_src = old_best ? old_best->attrs->src : NULL, .old_src = old_best ? old_best->src : NULL,
}; };
return 1; return 1;
@ -698,7 +703,7 @@ rt_notify_merged(struct channel *c, struct rte_export_internal *e)
if (e->new_best) if (e->new_best)
{ {
ep->new = rt_export_merged(c, e->net, &(e->rt_free), rte_update_pool, 0); ep->new = rt_export_merged(c, e->net, &(e->rt_free), rte_update_pool, 0);
ep->new_src = e->net->routes->attrs->src; ep->new_src = e->net->routes->src;
} }
/* Check old merged route */ /* Check old merged route */
@ -708,7 +713,7 @@ rt_notify_merged(struct channel *c, struct rte_export_internal *e)
if (!ep->new && !ep->old) if (!ep->new && !ep->old)
return 0; return 0;
ep->old_src = ep->old ? ep->old->attrs->src : NULL; ep->old_src = ep->old ? ep->old->src : NULL;
return 1; return 1;
} }
@ -988,7 +993,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
k = &net->routes; /* Find and remove original route from the same protocol */ k = &net->routes; /* Find and remove original route from the same protocol */
while (old = *k) while (old = *k)
{ {
if (old->attrs->src == src) if (old->src == src)
{ {
/* If there is the same route in the routing table but from /* If there is the same route in the routing table but from
* a different sender, then there are two paths from the * a different sender, then there are two paths from the
@ -1366,8 +1371,9 @@ static int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct
void void
rte_withdraw(struct channel *c, const net_addr *n, struct rte_src *src) rte_withdraw(struct channel *c, const net_addr *n, struct rte_src *src)
{ {
ASSERT(src);
if (!c->in_table || rte_update_in(c, n, NULL, src)) if (!c->in_table || rte_update_in(c, n, NULL, src))
rte_update2(c, n, NULL, src ?: c->proto->main_source); rte_update2(c, n, NULL, src);
} }
void void
@ -1375,7 +1381,7 @@ rte_update(struct channel *c, const net_addr *n, struct rte *new)
{ {
ASSERT(new); ASSERT(new);
ASSERT(new->attrs); ASSERT(new->attrs);
ASSERT(new->attrs->src); ASSERT(new->src);
if (!new->attrs->pref) if (!new->attrs->pref)
{ {
@ -1386,8 +1392,10 @@ rte_update(struct channel *c, const net_addr *n, struct rte *new)
rte *e = sl_alloc(rte_slab); rte *e = sl_alloc(rte_slab);
*e = *new; *e = *new;
if (!c->in_table || rte_update_in(c, n, e, e->attrs->src)) rt_lock_source(e->src);
rte_update2(c, n, e, e->attrs->src);
if (!c->in_table || rte_update_in(c, n, e, e->src))
rte_update2(c, n, e, e->src);
} }
/* Independent call to rte_announce(), used from next hop /* Independent call to rte_announce(), used from next hop
@ -1405,7 +1413,7 @@ static inline void
rte_discard(rte *old) /* Non-filtered route deletion, used during garbage collection */ rte_discard(rte *old) /* Non-filtered route deletion, used during garbage collection */
{ {
rte_update_lock(); rte_update_lock();
rte_recalculate(old->sender, old->net, NULL, old->attrs->src); rte_recalculate(old->sender, old->net, NULL, old->src);
rte_update_unlock(); rte_update_unlock();
} }
@ -1425,7 +1433,7 @@ rte_modify(rte *old)
new->flags = (old->flags & ~REF_MODIFY) | REF_COW; new->flags = (old->flags & ~REF_MODIFY) | REF_COW;
} }
rte_recalculate(old->sender, old->net, new, old->attrs->src); rte_recalculate(old->sender, old->net, new, old->src);
} }
rte_update_unlock(); rte_update_unlock();
@ -1975,6 +1983,7 @@ rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
rte *e = sl_alloc(rte_slab); rte *e = sl_alloc(rte_slab);
memcpy(e, old, sizeof(rte)); memcpy(e, old, sizeof(rte));
e->attrs = rta_lookup(a); e->attrs = rta_lookup(a);
rt_lock_source(e->src);
return e; return e;
} }
@ -2001,8 +2010,8 @@ rt_next_hop_update_net(rtable *tab, net *n)
/* Call a pre-comparison hook */ /* Call a pre-comparison hook */
/* Not really an efficient way to compute this */ /* Not really an efficient way to compute this */
if (e->attrs->src->proto->rte_recalculate) if (e->src->proto->rte_recalculate)
e->attrs->src->proto->rte_recalculate(tab, n, new, e, NULL); e->src->proto->rte_recalculate(tab, n, new, e, NULL);
if (e != old_best) if (e != old_best)
rte_free_quick(e); rte_free_quick(e);
@ -2343,7 +2352,7 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
/* Find the old rte */ /* Find the old rte */
for (pos = &net->routes; old = *pos; pos = &old->next) for (pos = &net->routes; old = *pos; pos = &old->next)
if (old->attrs->src == src) if (old->src == src)
{ {
if (new && rte_same(old, new)) if (new && rte_same(old, new))
{ {
@ -2441,7 +2450,7 @@ rt_reload_channel(struct channel *c)
return 0; return 0;
} }
rte_update2(c, e->net->n.addr, rte_do_cow(e), e->attrs->src); rte_update2(c, e->net->n.addr, rte_do_cow(e), e->src);
} }
c->reload_next_rte = NULL; c->reload_next_rte = NULL;
@ -2524,7 +2533,7 @@ rte_update_out(struct channel *c, const net_addr *n, struct rte_src *src, rte *n
/* Find the old rte */ /* Find the old rte */
for (pos = &net->routes; old = *pos; pos = &old->next) for (pos = &net->routes; old = *pos; pos = &old->next)
if ((c->ra_mode != RA_ANY) || (old->attrs->src == src)) if ((c->ra_mode != RA_ANY) || (old->src == src))
{ {
if (new && rte_same(old, new)) if (new && rte_same(old, new))
{ {

View File

@ -630,7 +630,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
if (r) if (r)
{ {
rta a0 = { rta a0 = {
.src = p->p.main_source,
.source = RTS_BABEL, .source = RTS_BABEL,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_UNICAST, .dest = RTD_UNICAST,
@ -672,6 +671,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
a0.nh.flags = RNF_ONLINK; a0.nh.flags = RNF_ONLINK;
rte e0 = { rte e0 = {
.src = p->p.main_source,
.attrs = &a0, .attrs = &a0,
}; };
@ -682,7 +682,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
{ {
/* Unreachable */ /* Unreachable */
rta a0 = { rta a0 = {
.src = p->p.main_source,
.source = RTS_BABEL, .source = RTS_BABEL,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_UNREACHABLE, .dest = RTD_UNREACHABLE,
@ -690,6 +689,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
}; };
rte e0 = { rte e0 = {
.src = p->p.main_source,
.attrs = &a0, .attrs = &a0,
}; };
@ -2102,10 +2102,8 @@ babel_kick_timer(struct babel_proto *p)
static int static int
babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED) babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED)
{ {
struct rta *a = (*new)->attrs;
/* Reject our own unreachable routes */ /* Reject our own unreachable routes */
if ((a->dest == RTD_UNREACHABLE) && (a->src->proto == P)) if (((*new)->attrs->dest == RTD_UNREACHABLE) && ((*new)->src->proto == P))
return -1; return -1;
return 0; return 0;

View File

@ -1664,7 +1664,7 @@ int
bgp_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED) bgp_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
{ {
rte *e = *new; rte *e = *new;
struct proto *SRC = e->attrs->src->proto; struct proto *SRC = e->src->proto;
struct bgp_proto *p = (struct bgp_proto *) P; struct bgp_proto *p = (struct bgp_proto *) P;
struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (struct bgp_proto *) SRC : NULL; struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (struct bgp_proto *) SRC : NULL;
@ -1719,7 +1719,7 @@ bgp_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
static ea_list * static ea_list *
bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs0, struct linpool *pool) bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs0, struct linpool *pool)
{ {
struct proto *SRC = e->attrs->src->proto; struct proto *SRC = e->src->proto;
struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (void *) SRC : NULL; struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (void *) SRC : NULL;
struct bgp_export_state s = { .proto = p, .channel = c, .pool = pool, .src = src, .route = e, .mpls = c->desc->mpls }; struct bgp_export_state s = { .proto = p, .channel = c, .pool = pool, .src = src, .route = e, .mpls = c->desc->mpls };
ea_list *attrs = attrs0; ea_list *attrs = attrs0;
@ -1874,7 +1874,7 @@ bgp_get_neighbor(rte *r)
return as; return as;
/* If AS_PATH is not defined, we treat rte as locally originated */ /* If AS_PATH is not defined, we treat rte as locally originated */
struct bgp_proto *p = (void *) r->attrs->src->proto; struct bgp_proto *p = (void *) r->src->proto;
return p->cf->confederation ?: p->local_as; return p->cf->confederation ?: p->local_as;
} }
@ -1904,8 +1904,8 @@ rte_stale(rte *r)
int int
bgp_rte_better(rte *new, rte *old) bgp_rte_better(rte *new, rte *old)
{ {
struct bgp_proto *new_bgp = (struct bgp_proto *) new->attrs->src->proto; struct bgp_proto *new_bgp = (struct bgp_proto *) new->src->proto;
struct bgp_proto *old_bgp = (struct bgp_proto *) old->attrs->src->proto; struct bgp_proto *old_bgp = (struct bgp_proto *) old->src->proto;
eattr *x, *y; eattr *x, *y;
u32 n, o; u32 n, o;
@ -2049,8 +2049,8 @@ bgp_rte_better(rte *new, rte *old)
int int
bgp_rte_mergable(rte *pri, rte *sec) bgp_rte_mergable(rte *pri, rte *sec)
{ {
struct bgp_proto *pri_bgp = (struct bgp_proto *) pri->attrs->src->proto; struct bgp_proto *pri_bgp = (struct bgp_proto *) pri->src->proto;
struct bgp_proto *sec_bgp = (struct bgp_proto *) sec->attrs->src->proto; struct bgp_proto *sec_bgp = (struct bgp_proto *) sec->src->proto;
eattr *x, *y; eattr *x, *y;
u32 p, s; u32 p, s;
@ -2131,7 +2131,7 @@ same_group(rte *r, u32 lpref, u32 lasn)
static inline int static inline int
use_deterministic_med(rte *r) use_deterministic_med(rte *r)
{ {
struct proto *P = r->attrs->src->proto; struct proto *P = r->src->proto;
return (P->proto == &proto_bgp) && ((struct bgp_proto *) P)->cf->deterministic_med; return (P->proto == &proto_bgp) && ((struct bgp_proto *) P)->cf->deterministic_med;
} }

View File

@ -1340,9 +1340,6 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
{ {
s->last_src = rt_get_source(&s->proto->p, path_id); s->last_src = rt_get_source(&s->proto->p, path_id);
s->last_id = path_id; s->last_id = path_id;
rta_free(s->cached_rta);
s->cached_rta = NULL;
} }
if (!a0) if (!a0)
@ -1355,8 +1352,6 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
/* Prepare cached route attributes */ /* Prepare cached route attributes */
if (s->cached_rta == NULL) if (s->cached_rta == NULL)
{ {
a0->src = s->last_src;
/* Workaround for rta_lookup() breaking eattrs */ /* Workaround for rta_lookup() breaking eattrs */
ea_list *ea = a0->eattrs; ea_list *ea = a0->eattrs;
s->cached_rta = rta_lookup(a0); s->cached_rta = rta_lookup(a0);
@ -1365,6 +1360,7 @@ bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
rte e0 = { rte e0 = {
.attrs = rta_clone(s->cached_rta), .attrs = rta_clone(s->cached_rta),
.src = s->last_src,
}; };
rte_update(&(s->channel->c), n, &e0); rte_update(&(s->channel->c), n, &e0);

View File

@ -469,9 +469,9 @@ mrt_rib_table_entry(struct mrt_table_dump_state *s, rte *r)
#ifdef CONFIG_BGP #ifdef CONFIG_BGP
/* Find peer index */ /* Find peer index */
if (r->attrs->src->proto->proto == &proto_bgp) if (r->src->proto->proto == &proto_bgp)
{ {
struct bgp_proto *p = (void *) r->attrs->src->proto; struct bgp_proto *p = (void *) r->src->proto;
struct mrt_peer_entry *n = struct mrt_peer_entry *n =
HASH_FIND(s->peer_hash, PEER, p->remote_id, p->remote_as, p->remote_ip); HASH_FIND(s->peer_hash, PEER, p->remote_id, p->remote_as, p->remote_ip);
@ -485,7 +485,7 @@ mrt_rib_table_entry(struct mrt_table_dump_state *s, rte *r)
/* Path Identifier */ /* Path Identifier */
if (s->add_path) if (s->add_path)
mrt_put_u32(b, r->attrs->src->private_id); mrt_put_u32(b, r->src->private_id);
/* Route Attributes */ /* Route Attributes */
mrt_put_u16(b, 0); mrt_put_u16(b, 0);
@ -516,7 +516,7 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path)
continue; continue;
/* Skip routes that should be reported in the other phase */ /* Skip routes that should be reported in the other phase */
if (!s->always_add_path && (!rt->attrs->src->private_id != !s->add_path)) if (!s->always_add_path && (!rt->src->private_id != !s->add_path))
{ {
s->want_add_path = 1; s->want_add_path = 1;
continue; continue;

View File

@ -478,7 +478,7 @@ ospf_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
rte *e = *new; rte *e = *new;
/* Reject our own routes */ /* Reject our own routes */
if (e->attrs->src->proto == P) if (e->src->proto == P)
return -1; return -1;
/* Do not export routes to stub areas */ /* Do not export routes to stub areas */

View File

@ -2047,7 +2047,6 @@ again1:
if (nf->n.type) /* Add the route */ if (nf->n.type) /* Add the route */
{ {
rta a0 = { rta a0 = {
.src = p->p.main_source,
.source = nf->n.type, .source = nf->n.type,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_UNICAST, .dest = RTD_UNICAST,
@ -2096,7 +2095,10 @@ again1:
.u.data = nf->n.rid, .u.data = nf->n.rid,
}; };
rte e0 = { .attrs = rta_lookup(&a0), }; rte e0 = {
.attrs = rta_lookup(&a0),
.src = p->p.main_source,
};
rta_free(nf->old_rta); rta_free(nf->old_rta);
nf->old_rta = rta_clone(e0.attrs); nf->old_rta = rta_clone(e0.attrs);

View File

@ -143,7 +143,6 @@ perf_loop(void *data)
if (!p->attrs_per_rte || !(i % p->attrs_per_rte)) { if (!p->attrs_per_rte || !(i % p->attrs_per_rte)) {
struct rta a0 = { struct rta a0 = {
.src = p->p.main_source,
.source = RTS_PERF, .source = RTS_PERF,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_UNICAST, .dest = RTD_UNICAST,
@ -163,7 +162,10 @@ perf_loop(void *data)
for (uint i=0; i<N; i++) for (uint i=0; i<N; i++)
{ {
rte e0 = { .attrs = p->data[i].a, }; rte e0 = {
.attrs = p->data[i].a,
.src = p->p.main_source,
};
rte_update(P->main_channel, &(p->data[i].net), &e0); rte_update(P->main_channel, &(p->data[i].net), &e0);
} }

View File

@ -145,7 +145,6 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
{ {
/* Update */ /* Update */
rta a0 = { rta a0 = {
.src = p->p.main_source,
.pref = p->p.main_channel->preference, .pref = p->p.main_channel->preference,
.source = RTS_RIP, .source = RTS_RIP,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
@ -210,6 +209,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
rte e0 = { rte e0 = {
.attrs = &a0, .attrs = &a0,
.src = p->p.main_source,
}; };
rte_update(p->p.main_channel, en->n.addr, &e0); rte_update(p->p.main_channel, en->n.addr, &e0);

View File

@ -121,14 +121,16 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_
struct rpki_proto *p = cache->p; struct rpki_proto *p = cache->p;
rta a0 = { rta a0 = {
.src = p->p.main_source,
.pref = channel->preference, .pref = channel->preference,
.source = RTS_RPKI, .source = RTS_RPKI,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_NONE, .dest = RTD_NONE,
}; };
rte e0 = { .attrs = &a0 }; rte e0 = {
.attrs = &a0,
.src = p->p.main_source,
};
rte_update(channel, &pfxr->n, &e0); rte_update(channel, &pfxr->n, &e0);
} }

View File

@ -56,7 +56,6 @@ static void
static_announce_rte(struct static_proto *p, struct static_route *r) static_announce_rte(struct static_proto *p, struct static_route *r)
{ {
rta *a = allocz(RTA_MAX_SIZE); rta *a = allocz(RTA_MAX_SIZE);
a->src = static_get_source(p, r->index);
a->source = RTS_STATIC; a->source = RTS_STATIC;
a->scope = SCOPE_UNIVERSE; a->scope = SCOPE_UNIVERSE;
a->dest = r->dest; a->dest = r->dest;
@ -103,7 +102,10 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
return; return;
/* We skip rta_lookup() here */ /* We skip rta_lookup() here */
rte e0 = { .attrs = a }, *e = &e0; rte e0 = {
.attrs = a,
.src = static_get_source(p, r->index),
}, *e = &e0;
if (r->cmds) if (r->cmds)
{ {

View File

@ -301,6 +301,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
{ {
rte e0 = { rte e0 = {
.attrs = rta_clone(e->attrs), .attrs = rta_clone(e->attrs),
.src = p->p.main_source,
}; };
rte_update(p->p.main_channel, e->net->n.addr, &e0); rte_update(p->p.main_channel, e->net->n.addr, &e0);
@ -877,7 +878,7 @@ krt_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
// struct krt_proto *p = (struct krt_proto *) P; // struct krt_proto *p = (struct krt_proto *) P;
rte *e = *new; rte *e = *new;
if (e->attrs->src->proto == P) if (e->src->proto == P)
return -1; return -1;
if (!krt_capable(e)) if (!krt_capable(e))