diff options
-rw-r--r-- | doc/bird.sgml | 3 | ||||
-rw-r--r-- | filter/config.Y | 2 | ||||
-rw-r--r-- | filter/data.h | 1 | ||||
-rw-r--r-- | filter/f-inst.c | 5 | ||||
-rw-r--r-- | lib/route.h | 24 | ||||
-rw-r--r-- | nest/rt-attr.c | 11 | ||||
-rw-r--r-- | nest/rt-dev.c | 3 | ||||
-rw-r--r-- | nest/rt-show.c | 2 | ||||
-rw-r--r-- | nest/rt-table.c | 9 | ||||
-rw-r--r-- | nest/rt.h | 1 | ||||
-rw-r--r-- | proto/babel/babel.c | 12 | ||||
-rw-r--r-- | proto/bgp/attrs.c | 6 | ||||
-rw-r--r-- | proto/bgp/packets.c | 2 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 2 | ||||
-rw-r--r-- | proto/ospf/rt.c | 6 | ||||
-rw-r--r-- | proto/perf/perf.c | 3 | ||||
-rw-r--r-- | proto/rip/rip.c | 8 | ||||
-rw-r--r-- | proto/rpki/rpki.c | 3 | ||||
-rw-r--r-- | proto/static/static.c | 7 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 2 |
20 files changed, 65 insertions, 47 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index 4df1d94f..a71624aa 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1732,8 +1732,7 @@ Common route attributes are: default value for new routes is <cf/SCOPE_UNIVERSE/. <tag><label id="rta-preference"><m/int/ preference</tag> - Preference of the route. Valid values are 0-65535. (See the chapter - about routing tables.) + Preference of the route. <tag><label id="rta-from"><m/ip/ from</tag> The router which the route has originated from. diff --git a/filter/config.Y b/filter/config.Y index f21f1c8e..dcfae788 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -286,7 +286,6 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, IF, THEN, ELSE, CASE, TRUE, FALSE, RT, RO, UNKNOWN, GENERIC, FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, - PREFERENCE, ROA_CHECK, ASN, SRC, DST, IS_V4, IS_V6, LEN, MAXLEN, @@ -773,7 +772,6 @@ static_attr: | IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); } | IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); } | 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); } ; diff --git a/filter/data.h b/filter/data.h index 4d2622ab..0e25ccd9 100644 --- a/filter/data.h +++ b/filter/data.h @@ -32,7 +32,6 @@ enum f_sa_code { SA_IFNAME, SA_IFINDEX, SA_WEIGHT, - SA_PREF, SA_GW_MPLS, } PACKED; diff --git a/filter/f-inst.c b/filter/f-inst.c index c5947955..9530d9ad 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -543,7 +543,6 @@ case SA_IFNAME: RESULT(sa.type, s, rta->nh.iface ? rta->nh.iface->name : ""); break; case SA_IFINDEX: RESULT(sa.type, i, rta->nh.iface ? rta->nh.iface->index : 0); break; case SA_WEIGHT: RESULT(sa.type, i, rta->nh.weight + 1); break; - case SA_PREF: RESULT(sa.type, i, rta->pref); break; case SA_GW_MPLS: RESULT(sa.type, i, rta->nh.labels ? rta->nh.label[0] : MPLS_NULL); break; default: @@ -648,10 +647,6 @@ } break; - case SA_PREF: - rta->pref = v1.val.i; - break; - default: bug("Invalid static attribute access (%u/%u)", sa.type, sa.sa_code); } diff --git a/lib/route.h b/lib/route.h index 3b368696..be72bb16 100644 --- a/lib/route.h +++ b/lib/route.h @@ -89,7 +89,6 @@ typedef struct rta { u16 source:7; /* Route source (RTS_...) */ u16 scope:4; /* Route scope (SCOPE_... -- see ip.h) */ u16 dest:4; /* Route destination type (RTD_...) */ - word pref; struct nexthop nh; /* Next hop */ } rta; @@ -181,10 +180,6 @@ struct ea_class_ref { struct ea_class *class; }; -#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other - protocol-specific metric is availabe */ -extern struct ea_class ea_gen_igp_metric; - void ea_register_init(struct ea_class *); struct ea_class_ref *ea_register_alloc(pool *, struct ea_class); @@ -290,6 +285,23 @@ static inline void ea_set_attr_data(ea_list **to, const struct ea_class *def, uint flags, void *data, uint len) { ea_set_attr(to, EA_LITERAL_STORE_ADATA(def, flags, data, len)); } +/* + * Common route attributes + */ + +/* Preference: first-order comparison */ +extern struct ea_class ea_gen_preference; +static inline u32 rt_get_preference(rte *rt) +{ return ea_get_int(rt->attrs->eattrs, &ea_gen_preference, 0); } + +/* IGP metric: second-order comparison */ +extern struct ea_class ea_gen_igp_metric; +u32 rt_get_igp_metric(rte *rt); +#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other + protocol-specific metric is availabe */ + + +/* Next hop structures */ #define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK) @@ -319,6 +331,4 @@ void rta_dump(rta *); void rta_dump_all(void); void rta_show(struct cli *, rta *); -u32 rt_get_igp_metric(rte *rt); - #endif diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 6bb27623..e5d87b53 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -65,6 +65,11 @@ struct ea_class ea_gen_igp_metric = { .type = T_INT, }; +struct ea_class ea_gen_preference = { + .name = "preference", + .type = T_INT, +}; + const char * const rta_src_names[RTS_MAX] = { [RTS_STATIC] = "static", [RTS_INHERIT] = "inherit", @@ -1228,7 +1233,6 @@ rta_hash(rta *a) BMIX(source); BMIX(scope); BMIX(dest); - MIX(pref); #undef MIX return mem_hash_value(&h) ^ nexthop_hash(&(a->nh)) ^ ea_hash(a->eattrs); @@ -1389,8 +1393,8 @@ rta_dump(rta *a) "RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" }; static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" }; - debug("pref=%d uc=%d %s %s%s h=%04x", - a->pref, a->uc, rts[a->source], ip_scope_text(a->scope), + debug("uc=%d %s %s%s h=%04x", + a->uc, rts[a->source], ip_scope_text(a->scope), rtd[a->dest], a->hash_key); if (!a->cached) debug(" !CACHED"); @@ -1469,6 +1473,7 @@ rta_init(void) rte_src_init(); ea_class_init(); + ea_register_init(&ea_gen_preference); ea_register_init(&ea_gen_igp_metric); } diff --git a/nest/rt-dev.c b/nest/rt-dev.c index bdf8584d..696b37b8 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -83,13 +83,14 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) struct rte_src *src = rt_get_source(P, ad->iface->index); rta a0 = { - .pref = c->preference, .source = RTS_DEVICE, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, .nh.iface = ad->iface, }; + ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, c->preference); + a = rta_lookup(&a0); e = rte_get_temp(a, src); e->pflags = 0; diff --git a/nest/rt-show.c b/nest/rt-show.c index 7d02f52e..1c764d8c 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -61,7 +61,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary if (get_route_info) get_route_info(e, info); else - bsprintf(info, " (%d)", a->pref); + bsprintf(info, " (%d)", rt_get_preference(e)); if (d->last_table != d->tab) rt_show_table(c, d); diff --git a/nest/rt-table.c b/nest/rt-table.c index 01194e02..919576bd 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -652,9 +652,12 @@ rte_better(rte *new, rte *old) if (!rte_is_valid(new)) return 0; - if (new->attrs->pref > old->attrs->pref) + u32 np = rt_get_preference(new); + u32 op = rt_get_preference(old); + + if (np > op) return 1; - if (new->attrs->pref < old->attrs->pref) + if (np < op) return 0; if (new->src->proto->proto != old->src->proto->proto) { @@ -678,7 +681,7 @@ rte_mergable(rte *pri, rte *sec) if (!rte_is_valid(pri) || !rte_is_valid(sec)) return 0; - if (pri->attrs->pref != sec->attrs->pref) + if (rt_get_preference(pri) != rt_get_preference(sec)) return 0; if (pri->src->proto->proto != sec->src->proto->proto) @@ -329,6 +329,7 @@ int rt_flowspec_check(rtable *tab_ip, rtable *tab_flow, const net_addr *n, rta * #define DEF_PREF_BGP 100 /* BGP */ #define DEF_PREF_RPKI 100 /* RPKI */ #define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */ +#define DEF_PREF_UNKNOWN 0 /* Routes with no preference set */ /* * Route Origin Authorization diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 97dca4ac..afd0b1e1 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -645,10 +645,11 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) { struct { ea_list l; - eattr a[3]; + eattr a[4]; } eattrs = { - .l.count = 3, + .l.count = ARRAY_SIZE(eattrs.a), .a = { + EA_LITERAL_EMBEDDED(&ea_gen_preference, 0, c->preference), EA_LITERAL_EMBEDDED(&ea_babel_metric, 0, r->metric), EA_LITERAL_STORE_ADATA(&ea_babel_router_id, 0, &r->router_id, sizeof(r->router_id)), EA_LITERAL_EMBEDDED(&ea_babel_seqno, 0, r->seqno), @@ -659,7 +660,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) .source = RTS_BABEL, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, - .pref = c->preference, .from = r->neigh->addr, .nh.gw = r->next_hop, .nh.iface = r->neigh->ifa->iface, @@ -687,9 +687,10 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) .source = RTS_BABEL, .scope = SCOPE_UNIVERSE, .dest = RTD_UNREACHABLE, - .pref = 1, }; + ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, 1); + rta *a = rta_lookup(&a0); rte *rte = rte_get_temp(a, p->p.main_source); rte->pflags = 0; @@ -2025,7 +2026,8 @@ babel_get_route_info(rte *rte, byte *buf) if (e) memcpy(&rid, e->u.ptr->data, sizeof(u64)); - buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref, + buf += bsprintf(buf, " (%d/%d) [%lR]", + rt_get_preference(rte), ea_get_int(rte->attrs->eattrs, &ea_babel_metric, BABEL_INFINITY), rid); } diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 597cf96c..097ba9a2 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -2169,7 +2169,7 @@ bgp_rte_mergable(rte *pri, rte *sec) static inline int same_group(rte *r, u32 lpref, u32 lasn) { - return (r->attrs->pref == lpref) && (bgp_get_neighbor(r) == lasn); + return (rt_get_preference(r) == lpref) && (bgp_get_neighbor(r) == lasn); } static inline int @@ -2184,7 +2184,7 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) { rte *r, *s; rte *key = new ? new : old; - u32 lpref = key->attrs->pref; + u32 lpref = rt_get_preference(key); u32 lasn = bgp_get_neighbor(key); int old_suppressed = old ? !!(old->pflags & BGP_REF_SUPPRESSED) : 0; @@ -2381,7 +2381,7 @@ bgp_get_route_info(rte *e, byte *buf) eattr *o = ea_find(e->attrs->eattrs, BGP_EA_ID(BA_ORIGIN)); u32 origas; - buf += bsprintf(buf, " (%d", e->attrs->pref); + buf += bsprintf(buf, " (%d", rt_get_preference(e)); if (e->pflags & BGP_REF_SUPPRESSED) buf += bsprintf(buf, "-"); diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 5c9bb8ba..45a4b1de 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -2478,7 +2478,7 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis a->scope = SCOPE_UNIVERSE; a->from = s->proto->remote_ip; a->eattrs = ea; - a->pref = c->c.preference; + ea_set_attr_u32(&a->eattrs, &ea_gen_preference, 0, c->c.preference); c->desc->decode_next_hop(s, nh, nh_len, a); bgp_finish_attrs(s, a); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 66d0eba6..427c2c86 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -588,7 +588,7 @@ ospf_get_route_info(rte * rte, byte * buf) } buf += bsprintf(buf, " %s", type); - buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, ea_get_int(rte->attrs->eattrs, &ea_ospf_metric1, LSINFINITY)); + buf += bsprintf(buf, " (%d/%d", rt_get_preference(rte), ea_get_int(rte->attrs->eattrs, &ea_ospf_metric1, LSINFINITY)); if (rte->attrs->source == RTS_OSPF_EXT2) buf += bsprintf(buf, "/%d", ea_get_int(rte->attrs->eattrs, &ea_ospf_metric2, LSINFINITY)); buf += bsprintf(buf, ")"); diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index 55bad599..3d8cf22c 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -2057,7 +2057,6 @@ again1: .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, .nh = *(nf->n.nhs), - .pref = p->p.main_channel->preference, }; if (reload || ort_changed(nf, &a0)) @@ -2069,12 +2068,15 @@ again1: struct { ea_list l; - eattr a[4]; + eattr a[5]; } eattrs; eattrs.l = (ea_list) {}; eattrs.a[eattrs.l.count++] = + EA_LITERAL_EMBEDDED(&ea_gen_preference, 0, p->p.main_channel->preference); + + eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_ospf_metric1, 0, nf->n.metric1); if (nf->n.type == RTS_OSPF_EXT2) diff --git a/proto/perf/perf.c b/proto/perf/perf.c index 2978100b..7b18866c 100644 --- a/proto/perf/perf.c +++ b/proto/perf/perf.c @@ -146,12 +146,13 @@ perf_loop(void *data) .source = RTS_PERF, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, - .pref = p->p.main_channel->preference, .nh.iface = p->ifa->iface, .nh.gw = gw, .nh.weight = 1, }; + ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); + p->data[i].a = rta_lookup(&a0); } else diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 52a3bd2c..244bcd0a 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -152,7 +152,6 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) { /* Update */ rta a0 = { - .pref = p->p.main_channel->preference, .source = RTS_RIP, .scope = SCOPE_UNIVERSE, .dest = RTD_UNICAST, @@ -197,11 +196,12 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) struct { ea_list l; - eattr a[3]; + eattr a[4]; struct rip_iface_adata riad; } ea_block = { - .l.count = 3, + .l.count = ARRAY_SIZE(ea_block.a), .a = { + EA_LITERAL_EMBEDDED(&ea_gen_preference, 0, p->p.main_channel->preference), EA_LITERAL_EMBEDDED(&ea_rip_metric, 0, rt_metric), EA_LITERAL_EMBEDDED(&ea_rip_tag, 0, rt_tag), EA_LITERAL_DIRECT_ADATA(&ea_rip_from, 0, &ea_block.riad.ad), @@ -1210,7 +1210,7 @@ rip_get_route_info(rte *rte, byte *buf) u32 rt_metric = ea_get_int(rte->attrs->eattrs, &ea_rip_metric, p->infinity); u32 rt_tag = ea_get_int(rte->attrs->eattrs, &ea_rip_tag, 0); - buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rt_metric); + buf += bsprintf(buf, " (%d/%d)", rt_get_preference(rte), rt_metric); if (rt_tag) bsprintf(buf, " [%04x]", rt_tag); diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index d4e95a83..710764e2 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -121,12 +121,13 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_ struct rpki_proto *p = cache->p; rta a0 = { - .pref = channel->preference, .source = RTS_RPKI, .scope = SCOPE_UNIVERSE, .dest = RTD_NONE, }; + ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, channel->preference); + rta *a = rta_lookup(&a0); rte *e = rte_get_temp(a, p->p.main_source); diff --git a/proto/static/static.c b/proto/static/static.c index 090ec875..d4b1c5f3 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -58,7 +58,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r) a->source = RTS_STATIC; a->scope = SCOPE_UNIVERSE; a->dest = r->dest; - a->pref = p->p.main_channel->preference; + ea_set_attr_u32(&a->eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); if (r->dest == RTD_UNICAST) { @@ -712,10 +712,11 @@ static void static_get_route_info(rte *rte, byte *buf) { eattr *a = ea_find(rte->attrs->eattrs, &ea_gen_igp_metric); + u32 pref = rt_get_preference(rte); if (a) - buf += bsprintf(buf, " (%d/%u)", rte->attrs->pref, a->u.data); + buf += bsprintf(buf, " (%d/%u)", pref, a->u.data); else - buf += bsprintf(buf, " (%d)", rte->attrs->pref); + buf += bsprintf(buf, " (%d)", pref); } static void diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 4da51ce2..b8e7670e 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -438,7 +438,7 @@ krt_learn_async(struct krt_proto *p, rte *e, int new) rte *g, **gg, *best, **bestp, *old_best; ASSERT(!e->attrs->cached); - e->attrs->pref = p->p.main_channel->preference; + ea_set_attr_u32(&e->attrs->eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); e->attrs = rta_lookup(e->attrs); |