]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
RIP: Convert the rte-local attributes to extended attributes
authorMaria Matejka <mq@ucw.cz>
Tue, 11 Feb 2020 12:25:57 +0000 (13:25 +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/rip/rip.c
proto/rip/rip.h

index 1809f7ccf34c0893f731d905c88e939452e284aa..a7a2782f79e237a69f12ec6878612911ceb9878e 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_RIP
-    struct {
-      struct iface *from;              /* Incoming iface */
-      u8 metric;                       /* RIP metric */
-      u16 tag;                         /* External route tag */
-    } rip;
-#endif
 #ifdef CONFIG_OSPF
     struct {
       u32 metric1, metric2;            /* OSPF Type 1 and Type 2 metrics */
index 94e3af304a8c4952a03bad07525eb54a7cb9ac02..a35ff93fe5c52c1cbb99434427ebfc4e17fc9ab9 100644 (file)
 #include "lib/string.h"
 #include "lib/alloca.h"
 
+#ifdef CONFIG_RIP
+#include "proto/rip/rip.h"
+#endif
+
 #ifdef CONFIG_BGP
 #include "proto/bgp/bgp.h"
 #endif
@@ -2826,8 +2830,8 @@ rt_get_igp_metric(rte *rt)
 #endif
 
 #ifdef CONFIG_RIP
-  if (a->source == RTS_RIP)
-    return rt->u.rip.metric;
+  if (ea = ea_find(rt->attrs->eattrs, EA_RIP_METRIC))
+    return ea->u.data;
 #endif
 
 #ifdef CONFIG_BGP
index 9befbbd12f897a47c43c1bbe3c1c913f753bc6fb..f56fb6c4dff8f81ed1bbd394cf459b2069310cf3 100644 (file)
@@ -188,14 +188,27 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
       a0.nh.iface = rt->from->ifa->iface;
     }
 
+    a0.eattrs = alloca(sizeof(ea_list) + 3*sizeof(eattr));
+    memset(a0.eattrs, 0, sizeof(ea_list)); /* Zero-ing only the ea_list header */
+    a0.eattrs->count = 3;
+    a0.eattrs->attrs[0] = (eattr) {
+      .id = EA_RIP_METRIC,
+      .type = EAF_TYPE_INT,
+      .u.data = rt_metric,
+    };
+    a0.eattrs->attrs[1] = (eattr) {
+      .id = EA_RIP_TAG,
+      .type = EAF_TYPE_INT,
+      .u.data = rt_tag,
+    };
+    a0.eattrs->attrs[2] = (eattr) {
+      .id = EA_RIP_FROM,
+      .type = EAF_TYPE_PTR,
+      .u.data = (uintptr_t) a0.nh.iface,
+    };
+
     rte e0 = {
       .attrs = &a0,
-      .u.rip = {
-       .from = a0.nh.iface,
-       .metric = rt_metric,
-       .tag = rt_tag,
-      },
-      .pflags = EA_ID_FLAG(EA_RIP_METRIC) | EA_ID_FLAG(EA_RIP_TAG)
     };
 
     rte_update(p->p.main_channel, en->n.addr, &e0);
@@ -306,8 +319,9 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
   if (new)
   {
     /* Update */
-    u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1);
     u32 rt_tag = ea_get_int(new->attrs->eattrs, EA_RIP_TAG, 0);
+    u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1);
+    struct iface *rt_from = (struct iface *) ea_get_int(new->attrs->eattrs, EA_RIP_FROM, 0);
 
     if (rt_metric > p->infinity)
     {
@@ -338,7 +352,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
     en->valid = RIP_ENTRY_VALID;
     en->metric = rt_metric;
     en->tag = rt_tag;
-    en->from = (new->attrs->src->proto == P) ? new->u.rip.from : NULL;
+    en->from = rt_from;
     en->iface = new->attrs->nh.iface;
     en->next_hop = new->attrs->nh.gw;
   }
