Merge commit '5cff1d5f' into haugesund

Conflicts:
      proto/bgp/attrs.c
      proto/pipe/pipe.c
This commit is contained in:
Maria Matejka 2022-03-09 10:56:06 +01:00
commit 83d9920f90
22 changed files with 137 additions and 158 deletions

View file

@ -248,10 +248,6 @@ assert_assign(struct f_lval *lval, struct f_inst *expr, const char *start, const
setter = f_new_inst(FI_VAR_SET, expr, lval->sym); setter = f_new_inst(FI_VAR_SET, expr, lval->sym);
getter = f_new_inst(FI_VAR_GET, lval->sym); getter = f_new_inst(FI_VAR_GET, lval->sym);
break; break;
case F_LVAL_PREFERENCE:
setter = f_new_inst(FI_PREF_SET, expr);
getter = f_new_inst(FI_PREF_GET);
break;
case F_LVAL_SA: case F_LVAL_SA:
setter = f_new_inst(FI_RTA_SET, expr, lval->sa); setter = f_new_inst(FI_RTA_SET, expr, lval->sa);
getter = f_new_inst(FI_RTA_GET, lval->sa); getter = f_new_inst(FI_RTA_GET, lval->sa);
@ -759,6 +755,7 @@ static_attr:
| IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); } | IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); }
| IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); } | IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); }
| WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); } | WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); }
| PREFERENCE { $$ = f_new_static_attr(T_INT, SA_PREF, 0); }
| GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); } | GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); }
; ;
@ -785,8 +782,6 @@ term:
| constant { $$ = $1; } | constant { $$ = $1; }
| constructor { $$ = $1; } | constructor { $$ = $1; }
| PREFERENCE { $$ = f_new_inst(FI_PREF_GET); }
| static_attr { $$ = f_new_inst(FI_RTA_GET, $1); } | static_attr { $$ = f_new_inst(FI_RTA_GET, $1); }
| dynamic_attr { $$ = f_new_inst(FI_EA_GET, $1); } | dynamic_attr { $$ = f_new_inst(FI_EA_GET, $1); }
@ -884,9 +879,6 @@ cmd:
cf_error( "This static attribute is read-only."); cf_error( "This static attribute is read-only.");
$$ = f_new_inst(FI_RTA_SET, $3, $1); $$ = f_new_inst(FI_RTA_SET, $3, $1);
} }
| PREFERENCE '=' term ';' {
$$ = f_new_inst(FI_PREF_SET, $3);
}
| UNSET '(' dynamic_attr ')' ';' { | UNSET '(' dynamic_attr ')' ';' {
$$ = f_new_inst(FI_EA_UNSET, $3); $$ = f_new_inst(FI_EA_UNSET, $3);
} }
@ -929,7 +921,6 @@ get_cf_position:
lvalue: lvalue:
CF_SYM_KNOWN { cf_assert_symbol($1, SYM_VARIABLE); $$ = (struct f_lval) { .type = F_LVAL_VARIABLE, .sym = $1 }; } CF_SYM_KNOWN { cf_assert_symbol($1, SYM_VARIABLE); $$ = (struct f_lval) { .type = F_LVAL_VARIABLE, .sym = $1 }; }
| PREFERENCE { $$ = (struct f_lval) { .type = F_LVAL_PREFERENCE }; }
| static_attr { $$ = (struct f_lval) { .type = F_LVAL_SA, .sa = $1 }; } | static_attr { $$ = (struct f_lval) { .type = F_LVAL_SA, .sa = $1 }; }
| dynamic_attr { $$ = (struct f_lval) { .type = F_LVAL_EA, .da = $1 }; }; | dynamic_attr { $$ = (struct f_lval) { .type = F_LVAL_EA, .da = $1 }; };

View file

@ -100,6 +100,7 @@ enum f_sa_code {
SA_IFNAME, SA_IFNAME,
SA_IFINDEX, SA_IFINDEX,
SA_WEIGHT, SA_WEIGHT,
SA_PREF,
SA_GW_MPLS, SA_GW_MPLS,
} PACKED; } PACKED;

View file

