]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Moved route preference to eattrs
authorMaria Matejka <mq@ucw.cz>
Wed, 20 Apr 2022 10:24:26 +0000 (12:24 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 4 May 2022 13:39:21 +0000 (15:39 +0200)
20 files changed:
doc/bird.sgml
filter/config.Y
filter/data.h
filter/f-inst.c
lib/route.h
nest/rt-attr.c
nest/rt-dev.c
nest/rt-show.c
nest/rt-table.c
nest/rt.h
proto/babel/babel.c
proto/bgp/attrs.c
proto/bgp/packets.c
proto/ospf/ospf.c
proto/ospf/rt.c
proto/perf/perf.c
proto/rip/rip.c
proto/rpki/rpki.c
proto/static/static.c
sysdep/unix/krt.c

index 4df1d94fe6992546b8dbcc134fe4bd98821d044c..a71624aae24e3cbd696cc3e688e971695f4df46f 100644 (file)
@@ -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.
index f21f1c8e83100b011b7c09fcfad332f9a99e2397..dcfae7881ce5b9797674a6d17afa0c25496e3313 100644 (file)
@@ -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); }
  ;
 
index 4d2622ab795ffdaa8f25b8baef56ee60f82834ba..0e25ccd94a8e31be99024e72e4f931ad22f3cc0f 100644 (file)
@@ -32,7 +32,6 @@ enum f_sa_code {
   SA_IFNAME,
   SA_IFINDEX,
   SA_WEIGHT,
-  SA_PREF,
   SA_GW_MPLS,
 } PACKED;
 
index c5947955494fdf2e9c535a1da2fd3710038e3a13..9530d9ad8271ff461170667dcecc3660f36cc247 100644 (file)
       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:
         }
        break;
 
-      case SA_PREF:
-       rta->pref = v1.val.i;
-       break;
-
       default:
        bug("Invalid static attribute access (%u/%u)", sa.type, sa.sa_code);
       }
index 3b3686964287bf05034a04fec818750338536ca2..be72bb16341c063861e4008e1e3160c4495166e4 100644 (file)
@@ -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
index 6bb276237b32acd8931560515663fb04b65ecf1b..e5d87b536bfb557b5ff956d47766c5ff9f99168b 100644 (file)
@@ -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);
 }
 
index bdf8584d70e9ea376fe63e7c63c4c5940ae1abf0..696b37b8da4e491c4acda36b6b7a6b9d648c589a 100644 (file)
@@ -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;
index 7d02f52ede58c1076955a28b2cca5637348724a1..1c764d8caa0ce2d60709ec4d9fb66856234e5493 100644 (file)
@@ -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);
index 01194e02136995376c92c697f1f66d49f674a77e..919576bdeb83423021af43a89555f9d79dc0e452 100644 (file)
@@ -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)
index 7451a261745a046a30e276371b80e699900c2be3..6bd9cd387701e3c92443553b890fc02d00b6741d 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -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
index 97dca4aceb538becb0d7716e98bfec880aff3a8c..afd0b1e104544622a010d7ad278b011e6a7d3994 100644 (file)
@@ -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);
 }
 
index 597cf96cb6412f8de22b60f28b2e58bc873f20ef..097ba9a21fe673c2e80e3dc4607ec5d0850272b4 100644 (file)
@@ -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, "-");
index 5c9bb8ba4935ec1719d8d61ec6231a0fda03576c..45a4b1deee0fdeb1c71a0dc7ad4d794d82191bce 100644 (file)
@@ -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);
index 66d0eba67612afed2587ff4f3dc1199e342217d9..427c2c8614d6fd9e52bf6fe55ce15a29c8f72bde 100644 (file)
@@ -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, ")");
index 55bad59993516f1bf7325b4e6063ee03b205e497..3d8cf22cc0ddaeee09aab0af2358e3059a51160f 100644 (file)
@@ -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,11 +2068,14 @@ 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);
 
index 2978100b2b4c99064bf6289867dd03a3d70a21c2..7b18866ced5207431e7f60ca0ab186c69933070a 100644 (file)
@@ -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
index 52a3bd2c9227e0479af21569bbd504ce199ea551..244bcd0aa8bb52c71a829c5edd73da1aa84b6b83 100644 (file)
@@ -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);
index d4e95a83dc4e5e56fced2be097aa6e55fbf23c64..710764e2a78fd010affb4e23290f675c74eaf412 100644 (file)
@@ -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);
 
index 090ec87503b7b5bd789a2fdee259448337f59fd6..d4b1c5f3876d430370ca20d8cabeb363de99c701 100644 (file)
@@ -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
index 4da51ce2dd9191afe2403fec8a4960f6b833c5c3..b8e7670e30a1dfb1c013cf635a45156f8c713e1a 100644 (file)
@@ -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);