]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
OSPF: Convert the rte-local attributes to extended attributes
authorMaria Matejka <mq@jmq.cz>
Tue, 11 Feb 2020 20:24:15 +0000 (21:24 +0100)
committerMaria Matejka <mq@ucw.cz>
Thu, 30 Apr 2020 14:14:26 +0000 (16:14 +0200)
nest/route.h
nest/rt-table.c
proto/ospf/ospf.c
proto/ospf/rt.c

index a7a2782f79e237a69f12ec6878612911ceb9878e..7b15fa3d3ac8aaee2e392813b8e1b4f0e3d620dd 100644 (file)
@@ -222,13 +222,6 @@ typedef struct rte {
   byte pflags;                         /* Protocol-specific flags */
   btime lastmod;                       /* Last modified */
   union {                              /* Protocol-dependent data (metrics etc.) */
-#ifdef CONFIG_OSPF
-    struct {
-      u32 metric1, metric2;            /* OSPF Type 1 and Type 2 metrics */
-      u32 tag;                         /* External route tag */
-      u32 router_id;                   /* Router that originated this route */
-    } ospf;
-#endif
 #ifdef CONFIG_BABEL
     struct {
       u16 seqno;                       /* Babel seqno */
index a35ff93fe5c52c1cbb99434427ebfc4e17fc9ab9..5d1932c55e8affebd348571a29c13d37ad35fe3d 100644 (file)
 #include "proto/rip/rip.h"
 #endif
 
+#ifdef CONFIG_OSPF
+#include "proto/ospf/ospf.h"
+#endif
+
 #ifdef CONFIG_BGP
 #include "proto/bgp/bgp.h"
 #endif
@@ -2826,7 +2830,7 @@ rt_get_igp_metric(rte *rt)
   if ((a->source == RTS_OSPF) ||
       (a->source == RTS_OSPF_IA) ||
       (a->source == RTS_OSPF_EXT1))
-    return rt->u.ospf.metric1;
+    return ea_find(rt->attrs->eattrs, EA_OSPF_METRIC1)->u.data;
 #endif
 
 #ifdef CONFIG_RIP
index 21aa2ce913898c3f8f2bda00a248b1acc2bae650..3c0a923246485fff59ac9ee950d0f47b8afd3510 100644 (file)
 #include "ospf.h"
 
 static int ospf_preexport(struct proto *P, rte **new, struct linpool *pool);
-static void ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
-static void ospf_store_tmp_attrs(struct rte *rt, struct linpool *pool);
 static void ospf_reload_routes(struct channel *C);
 static int ospf_rte_better(struct rte *new, struct rte *old);
-static int ospf_rte_same(struct rte *new, struct rte *old);
 static void ospf_disp(timer *timer);
 
 
@@ -378,10 +375,7 @@ ospf_init(struct proto_config *CF)
   P->reload_routes = ospf_reload_routes;
   P->feed_begin = ospf_feed_begin;
   P->feed_end = ospf_feed_end;
-  P->make_tmp_attrs = ospf_make_tmp_attrs;
-  P->store_tmp_attrs = ospf_store_tmp_attrs;
   P->rte_better = ospf_rte_better;
-  P->rte_same = ospf_rte_same;
 
   return P;
 }
@@ -390,7 +384,9 @@ ospf_init(struct proto_config *CF)
 static int
 ospf_rte_better(struct rte *new, struct rte *old)
 {
-  if (new->u.ospf.metric1 == LSINFINITY)
+  u32 new_metric1 = ea_get_int(new->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);
+
+  if (new_metric1 == LSINFINITY)
     return 0;
 
   if(new->attrs->source < old->attrs->source) return 1;
@@ -398,28 +394,19 @@ ospf_rte_better(struct rte *new, struct rte *old)
 
   if(new->attrs->source == RTS_OSPF_EXT2)
   {
-    if(new->u.ospf.metric2 < old->u.ospf.metric2) return 1;
-    if(new->u.ospf.metric2 > old->u.ospf.metric2) return 0;
+    u32 old_metric2 = ea_get_int(old->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY);
+    u32 new_metric2 = ea_get_int(new->attrs->eattrs, EA_OSPF_METRIC2, LSINFINITY);
+    if(new_metric2 < old_metric2) return 1;
+    if(new_metric2 > old_metric2) return 0;
   }
 
-  if (new->u.ospf.metric1 < old->u.ospf.metric1)
+  u32 old_metric1 = ea_get_int(old->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY);
+  if (new_metric1 < old_metric1)
     return 1;
 
   return 0;                    /* Old is shorter or same */
 }
 
-static int
-ospf_rte_same(struct rte *new, struct rte *old)
-{
-  /* new->attrs == old->attrs always */
-  return
-    new->u.ospf.metric1 == old->u.ospf.metric1 &&
-    new->u.ospf.metric2 == old->u.ospf.metric2 &&
-    new->u.ospf.tag == old->u.ospf.tag &&
-    new->u.ospf.router_id == old->u.ospf.router_id;
-}
-
-
 void
 ospf_schedule_rtcalc(struct ospf_proto *p)
 {
@@ -501,26 +488,6 @@ ospf_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
   return 0;
 }
 
-static void
-ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool)
-{
-  rte_init_tmp_attrs(rt, pool, 4);
-  rte_make_tmp_attr(rt, EA_OSPF_METRIC1, EAF_TYPE_INT, rt->u.ospf.metric1);
-  rte_make_tmp_attr(rt, EA_OSPF_METRIC2, EAF_TYPE_INT, rt->u.ospf.metric2);
-  rte_make_tmp_attr(rt, EA_OSPF_TAG, EAF_TYPE_INT, rt->u.ospf.tag);
-  rte_make_tmp_attr(rt, EA_OSPF_ROUTER_ID, EAF_TYPE_ROUTER_ID, rt->u.ospf.router_id);
-}
-
-static void
-ospf_store_tmp_attrs(struct rte *rt, struct linpool *pool)
-{
-  rte_init_tmp_attrs(rt, pool, 4);
-  rt->u.ospf.metric1 = rte_store_tmp_attr(rt, EA_OSPF_METRIC1);
-  rt->u.ospf.metric2 = rte_store_tmp_attr(rt, EA_OSPF_METRIC2);
-  rt->u.ospf.tag = rte_store_tmp_attr(rt, EA_OSPF_TAG);
-  rt->u.ospf.router_id = rte_store_tmp_attr(rt, EA_OSPF_ROUTER_ID);
-}
-
 /**
  * ospf_shutdown - Finish of OSPF instance
  * @P: OSPF protocol instance
@@ -607,16 +574,20 @@ ospf_get_route_info(rte * rte, byte * buf)
   }
 
   buf += bsprintf(buf, " %s", type);
-  buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, rte->u.ospf.metric1);
+  buf += bsprintf(buf, " (%d/%d", rte->attrs->pref, ea_find(rte->attrs->eattrs, EA_OSPF_METRIC1)->u.data);
   if (rte->attrs->source == RTS_OSPF_EXT2)
-    buf += bsprintf(buf, "/%d", rte->u.ospf.metric2);
+    buf += bsprintf(buf, "/%d", ea_find(rte->attrs->eattrs, EA_OSPF_METRIC2)->u.data);
   buf += bsprintf(buf, ")");
-  if ((rte->attrs->source == RTS_OSPF_EXT1 || rte->attrs->source == RTS_OSPF_EXT2) && rte->u.ospf.tag)
+  if (rte->attrs->source == RTS_OSPF_EXT1 || rte->attrs->source == RTS_OSPF_EXT2)
   {
-    buf += bsprintf(buf, " [%x]", rte->u.ospf.tag);
+    eattr *ea = ea_find(rte->attrs->eattrs, EA_OSPF_TAG);
+    if (ea)
+      buf += bsprintf(buf, " [%x]", ea->u.data);
   }
-  if (rte->u.ospf.router_id)
-    buf += bsprintf(buf, " [%R]", rte->u.ospf.router_id);
+  
+  eattr *ea = ea_find(rte->attrs->eattrs, EA_OSPF_ROUTER_ID);
+  if (ea)
+    buf += bsprintf(buf, " [%R]", ea->u.data);
 }
 
 static int
index 21243c949a9062944899da9a6891628836fe8149..521a6633200a54abce635924f2e91eac02042cb4 100644 (file)
@@ -2053,25 +2053,50 @@ again1:
 
       if (reload || ort_changed(nf, &a0))
       {
-       rte e0 = {
-         .attrs = rta_lookup(&a0),
-         .u.ospf.metric1 = nf->old_metric1 = nf->n.metric1,
-         .u.ospf.metric2 = nf->old_metric2 = nf->n.metric2,
-         .u.ospf.tag = nf->old_tag = nf->n.tag,
-         .u.ospf.router_id = nf->old_rid = nf->n.rid,
-         .pflags = EA_ID_FLAG(EA_OSPF_METRIC1) | EA_ID_FLAG(EA_OSPF_ROUTER_ID),
+       _Bool have_metric2 = (nf->n.type == RTS_OSPF_EXT2);
+       _Bool have_tag = (((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2)) && nf->n.tag);
+       _Bool have_router_id = !!nf->n.rid;
+
+       a0.eattrs = alloca(sizeof(ea_list) + (1 + have_metric2 + have_tag + have_router_id) * sizeof(eattr));
+       memset(a0.eattrs, 0, sizeof(ea_list));
+
+       nf->old_metric1 = nf->n.metric1;
+       nf->old_metric2 = nf->n.metric2;
+       nf->old_tag = nf->n.tag;
+       nf->old_rid = nf->n.rid;
+
+       a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+         .id = EA_OSPF_METRIC1,
+         .type = EAF_TYPE_INT,
+         .u.data = nf->n.metric1,
        };
 
+       if (have_metric2)
+         a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+           .id = EA_OSPF_METRIC2,
+           .type = EAF_TYPE_INT,
+           .u.data = nf->n.metric2,
+         };
+
+       if (have_tag)
+         a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+           .id = EA_OSPF_TAG,
+           .type = EAF_TYPE_INT,
+           .u.data = nf->n.tag,
+         };
+
+       if (have_router_id)
+         a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
+           .id = EA_OSPF_ROUTER_ID,
+           .type = EAF_TYPE_ROUTER_ID,
+           .u.data = nf->n.rid,
+         };
+
+       rte e0 = { .attrs = rta_lookup(&a0), };
+
        rta_free(nf->old_rta);
        nf->old_rta = rta_clone(e0.attrs);
 
-       if (nf->n.type == RTS_OSPF_EXT2)
-         e0.pflags |= EA_ID_FLAG(EA_OSPF_METRIC2);
-
-       /* Perhaps onfly if tag is non-zero? */
-       if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
-         e0.pflags |= EA_ID_FLAG(EA_OSPF_TAG);
-
        DBG("Mod rte type %d - %N via %I on iface %s, met %d\n",
            a0.source, nf->fn.addr, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);