@ -526,13 +526,14 @@
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;
case SA_IFNAME: RESULT(sa.f_type, s, rta->nh.iface ? rta->nh.iface->name : ""); break; case SA_IFNAME: RESULT(sa.f_type, s, rta->nh.iface ? rta->nh.iface->name : ""); break;
case SA_IFINDEX: RESULT(sa.f_type, i, rta->nh.iface ? rta->nh.iface->index : 0); break; case SA_IFINDEX: RESULT(sa.f_type, i, rta->nh.iface ? rta->nh.iface->index : 0); break;
case SA_WEIGHT: RESULT(sa.f_type, i, rta->nh.weight + 1); break; case SA_WEIGHT: RESULT(sa.f_type, i, rta->nh.weight + 1); break;
case SA_PREF: RESULT(sa.f_type, i, rta->pref); break;
case SA_GW_MPLS: RESULT(sa.f_type, i, rta->nh.labels ? rta->nh.label[0] : MPLS_NULL); break; case SA_GW_MPLS: RESULT(sa.f_type, i, rta->nh.labels ? rta->nh.label[0] : MPLS_NULL); break;
default: default:
@ -561,7 +562,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" );
@ -637,6 +638,10 @@
} }
break; break;
case SA_PREF:
rta->pref = v1.val.i;
break;
default: default:
bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code); bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code);
} }
@ -804,20 +809,6 @@
} }
} }
INST(FI_PREF_GET, 0, 1) {
ACCESS_RTE;
RESULT(T_INT, i, (*fs->rte)->pref);
}
INST(FI_PREF_SET, 1, 0) {
ACCESS_RTE;
ARG(1,T_INT);
if (v1.val.i > 0xFFFF)
runtime( "Setting preference value out of bounds" );
f_rte_cow(fs);
(*fs->rte)->pref = v1.val.i;
}
INST(FI_LENGTH, 1, 1) { /* Get length of */ INST(FI_LENGTH, 1, 1) { /* Get length of */
ARG_ANY(1); ARG_ANY(1);
switch(v1.type) { switch(v1.type) {

View file

@ -215,6 +215,12 @@ mem_hash_mix(u64 *h, const void *p, uint s)
*h = *h * multiplier + pp[i]; *h = *h * multiplier + pp[i];
} }
static inline void
mem_hash_mix_num(u64 *h, u64 val)
{
mem_hash_mix(h, &val, sizeof(val));
}
static inline uint static inline uint
mem_hash_value(u64 *h) mem_hash_value(u64 *h)
{ {

View file

@ -255,12 +255,12 @@ 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 */
byte flags; /* Flags (REF_...) */ byte flags; /* Flags (REF_...) */
byte pflags; /* Protocol-specific flags */ byte pflags; /* Protocol-specific flags */
word pref; /* Route preference */
btime lastmod; /* Last modified */ btime lastmod; /* Last modified */
union { /* Protocol-dependent data (metrics etc.) */ union { /* Protocol-dependent data (metrics etc.) */
#ifdef CONFIG_RIP #ifdef CONFIG_RIP
@ -352,7 +352,7 @@ net *net_get(rtable *tab, const net_addr *addr);
net *net_route(rtable *tab, const net_addr *n); net *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 *); rte *rte_get_temp(struct rta *, struct rte_src *src);
void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src); 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 */ /* 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);
@ -487,14 +487,14 @@ 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) */
u8 source; /* Route source (RTS_...) */ u16 cached:1; /* Are attributes cached? */
u8 scope; /* Route scope (SCOPE_... -- see ip.h) */ u16 source:7; /* Route source (RTS_...) */
u8 dest; /* Route destination type (RTD_...) */ u16 scope:4; /* Route scope (SCOPE_... -- see ip.h) */
u8 aflags; u16 dest:4; /* Route destination type (RTD_...) */
word pref;
struct nexthop nh; /* Next hop */ struct nexthop nh; /* Next hop */
} rta; } rta;
@ -516,11 +516,6 @@ typedef struct rta {
#define RTS_PERF 15 /* Perf checker */ #define RTS_PERF 15 /* Perf checker */
#define RTS_MAX 16 #define RTS_MAX 16
#define RTC_UNICAST 0
#define RTC_BROADCAST 1
#define RTC_MULTICAST 2
#define RTC_ANYCAST 3 /* IPv6 Anycast */
#define RTD_NONE 0 /* Undefined next hop */ #define RTD_NONE 0 /* Undefined next hop */
#define RTD_UNICAST 1 /* Next hop is neighbor router */ #define RTD_UNICAST 1 /* Next hop is neighbor router */
#define RTD_BLACKHOLE 2 /* Silently drop packets */ #define RTD_BLACKHOLE 2 /* Silently drop packets */
@ -528,8 +523,6 @@ typedef struct rta {
#define RTD_PROHIBIT 4 /* Administratively prohibited */ #define RTD_PROHIBIT 4 /* Administratively prohibited */
#define RTD_MAX 5 #define RTD_MAX 5
#define RTAF_CACHED 1 /* This is a cached rta */
#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other #define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
protocol-specific metric is availabe */ protocol-specific metric is availabe */
@ -718,7 +711,7 @@ void rta_init(void);
static inline size_t rta_size(const rta *a) { return sizeof(rta) + sizeof(u32)*a->nh.labels; } static inline size_t rta_size(const rta *a) { return sizeof(rta) + sizeof(u32)*a->nh.labels; }
#define RTA_MAX_SIZE (sizeof(rta) + sizeof(u32)*MPLS_MAX_LABEL_STACK) #define RTA_MAX_SIZE (sizeof(rta) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */ rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */
static inline int rta_is_cached(rta *r) { return r->aflags & RTAF_CACHED; } static inline int rta_is_cached(rta *r) { return r->cached; }
static inline rta *rta_clone(rta *r) { r->uc++; return r; } static inline rta *rta_clone(rta *r) { r->uc++; return r; }
void rta__free(rta *r); void rta__free(rta *r);
static inline void rta_free(rta *r) { if (r && !--r->uc) rta__free(r); } static inline void rta_free(rta *r) { if (r && !--r->uc) rta__free(r); }

View file

@ -1104,13 +1104,14 @@ rta_hash(rta *a)
u64 h; u64 h;
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));
MIX(src); #define BMIX(f) mem_hash_mix_num(&h, a->f);
MIX(hostentry); MIX(hostentry);
MIX(from); MIX(from);
MIX(igp_metric); MIX(igp_metric);
MIX(source); BMIX(source);
MIX(scope); BMIX(scope);
MIX(dest); BMIX(dest);
MIX(pref);
#undef MIX #undef MIX
return mem_hash_value(&h) ^ nexthop_hash(&(a->nh)) ^ ea_hash(a->eattrs); return mem_hash_value(&h) ^ nexthop_hash(&(a->nh)) ^ ea_hash(a->eattrs);
@ -1119,8 +1120,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 &&
@ -1198,7 +1198,7 @@ rta_lookup(rta *o)
rta *r; rta *r;
uint h; uint h;
ASSERT(!(o->aflags & RTAF_CACHED)); ASSERT(!o->cached);
if (o->eattrs) if (o->eattrs)
ea_normalize(o->eattrs); ea_normalize(o->eattrs);
@ -1209,8 +1209,7 @@ rta_lookup(rta *o)
r = rta_copy(o); r = rta_copy(o);
r->hash_key = h; r->hash_key = h;
r->aflags = RTAF_CACHED; r->cached = 1;
rt_lock_source(r->src);
rt_lock_hostentry(r->hostentry); rt_lock_hostentry(r->hostentry);
rta_insert(r); rta_insert(r);
@ -1223,17 +1222,16 @@ rta_lookup(rta *o)
void void
rta__free(rta *a) rta__free(rta *a)
{ {
ASSERT(rta_cache_count && (a->aflags & RTAF_CACHED)); ASSERT(rta_cache_count && a->cached);
rta_cache_count--; rta_cache_count--;
*a->pprev = a->next; *a->pprev = a->next;
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);
a->aflags = 0; /* Poison the entry */ a->cached = 0;
sl_free(rta_slab(a), a); sl_free(rta_slab(a), a);
} }
@ -1248,7 +1246,7 @@ rta_do_cow(rta *o, linpool *lp)
memcpy(*nhn, nho, nexthop_size(nho)); memcpy(*nhn, nho, nexthop_size(nho));
nhn = &((*nhn)->next); nhn = &((*nhn)->next);
} }
r->aflags = 0; r->cached = 0;
r->uc = 0; r->uc = 0;
return r; return r;
} }
@ -1268,10 +1266,10 @@ 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 uc=%d %s %s%s h=%04x", debug("pref=%d uc=%d %s %s%s h=%04x",
a->src->proto->name, 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->aflags & RTAF_CACHED)) if (!a->cached)
debug(" !CACHED"); debug(" !CACHED");
debug(" <-%I", a->from); debug(" <-%I", a->from);
if (a->dest == RTD_UNICAST) if (a->dest == RTD_UNICAST)