@@ -1053,37 +1067,15 @@ rip_reload_routes(struct channel *C)
   rip_kick_timer(p);
 }
 
-static void
-rip_make_tmp_attrs(struct rte *rt, struct linpool *pool)
-{
-  rte_init_tmp_attrs(rt, pool, 2);
-  rte_make_tmp_attr(rt, EA_RIP_METRIC, EAF_TYPE_INT, rt->u.rip.metric);
-  rte_make_tmp_attr(rt, EA_RIP_TAG, EAF_TYPE_INT, rt->u.rip.tag);
-}
-
-static void
-rip_store_tmp_attrs(struct rte *rt, struct linpool *pool)
-{
-  rte_init_tmp_attrs(rt, pool, 2);
-  rt->u.rip.metric = rte_store_tmp_attr(rt, EA_RIP_METRIC);
-  rt->u.rip.tag = rte_store_tmp_attr(rt, EA_RIP_TAG);
-}
-
 static int
 rip_rte_better(struct rte *new, struct rte *old)
 {
-  return new->u.rip.metric < old->u.rip.metric;
-}
+  u32 new_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1);
+  u32 old_metric = ea_get_int(old->attrs->eattrs, EA_RIP_METRIC, 1);
 
-static int
-rip_rte_same(struct rte *new, struct rte *old)
-{
-  return ((new->u.rip.metric == old->u.rip.metric) &&
-         (new->u.rip.tag == old->u.rip.tag) &&
-         (new->u.rip.from == old->u.rip.from));
+  return new_metric < old_metric;
 }
 
-
 static void
 rip_postconfig(struct proto_config *CF)
 {
@@ -1105,10 +1097,7 @@ rip_init(struct proto_config *CF)
   P->rt_notify = rip_rt_notify;
   P->neigh_notify = rip_neigh_notify;
   P->reload_routes = rip_reload_routes;
-  P->make_tmp_attrs = rip_make_tmp_attrs;
-  P->store_tmp_attrs = rip_store_tmp_attrs;
   P->rte_better = rip_rte_better;
-  P->rte_same = rip_rte_same;
 
   return P;
 }
@@ -1183,10 +1172,13 @@ rip_reconfigure(struct proto *P, struct proto_config *CF)
 static void
 rip_get_route_info(rte *rte, byte *buf)
 {
-  buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rte->u.rip.metric);
+  u32 rt_metric = ea_get_int(rte->attrs->eattrs, EA_RIP_METRIC, 1);
+  u32 rt_tag = ea_get_int(rte->attrs->eattrs, EA_RIP_TAG, 0);
+
+  buf += bsprintf(buf, " (%d/%d)", rte->attrs->pref, rt_metric);
 
-  if (rte->u.rip.tag)
-    bsprintf(buf, " [%04x]", rte->u.rip.tag);
+  if (rt_tag)
+    bsprintf(buf, " [%04x]", rt_tag);
 }
 
 static int
@@ -1202,6 +1194,10 @@ rip_get_attr(const eattr *a, byte *buf, int buflen UNUSED)
     bsprintf(buf, "tag: %04x", a->u.data);
     return GA_FULL;
 
+  case EA_RIP_FROM:
+    bsprintf(buf, "from: %s", ((struct iface *) a->u.data)->name);
+    return GA_FULL;
+
   default:
     return GA_UNKNOWN;
   }
index 8d3470007882c3af963f0fe538722fc5a6202e41..f8713c4a76c72890ccb439ef25d84d2acecd83b9 100644 (file)
@@ -197,6 +197,7 @@ struct rip_rte
 
 #define EA_RIP_METRIC          EA_CODE(PROTOCOL_RIP, 0)
 #define EA_RIP_TAG             EA_CODE(PROTOCOL_RIP, 1)
+#define EA_RIP_FROM            EA_CODE(PROTOCOL_RIP, 2)
 
 static inline int rip_is_v2(struct rip_proto *p)
 { return p->rip2; }