]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Babel: Convert the rte-local attributes to extended attributes
authorMaria Matejka <mq@ucw.cz>
Thu, 13 Feb 2020 12:22:15 +0000 (13:22 +0100)
committerMaria Matejka <mq@ucw.cz>
Wed, 13 Oct 2021 17:09:04 +0000 (19:09 +0200)
nest/route.h
proto/babel/babel.c
proto/babel/babel.h

index 1ed40d68f6c05bb2e77f3458ace95d54584ac549..531a4ca8b8d98c110fc17477fa4781bec9a31d2e 100644 (file)
@@ -249,13 +249,6 @@ typedef struct rte {
       u8 suppressed;                   /* Used for deterministic MED comparison */
       s8 stale;                                /* Route is LLGR_STALE, -1 if unknown */
     } bgp;
-#endif
-#ifdef CONFIG_BABEL
-    struct {
-      u16 seqno;                       /* Babel seqno */
-      u16 metric;                      /* Babel metric */
-      u64 router_id;                   /* Babel router id */
-    } babel;
 #endif
     struct {                           /* Routes generated by krt sync (both temporary and inherited ones) */
       s8 src;                          /* Alleged route source (see krt.h) */
index d17f318be8571b6eeab16cfa19d40f08b836eca1..07213c8c581a113628d30485c658dbdbbada3a1a 100644 (file)
@@ -648,6 +648,29 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
       .from = r->neigh->addr,
       .nh.gw = r->next_hop,
       .nh.iface = r->neigh->ifa->iface,
+      .eattrs = alloca(sizeof(ea_list) + 3*sizeof(eattr)),
+    };
+
+    *a0.eattrs = (ea_list) { .count = 3 };
+    a0.eattrs->attrs[0] = (eattr) {
+      .id = EA_BABEL_METRIC,
+      .type = EAF_TYPE_INT,
+      .u.data = r->metric,
+    };
+
+    struct adata *ad = alloca(sizeof(struct adata) + sizeof(u64));
+    ad->length = sizeof(u64);
+    memcpy(ad->data, &(r->router_id), sizeof(u64));
+    a0.eattrs->attrs[1] = (eattr) {
+      .id = EA_BABEL_ROUTER_ID,
+      .type = EAF_TYPE_OPAQUE,
+      .u.ptr = ad,
+    };
+
+    a0.eattrs->attrs[2] = (eattr) {
+      .id = EA_BABEL_SEQNO,
+      .type = EAF_TYPE_INT,
+      .u.data = r->seqno,
     };
 
     /*
@@ -660,10 +683,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
 
     rta *a = rta_lookup(&a0);
     rte *rte = rte_get_temp(a, p->p.main_source);
-    rte->u.babel.seqno = r->seqno;
-    rte->u.babel.metric = r->metric;
-    rte->u.babel.router_id = r->router_id;
-    rte->pflags = EA_ID_FLAG(EA_BABEL_METRIC) | EA_ID_FLAG(EA_BABEL_ROUTER_ID);
 
     e->unreachable = 0;
     rte_update2(c, e->n.addr, rte, p->p.main_source);
@@ -680,7 +699,6 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
 
     rta *a = rta_lookup(&a0);
     rte *rte = rte_get_temp(a, p->p.main_source);
-    memset(&rte->u.babel, 0, sizeof(rte->u.babel));
     rte->pflags = 0;
 
     e->unreachable = 1;
@@ -2009,7 +2027,13 @@ babel_dump(struct proto *P)
 static void
 babel_get_route_info(rte *rte, byte *buf)
 {
-  buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref, rte->u.babel.metric, rte->u.babel.router_id);
+  u64 rid = 0;
+  eattr *e = ea_find(rte->attrs->eattrs, EA_BABEL_ROUTER_ID);
+  if (e)
+    memcpy(&rid, e->u.ptr->data, sizeof(u64));
+
+  buf += bsprintf(buf, " (%d/%d) [%lR]", rte->attrs->pref,
+      ea_get_int(rte->attrs->eattrs, EA_BABEL_METRIC, BABEL_INFINITY), rid);
 }
 
 static int
@@ -2017,6 +2041,9 @@ babel_get_attr(const eattr *a, byte *buf, int buflen UNUSED)
 {
   switch (a->id)
   {
+  case EA_BABEL_SEQNO:
+    return GA_FULL;
+
   case EA_BABEL_METRIC:
     bsprintf(buf, "metric: %d", a->u.data);
     return GA_FULL;
@@ -2240,27 +2267,6 @@ babel_preexport(struct proto *P, struct rte *new)
   return 0;
 }
 
-static void
-babel_make_tmp_attrs(struct rte *rt, struct linpool *pool)
-{
-  struct adata *id = lp_alloc_adata(pool, sizeof(u64));
-  memcpy(id->data, &rt->u.babel.router_id, sizeof(u64));
-
-  rte_init_tmp_attrs(rt, pool, 2);
-  rte_make_tmp_attr(rt, EA_BABEL_METRIC, EAF_TYPE_INT, rt->u.babel.metric);
-  rte_make_tmp_attr(rt, EA_BABEL_ROUTER_ID, EAF_TYPE_OPAQUE, (uintptr_t) id);
-}
-
-static void
-babel_store_tmp_attrs(struct rte *rt, struct linpool *pool)
-{
-  rte_init_tmp_attrs(rt, pool, 2);
-  rt->u.babel.metric = rte_store_tmp_attr(rt, EA_BABEL_METRIC);
-
-  /* EA_BABEL_ROUTER_ID is read-only, we do not really save the value */
-  rte_store_tmp_attr(rt, EA_BABEL_ROUTER_ID);
-}
-
 /*
  * babel_rt_notify - core tells us about new route (possibly our own),
  * so store it into our data structures.
@@ -2275,10 +2281,22 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
   if (new)
   {
     /* Update */