View file

@ -83,7 +83,7 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
struct rte_src *src = rt_get_source(P, ad->iface->index); struct rte_src *src = rt_get_source(P, ad->iface->index);
rta a0 = { rta a0 = {
.src = src, .pref = c->preference,
.source = RTS_DEVICE, .source = RTS_DEVICE,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_UNICAST, .dest = RTD_UNICAST,
@ -91,7 +91,7 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
}; };
a = rta_lookup(&a0); a = rta_lookup(&a0);
e = rte_get_temp(a); e = rte_get_temp(a, src);
e->pflags = 0; e->pflags = 0;
rte_update2(c, net, e, src); rte_update2(c, net, e, src);
} }

View file

@ -57,17 +57,17 @@ 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
bsprintf(info, " (%d)", e->pref); bsprintf(info, " (%d)", a->pref);
if (d->last_table != d->tab) if (d->last_table != d->tab)
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)
@ -180,7 +180,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

@ -548,7 +548,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;
} }
@ -563,14 +563,14 @@ rte_find(net *net, struct rte_src *src)
* the protocol. * the protocol.
*/ */
rte * rte *
rte_get_temp(rta *a) rte_get_temp(rta *a, struct rte_src *src)
{ {
rte *e = sl_alloc(rte_slab); rte *e = sl_alloc(rte_slab);
e->attrs = a; e->attrs = a;
e->id = 0; e->id = 0;
e->flags = 0; e->flags = 0;
e->pref = 0; rt_lock_source(e->src = src);
return e; return e;
} }
@ -580,6 +580,8 @@ rte_do_cow(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);
e->attrs = rta_clone(r->attrs); e->attrs = rta_clone(r->attrs);
e->flags = 0; e->flags = 0;
return e; return e;
@ -626,6 +628,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);
@ -634,6 +637,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);
} }
@ -758,7 +762,7 @@ void
rte_make_tmp_attrs(rte **r, linpool *lp, rta **old_attrs) rte_make_tmp_attrs(rte **r, linpool *lp, rta **old_attrs)
{ {
void (*make_tmp_attrs)(rte *r, linpool *lp); void (*make_tmp_attrs)(rte *r, linpool *lp);
make_tmp_attrs = (*r)->attrs->src->proto->make_tmp_attrs; make_tmp_attrs = (*r)->src->proto->make_tmp_attrs;
if (!make_tmp_attrs) if (!make_tmp_attrs)
return; return;
@ -787,7 +791,7 @@ static void
rte_store_tmp_attrs(rte *r, linpool *lp, rta *old_attrs) rte_store_tmp_attrs(rte *r, linpool *lp, rta *old_attrs)
{ {
void (*store_tmp_attrs)(rte *rt, linpool *lp); void (*store_tmp_attrs)(rte *rt, linpool *lp);
store_tmp_attrs = r->attrs->src->proto->store_tmp_attrs; store_tmp_attrs = r->src->proto->store_tmp_attrs;
if (!store_tmp_attrs) if (!store_tmp_attrs)
return; return;
@ -817,20 +821,20 @@ rte_better(rte *new, rte *old)
if (!rte_is_valid(new)) if (!rte_is_valid(new))
return 0; return 0;
if (new->pref > old->pref) if (new->attrs->pref > old->attrs->pref)
return 1; return 1;
if (new->pref < old->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;
} }
@ -843,13 +847,13 @@ rte_mergable(rte *pri, rte *sec)
if (!rte_is_valid(pri) || !rte_is_valid(sec)) if (!rte_is_valid(pri) || !rte_is_valid(sec))
return 0; return 0;
if (pri->pref != sec->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;
@ -1377,8 +1381,8 @@ rte_same(rte *x, rte *y)
return return
x->attrs == y->attrs && x->attrs == y->attrs &&
x->pflags == y->pflags && x->pflags == y->pflags &&
x->pref == y->pref && x->src == y->src &&
(!x->attrs->src->proto->rte_same || x->attrs->src->proto->rte_same(x, y)) && (!x->src->proto->rte_same || x->src->proto->rte_same(x, y)) &&
rte_is_filtered(x) == rte_is_filtered(y); rte_is_filtered(x) == rte_is_filtered(y);
} }
@ -1399,7 +1403,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
@ -1766,9 +1770,6 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
new->net = nn; new->net = nn;
new->sender = c; new->sender = c;
if (!new->pref)
new->pref = c->preference;
stats->imp_updates_received++; stats->imp_updates_received++;
if (!rte_validate(new)) if (!rte_validate(new))
{ {
@ -1863,7 +1864,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();
} }
@ -1883,7 +1884,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();
@ -2007,10 +2008,10 @@ rte_dump(rte *e)
{ {
net *n = e->net; net *n = e->net;
debug("%-1N ", n->n.addr); debug("%-1N ", n->n.addr);
debug("PF=%02x pref=%d ", e->pflags, e->pref); debug("PF=%02x ", e->pflags);
rta_dump(e->attrs); rta_dump(e->attrs);
if (e->attrs->src->proto->proto->dump_attrs) if (e->src->proto->proto->dump_attrs)
e->attrs->src->proto->proto->dump_attrs(e); e->src->proto->proto->dump_attrs(e);
debug("\n"); debug("\n");
} }
@ -2724,11 +2725,12 @@ rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
memcpy(mls.stack, &a->nh.label[a->nh.labels - mls.len], mls.len * sizeof(u32)); memcpy(mls.stack, &a->nh.label[a->nh.labels - mls.len], mls.len * sizeof(u32));
rta_apply_hostentry(a, old->attrs->hostentry, &mls); rta_apply_hostentry(a, old->attrs->hostentry, &mls);
a->aflags = 0; a->cached = 0;
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;
} }
@ -2856,7 +2858,7 @@ rt_flowspec_update_rte(rtable *tab, rte *r)
return NULL; return NULL;
const net_addr *n = r->net->n.addr; const net_addr *n = r->net->n.addr;
struct bgp_proto *p = (void *) r->attrs->src->proto; struct bgp_proto *p = (void *) r->src->proto;
int valid = rt_flowspec_check(r->u.bgp.base_table, tab, n, r->attrs, p->is_interior); int valid = rt_flowspec_check(r->u.bgp.base_table, tab, n, r->attrs, p->is_interior);
int dest = valid ? RTD_NONE : RTD_UNREACHABLE; int dest = valid ? RTD_NONE : RTD_UNREACHABLE;
@ -2866,7 +2868,7 @@ rt_flowspec_update_rte(rtable *tab, rte *r)
rta *a = alloca(RTA_MAX_SIZE); rta *a = alloca(RTA_MAX_SIZE);
memcpy(a, r->attrs, rta_size(r->attrs)); memcpy(a, r->attrs, rta_size(r->attrs));
a->dest = dest; a->dest = dest;
a->aflags = 0; a->cached = 0;
rte *new = sl_alloc(rte_slab); rte *new = sl_alloc(rte_slab);
memcpy(new, r, sizeof(rte)); memcpy(new, r, sizeof(rte));
@ -2906,8 +2908,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);
@ -3240,9 +3242,6 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
{ {
net = net_get(tab, n); net = net_get(tab, n);
if (!new->pref)
new->pref = c->preference;
if (!rta_is_cached(new->attrs)) if (!rta_is_cached(new->attrs))
new->attrs = rta_lookup(new->attrs); new->attrs = rta_lookup(new->attrs);
} }
@ -3256,7 +3255,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))
{ {
@ -3361,7 +3360,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;
@ -3444,7 +3443,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte **
if (new) if (new)
{ {
net = net_get(tab, n); net = net_get(tab, n);
src = new->attrs->src; src = new->src;
rte_store_tmp_attrs(new, rte_update_pool, NULL); rte_store_tmp_attrs(new, rte_update_pool, NULL);
@ -3454,7 +3453,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte **
else else
{ {
net = net_find(tab, n); net = net_find(tab, n);
src = old0->attrs->src; src = old0->src;
if (!net) if (!net)
goto drop_withdraw; goto drop_withdraw;
@ -3462,7 +3461,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte **
/* 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

@ -641,10 +641,10 @@ 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,
.pref = c->preference,
.from = r->neigh->addr, .from = r->neigh->addr,
.nh.gw = r->next_hop, .nh.gw = r->next_hop,
.nh.iface = r->neigh->ifa->iface, .nh.iface = r->neigh->ifa->iface,
@ -659,7 +659,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
a0.nh.flags = RNF_ONLINK; a0.nh.flags = RNF_ONLINK;
rta *a = rta_lookup(&a0); rta *a = rta_lookup(&a0);
rte *rte = rte_get_temp(a); rte *rte = rte_get_temp(a, p->p.main_source);
rte->u.babel.seqno = r->seqno; rte->u.babel.seqno = r->seqno;
rte->u.babel.metric = r->metric; rte->u.babel.metric = r->metric;
rte->u.babel.router_id = r->router_id; rte->u.babel.router_id = r->router_id;
@ -672,17 +672,16 @@ 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,
.pref = 1,
}; };
rta *a = rta_lookup(&a0); rta *a = rta_lookup(&a0);
rte *rte = rte_get_temp(a); rte *rte = rte_get_temp(a, p->p.main_source);
memset(&rte->u.babel, 0, sizeof(rte->u.babel)); memset(&rte->u.babel, 0, sizeof(rte->u.babel));
rte->pflags = 0; rte->pflags = 0;
rte->pref = 1;
e->unreachable = 1; e->unreachable = 1;
rte_update2(c, e->n.addr, rte, p->p.main_source); rte_update2(c, e->n.addr, rte, p->p.main_source);
@ -2010,7 +2009,7 @@ babel_dump(struct proto *P)
static void static void
babel_get_route_info(rte *rte, byte *buf) babel_get_route_info(rte *rte, byte *buf)
{ {
buf += bsprintf(buf, " (%d/%d) [%lR]", rte->pref, rte->u.babel.metric, rte->u.babel.router_id); buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref, rte->u.babel.metric, rte->u.babel.router_id);
} }
static int static int
@ -2235,7 +2234,7 @@ babel_preexport(struct proto *P, struct rte *new)
{ {
struct rta *a = new->attrs; 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 ((a->dest == RTD_UNREACHABLE) && (new->src->proto == P))
return -1; return -1;
return 0; return 0;
@ -2276,7 +2275,7 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
if (new) if (new)
{ {
/* Update */ /* Update */
uint internal = (new->attrs->src->proto == P); uint internal = (new->src->proto == P);
uint rt_seqno = internal ? new->u.babel.seqno : p->update_seqno; uint rt_seqno = internal ? new->u.babel.seqno : p->update_seqno;
uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0); uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0);
u64 rt_router_id = internal ? new->u.babel.router_id : p->router_id; u64 rt_router_id = internal ? new->u.babel.router_id : p->router_id;

View file

@ -1670,7 +1670,7 @@ bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px)
int int
bgp_preexport(struct proto *P, rte *e) bgp_preexport(struct proto *P, rte *e)
{ {
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;
@ -1729,7 +1729,7 @@ bgp_preexport(struct proto *P, rte *e)
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;
@ -1861,12 +1861,12 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old)
/* If attributes are invalid, we fail back to withdraw */ /* If attributes are invalid, we fail back to withdraw */
buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c); buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c);
path = new->attrs->src->global_id; path = new->src->global_id;
} }
else else
{ {
buck = bgp_get_withdraw_bucket(c); buck = bgp_get_withdraw_bucket(c);
path = old->attrs->src->global_id; path = old->src->global_id;
} }
px = bgp_get_prefix(c, n->n.addr, c->add_path_tx ? path : 0); px = bgp_get_prefix(c, n->n.addr, c->add_path_tx ? path : 0);
@ -1886,7 +1886,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;
} }
@ -1906,8 +1906,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;
@ -2051,8 +2051,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;
@ -2130,13 +2130,13 @@ bgp_rte_mergable(rte *pri, rte *sec)
static inline int static inline int
same_group(rte *r, u32 lpref, u32 lasn) same_group(rte *r, u32 lpref, u32 lasn)
{ {
return (r->pref == lpref) && (bgp_get_neighbor(r) == lasn); return (r->attrs->pref == lpref) && (bgp_get_neighbor(r) == 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;
} }
@ -2145,7 +2145,7 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
{ {
rte *r, *s; rte *r, *s;
rte *key = new ? new : old; rte *key = new ? new : old;
u32 lpref = key->pref; u32 lpref = key->attrs->pref;
u32 lasn = bgp_get_neighbor(key); u32 lasn = bgp_get_neighbor(key);
int old_suppressed = old ? old->u.bgp.suppressed : 0; int old_suppressed = old ? old->u.bgp.suppressed : 0;
@ -2368,7 +2368,7 @@ bgp_get_route_info(rte *e, byte *buf)
eattr *o = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); eattr *o = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN));
u32 origas; u32 origas;
buf += bsprintf(buf, " (%d", e->pref); buf += bsprintf(buf, " (%d", e->attrs->pref);
if (e->u.bgp.suppressed) if (e->u.bgp.suppressed)
buf += bsprintf(buf, "-"); buf += bsprintf(buf, "-");

