mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-23 02:01:55 +00:00
Preference moved to RTA and set explicitly in protocols
This commit is contained in:
parent
86dbe0980c
commit
1fd32f9562
@ -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);
|
||||||
@ -749,6 +745,7 @@ static_attr:
|
|||||||
| DEST { $$ = f_new_static_attr(T_ENUM_RTD, SA_DEST, 0); }
|
| DEST { $$ = f_new_static_attr(T_ENUM_RTD, SA_DEST, 0); }
|
||||||
| 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); }
|
||||||
|
| PREFERENCE { $$ = f_new_static_attr(T_INT, SA_PREF, 0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
term:
|
term:
|
||||||
@ -774,8 +771,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); }
|
||||||
@ -869,9 +864,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);
|
||||||
}
|
}
|
||||||
@ -914,7 +906,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 }; };
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ enum f_sa_code {
|
|||||||
SA_DEST,
|
SA_DEST,
|
||||||
SA_IFNAME,
|
SA_IFNAME,
|
||||||
SA_IFINDEX,
|
SA_IFINDEX,
|
||||||
|
SA_PREF,
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
/* Static attribute definition (members of struct rta) */
|
/* Static attribute definition (members of struct rta) */
|
||||||
|
@ -507,6 +507,7 @@
|
|||||||
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_PREF: RESULT(sa.f_type, i, rta->pref); 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);
|
||||||
@ -577,6 +578,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);
|
||||||
}
|
}
|
||||||
@ -744,20 +749,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) {
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
19
nest/route.h
19
nest/route.h
@ -220,7 +220,6 @@ typedef struct rte {
|
|||||||
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
|
||||||
@ -463,10 +462,11 @@ typedef struct rta {
|
|||||||
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;
|
||||||
|
|
||||||
@ -488,11 +488,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 */
|
||||||
@ -500,8 +495,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 */
|
||||||
|
|
||||||
@ -690,7 +683,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); }
|
||||||
|
@ -1099,13 +1099,15 @@ 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));
|
||||||
|
#define BMIX(f) mem_hash_mix_num(&h, a->f);
|
||||||
MIX(src);
|
MIX(src);
|
||||||
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);
|
||||||
@ -1193,7 +1195,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);
|
||||||
|
|
||||||
@ -1204,7 +1206,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_source(r->src);
|
||||||
rt_lock_hostentry(r->hostentry);
|
rt_lock_hostentry(r->hostentry);
|
||||||
rta_insert(r);
|
rta_insert(r);
|
||||||
@ -1218,7 +1220,7 @@ 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)
|
||||||
@ -1228,7 +1230,7 @@ rta__free(rta *a)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1243,7 +1245,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;
|
||||||
}
|
}
|
||||||
@ -1263,10 +1265,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("p=%s pref=%d uc=%d %s %s%s h=%04x",
|
||||||
a->src->proto->name, a->uc, rts[a->source], ip_scope_text(a->scope),
|
a->src->proto->name, 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)
|
||||||
|
@ -78,13 +78,14 @@ 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),
|
.src = rt_get_source(P, ad->iface->index),
|
||||||
|
.pref = c->preference,
|
||||||
.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 = {
|
rte e0 = {
|
||||||
.attrs = rta_lookup(&a0),
|
.attrs = &a0,
|
||||||
};
|
};
|
||||||
rte_update(c, net, &e0);
|
rte_update(c, net, &e0);
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
|
|||||||
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);
|
||||||
|
@ -283,7 +283,7 @@ 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));
|
||||||
if (e->attrs->aflags & RTAF_CACHED)
|
if (e->attrs->cached)
|
||||||
e->attrs = rta_clone(r->attrs);
|
e->attrs = rta_clone(r->attrs);
|
||||||
else
|
else
|
||||||
e->attrs = rta_lookup(r->attrs);
|
e->attrs = rta_lookup(r->attrs);
|
||||||
@ -502,9 +502,9 @@ 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->attrs->src->proto->proto != old->attrs->src->proto->proto)
|
||||||
{
|
{
|
||||||
@ -528,7 +528,7 @@ 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->attrs->src->proto->proto != sec->attrs->src->proto->proto)
|
||||||
@ -1057,7 +1057,6 @@ 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->attrs->src->proto->rte_same || x->attrs->src->proto->rte_same(x, y)) &&
|
(!x->attrs->src->proto->rte_same || x->attrs->src->proto->rte_same(x, y)) &&
|
||||||
rte_is_filtered(x) == rte_is_filtered(y);
|
rte_is_filtered(x) == rte_is_filtered(y);
|
||||||
}
|
}
|
||||||
@ -1395,9 +1394,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))
|
||||||
{
|
{
|
||||||
@ -1493,6 +1489,12 @@ rte_update(struct channel *c, const net_addr *n, struct rte *new)
|
|||||||
ASSERT(new->attrs);
|
ASSERT(new->attrs);
|
||||||
ASSERT(new->attrs->src);
|
ASSERT(new->attrs->src);
|
||||||
|
|
||||||
|
if (!new->attrs->pref)
|
||||||
|
{
|
||||||
|
ASSERT(!new->attrs->cached);
|
||||||
|
new->attrs->pref = c->preference;
|
||||||
|
}
|
||||||
|
|
||||||
rte *e = sl_alloc(rte_slab);
|
rte *e = sl_alloc(rte_slab);
|
||||||
*e = *new;
|
*e = *new;
|
||||||
|
|
||||||
@ -1659,7 +1661,7 @@ 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->attrs->src->proto->proto->dump_attrs)
|
||||||
e->attrs->src->proto->proto->dump_attrs(e);
|
e->attrs->src->proto->proto->dump_attrs(e);
|
||||||
@ -2038,7 +2040,7 @@ 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));
|
||||||
@ -2398,9 +2400,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);
|
||||||
}
|
}
|
||||||
|
@ -635,13 +635,14 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
|
|||||||
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
rte e0 = {
|
rte e0 = {
|
||||||
.attrs = rta_lookup(&a0),
|
.attrs = &a0,
|
||||||
.u.babel = {
|
.u.babel = {
|
||||||
.seqno = r->seqno,
|
.seqno = r->seqno,
|
||||||
.metric = r->metric,
|
.metric = r->metric,
|
||||||
@ -661,11 +662,11 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
|
|||||||
.source = RTS_BABEL,
|
.source = RTS_BABEL,
|
||||||
.scope = SCOPE_UNIVERSE,
|
.scope = SCOPE_UNIVERSE,
|
||||||
.dest = RTD_UNREACHABLE,
|
.dest = RTD_UNREACHABLE,
|
||||||
|
.pref = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
rte e0 = {
|
rte e0 = {
|
||||||
.attrs = &a0,
|
.attrs = &a0,
|
||||||
.pref = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
e->unreachable = 1;
|
e->unreachable = 1;
|
||||||
@ -1850,7 +1851,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
|
||||||
|
@ -2087,7 +2087,7 @@ 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
|
||||||
@ -2102,7 +2102,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;
|
||||||
|
|
||||||
@ -2325,7 +2325,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, "-");
|
||||||
|
@ -2394,6 +2394,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);
|
||||||
|
@ -607,7 +607,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, ")");
|
||||||
|
@ -2048,6 +2048,7 @@ again1:
|
|||||||
.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))
|
||||||
|
@ -147,6 +147,7 @@ perf_loop(void *data)
|
|||||||
.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,
|
||||||
|
@ -68,7 +68,7 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o
|
|||||||
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->attrs = rta_lookup(a);
|
e->attrs = rta_lookup(a);
|
||||||
@ -76,7 +76,6 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o
|
|||||||
|
|
||||||
/* 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
|
||||||
|
@ -145,6 +145,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
|
|||||||
/* Update */
|
/* Update */
|
||||||
rta a0 = {
|
rta a0 = {
|
||||||
.src = p->p.main_source,
|
.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,
|
||||||
@ -188,7 +189,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rte e0 = {
|
rte e0 = {
|
||||||
.attrs = rta_lookup(&a0),
|
.attrs = &a0,
|
||||||
.u.rip = {
|
.u.rip = {
|
||||||
.from = a0.nh.iface,
|
.from = a0.nh.iface,
|
||||||
.metric = rt_metric,
|
.metric = rt_metric,
|
||||||
@ -1182,7 +1183,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);
|
||||||
|
@ -122,12 +122,13 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_
|
|||||||
|
|
||||||
rta a0 = {
|
rta a0 = {
|
||||||
.src = p->p.main_source,
|
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
rte e0 = { .attrs = rta_lookup(&a0) };
|
rte e0 = { .attrs = &a0 };
|
||||||
|
|
||||||
rte_update(channel, &pfxr->n, &e0);
|
rte_update(channel, &pfxr->n, &e0);
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -434,6 +434,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 = rte_store(e);
|
e = rte_store(e);
|
||||||
|
|
||||||
old_best = n->routes;
|
old_best = n->routes;
|
||||||
|
Loading…
Reference in New Issue
Block a user