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 692b7d89..1c4eb0a2 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 5d78c98e..be1c3e1d 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 8253ab8e..66b8b312 100644 --- a/lib/route.h +++ b/lib/route.h @@ -91,7 +91,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; @@ -183,10 +182,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); @@ -292,6 +287,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(const 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) @@ -321,6 +333,4 @@ void rta_dump(rta *); void rta_dump_all(void); void rta_show(struct cli *, rta *); -u32 rt_get_igp_metric(const 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 77213a2c..2d0c594f 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -80,13 +80,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); + rte e0 = { .attrs = rta_lookup(&a0), .src = src, diff --git a/nest/rt-show.c b/nest/rt-show.c index 26180a8d..6c5f32b1 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 d89c087d..e0c475b7 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -634,9 +634,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) { @@ -660,7 +663,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) @@ -487,6 +487,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 eaebdb83..6cc6b794 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, @@ -689,9 +689,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); + rte e0 = { .attrs = &a0, .src = p->p.main_source, @@ -2028,7 +2029,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 73939bf0..6a91e6e7 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -2172,7 +2172,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 @@ -2186,7 +2186,7 @@ int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) { 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; @@ -2388,7 +2388,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 d64cabe8..f87d25a3 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -2479,7 +2479,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 bb0d6aac..121e8f9c 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 a6d39d7f..fb822e34 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 13ce656a..f07887a3 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 739fe96c..cf186f87 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), @@ -1209,7 +1209,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 153e5293..eecab897 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); + rte e0 = { .attrs = &a0, .src = p->p.main_source, }; rte_update(channel, &pfxr->n, &e0, p->p.main_source); diff --git a/proto/static/static.c b/proto/static/static.c index 2fc8e788..9b6c38ee 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) { @@ -695,10 +695,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 5a29289f..b94b05ae 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -439,7 +439,7 @@ krt_learn_async(struct krt_proto *p, rte *e, int new) struct rte_storage *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); struct rte_storage *ee = rte_store(e, n, p->krt_table); |