View file

@ -1386,8 +1386,6 @@ bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, rta *a
/* 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);
@ -1395,7 +1393,7 @@ bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, rta *a
} }
rta *a = rta_clone(s->cached_rta); rta *a = rta_clone(s->cached_rta);
rte *e = rte_get_temp(a); rte *e = rte_get_temp(a, s->last_src);
e->pflags = 0; e->pflags = 0;
e->u.bgp.suppressed = 0; e->u.bgp.suppressed = 0;
@ -2481,6 +2479,7 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis
a->scope = SCOPE_UNIVERSE; a->scope = SCOPE_UNIVERSE;
a->from = s->proto->remote_ip; a->from = s->proto->remote_ip;
a->eattrs = ea; a->eattrs = ea;
a->pref = c->c.preference;
c->desc->decode_next_hop(s, nh, nh_len, a); c->desc->decode_next_hop(s, nh, nh_len, a);
bgp_finish_attrs(s, a); bgp_finish_attrs(s, a);

View file

@ -472,9 +472,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);
@ -488,7 +488,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);
@ -519,7 +519,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

@ -490,7 +490,7 @@ ospf_preexport(struct proto *P, rte *e)
struct ospf_area *oa = ospf_main_area(p); struct ospf_area *oa = ospf_main_area(p);
/* 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 */
@ -609,7 +609,7 @@ ospf_get_route_info(rte * rte, byte * buf)
} }
buf += bsprintf(buf, " %s", type); buf += bsprintf(buf, " %s", type);
buf += bsprintf(buf, " (%d/%d", rte->pref, rte->u.ospf.metric1); buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, rte->u.ospf.metric1);
if (rte->attrs->source == RTS_OSPF_EXT2) if (rte->attrs->source == RTS_OSPF_EXT2)
buf += bsprintf(buf, "/%d", rte->u.ospf.metric2); buf += bsprintf(buf, "/%d", rte->u.ospf.metric2);
buf += bsprintf(buf, ")"); buf += bsprintf(buf, ")");