-    uint internal = (new->src->proto == P);
-    uint rt_seqno = internal ? new->u.babel.seqno : p->update_seqno;
+    uint rt_seqno;
     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 = 0;
+
+    if (new->src->proto == P)
+    {
+      rt_seqno = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
+      eattr *e = ea_find(new->attrs->eattrs, EA_BABEL_ROUTER_ID);
+      if (e)
+       memcpy(&rt_router_id, e->u.ptr->data, sizeof(u64));
+    }
+    else
+    {
+      rt_seqno = p->update_seqno;
+      rt_router_id = p->router_id;
+    }
 
     if (rt_metric > BABEL_INFINITY)
     {
@@ -2321,21 +2339,16 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
 static int
 babel_rte_better(struct rte *new, struct rte *old)
 {
-  return new->u.babel.metric < old->u.babel.metric;
-}
+  uint new_metric = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
+  uint old_metric = ea_find(old->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
 
-static int
-babel_rte_same(struct rte *new, struct rte *old)
-{
-  return ((new->u.babel.seqno == old->u.babel.seqno) &&
-         (new->u.babel.metric == old->u.babel.metric) &&
-         (new->u.babel.router_id == old->u.babel.router_id));
+  return new_metric < old_metric;
 }
 
 static u32
 babel_rte_igp_metric(struct rte *rt)
 {
-  return rt->u.babel.metric;
+  return ea_get_int(rt->attrs->eattrs, EA_BABEL_METRIC, BABEL_INFINITY);
 }
 
 
@@ -2369,10 +2382,7 @@ babel_init(struct proto_config *CF)
   P->if_notify = babel_if_notify;
   P->rt_notify = babel_rt_notify;
   P->preexport = babel_preexport;
-  P->make_tmp_attrs = babel_make_tmp_attrs;
-  P->store_tmp_attrs = babel_store_tmp_attrs;
   P->rte_better = babel_rte_better;
-  P->rte_same = babel_rte_same;
   P->rte_igp_metric = babel_rte_igp_metric;
 
   return P;
index 84feb085dae72a8cd21c0c42131cb5724419bed1..8b6da3c8ce917440584d74f86d59eac4dcf60c84 100644 (file)
@@ -28,6 +28,7 @@
 
 #define EA_BABEL_METRIC                EA_CODE(PROTOCOL_BABEL, 0)
 #define EA_BABEL_ROUTER_ID     EA_CODE(PROTOCOL_BABEL, 1)
+#define EA_BABEL_SEQNO         EA_CODE(PROTOCOL_BABEL, 2)
 
 #define BABEL_MAGIC            42
 #define BABEL_VERSION          2