View file

@ -2053,17 +2053,17 @@ 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,
.nh = *(nf->n.nhs), .nh = *(nf->n.nhs),
.pref = p->p.main_channel->preference,
}; };
if (reload || ort_changed(nf, &a0)) if (reload || ort_changed(nf, &a0))
{ {
rta *a = rta_lookup(&a0); rta *a = rta_lookup(&a0);
rte *e = rte_get_temp(a); rte *e = rte_get_temp(a, p->p.main_source);
rta_free(nf->old_rta); rta_free(nf->old_rta);
nf->old_rta = rta_clone(a); nf->old_rta = rta_clone(a);

View file

@ -143,10 +143,10 @@ 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,
.pref = p->p.main_channel->preference,
.nh.iface = p->ifa->iface, .nh.iface = p->ifa->iface,
.nh.gw = gw, .nh.gw = gw,
.nh.weight = 1, .nh.weight = 1,
@ -161,7 +161,7 @@ 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); rte *e = rte_get_temp(p->data[i].a, p->p.main_source);
e->pflags = 0; e->pflags = 0;
rte_update(P, &(p->data[i].net), e); rte_update(P, &(p->data[i].net), e);

View file

@ -65,34 +65,33 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o
if (new) if (new)
{ {
src = new->src;
a = alloca(rta_size(new->attrs)); a = alloca(rta_size(new->attrs));
memcpy(a, new->attrs, rta_size(new->attrs)); memcpy(a, new->attrs, rta_size(new->attrs));
a->aflags = 0; a->cached = 0;
a->hostentry = NULL; a->hostentry = NULL;
e = rte_get_temp(a); e = rte_get_temp(a, src);
e->pflags = 0; e->pflags = 0;
/* Copy protocol specific embedded attributes. */ /* Copy protocol specific embedded attributes. */
memcpy(&(e->u), &(new->u), sizeof(e->u)); memcpy(&(e->u), &(new->u), sizeof(e->u));
e->pref = new->pref;
e->pflags = new->pflags; e->pflags = new->pflags;
#ifdef CONFIG_BGP #ifdef CONFIG_BGP
/* Hack to cleanup cached value */ /* Hack to cleanup cached value */
if (e->attrs->src->proto->proto == &proto_bgp) if (e->src->proto->proto == &proto_bgp)
{ {
e->u.bgp.stale = -1; e->u.bgp.stale = -1;
e->u.bgp.base_table = NULL; e->u.bgp.base_table = NULL;
} }
#endif #endif
src = a->src;
} }
else else
{ {
e = NULL; e = NULL;
src = old->attrs->src; src = old->src;
} }
src_ch->table->pipe_busy = 1; src_ch->table->pipe_busy = 1;

View file

@ -145,7 +145,7 @@ 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,
.source = RTS_RIP, .source = RTS_RIP,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_UNICAST, .dest = RTD_UNICAST,
@ -189,7 +189,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
} }
rta *a = rta_lookup(&a0); rta *a = rta_lookup(&a0);
rte *e = rte_get_temp(a); rte *e = rte_get_temp(a, p->p.main_source);
e->u.rip.from = a0.nh.iface; e->u.rip.from = a0.nh.iface;
e->u.rip.metric = rt_metric; e->u.rip.metric = rt_metric;
@ -339,7 +339,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
en->valid = RIP_ENTRY_VALID; en->valid = RIP_ENTRY_VALID;
en->metric = rt_metric; en->metric = rt_metric;
en->tag = rt_tag; en->tag = rt_tag;
en->from = (new->attrs->src->proto == P) ? new->u.rip.from : NULL; en->from = (new->src->proto == P) ? new->u.rip.from : NULL;
en->iface = new->attrs->nh.iface; en->iface = new->attrs->nh.iface;
en->next_hop = new->attrs->nh.gw; en->next_hop = new->attrs->nh.gw;
} }
@ -1198,7 +1198,7 @@ rip_reconfigure(struct proto *P, struct proto_config *CF)
static void static void
rip_get_route_info(rte *rte, byte *buf) rip_get_route_info(rte *rte, byte *buf)
{ {
buf += bsprintf(buf, " (%d/%d)", rte->pref, rte->u.rip.metric); buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rte->u.rip.metric);
if (rte->u.rip.tag) if (rte->u.rip.tag)
bsprintf(buf, " [%04x]", rte->u.rip.tag); bsprintf(buf, " [%04x]", rte->u.rip.tag);

View file

@ -121,18 +121,18 @@ 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,
.source = RTS_RPKI, .source = RTS_RPKI,
.scope = SCOPE_UNIVERSE, .scope = SCOPE_UNIVERSE,
.dest = RTD_NONE, .dest = RTD_NONE,
}; };
rta *a = rta_lookup(&a0); rta *a = rta_lookup(&a0);
rte *e = rte_get_temp(a); rte *e = rte_get_temp(a, p->p.main_source);
e->pflags = 0; e->pflags = 0;
rte_update2(channel, &pfxr->n, e, a0.src); rte_update2(channel, &pfxr->n, e, e->src);
} }
void void

View file

@ -56,10 +56,11 @@ 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); struct rte_src *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;
a->pref = p->p.main_channel->preference;
if (r->dest == RTD_UNICAST) if (r->dest == RTD_UNICAST)
{ {
@ -102,7 +103,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 *e = rte_get_temp(a, src);
e->pflags = 0; e->pflags = 0;
if (r->cmds) if (r->cmds)
@ -119,7 +120,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_update2(p->p.main_channel, r->net, e, src);
r->state = SRS_CLEAN; r->state = SRS_CLEAN;
if (r->cmds) if (r->cmds)
@ -131,7 +132,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_update2(p->p.main_channel, r->net, NULL, src);
r->state = SRS_DOWN; r->state = SRS_DOWN;
} }
@ -721,9 +722,9 @@ static_get_route_info(rte *rte, byte *buf)
{ {
eattr *a = ea_find(rte->attrs->eattrs, EA_GEN_IGP_METRIC); eattr *a = ea_find(rte->attrs->eattrs, EA_GEN_IGP_METRIC);
if (a) if (a)
buf += bsprintf(buf, " (%d/%u)", rte->pref, a->u.data); buf += bsprintf(buf, " (%d/%u)", rte->attrs->pref, a->u.data);
else else
buf += bsprintf(buf, " (%d)", rte->pref); buf += bsprintf(buf, " (%d)", rte->attrs->pref);
} }
static void static void

View file

@ -1580,7 +1580,7 @@ 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 *e = rte_get_temp(s->attrs, s->proto->p.main_source);
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;
@ -1755,7 +1755,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;

View file

@ -300,7 +300,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
{ {
net *n = e->net; net *n = e->net;
rta *aa = rta_clone(e->attrs); rta *aa = rta_clone(e->attrs);
rte *ee = rte_get_temp(aa); rte *ee = rte_get_temp(aa, p->p.main_source);
ee->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);
ee->u.krt = e->u.krt; ee->u.krt = e->u.krt;
rte_update(&p->p, n->n.addr, ee); rte_update(&p->p, n->n.addr, ee);
@ -433,6 +433,9 @@ 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;
ASSERT(!e->attrs->cached);
e->attrs->pref = p->p.main_channel->preference;
e->attrs = rta_lookup(e->attrs); e->attrs = rta_lookup(e->attrs);
old_best = n->routes; old_best = n->routes;
@ -906,7 +909,7 @@ static int
krt_preexport(struct proto *P, rte *e) krt_preexport(struct proto *P, rte *e)
{ {
// struct krt_proto *p = (struct krt_proto *) P; // struct krt_proto *p = (struct krt_proto *) P;
if (e->attrs->src->proto == P) if (e->src->proto == P)
return -1; return -1;
if (!krt_capable(e)) if (!krt_capable(e))