]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Babel: Update to integrated branch
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 9 Dec 2016 23:11:26 +0000 (00:11 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 9 Dec 2016 23:44:13 +0000 (00:44 +0100)
configure.in
proto/babel/babel.c
proto/babel/babel.h
proto/babel/config.Y
proto/babel/packets.c

index 32344d1f959d5f5590e97eadbddce50aa904e720..bb779be7501e1e939e1f5460c1081790e0cb1834 100644 (file)
@@ -185,8 +185,7 @@ fi
 
 AC_SUBST(iproutedir)
 
-# all_protocols="$proto_bfd babel bgp ospf pipe radv rip $proto_rpki static"
-all_protocols="$proto_bfd bgp ospf pipe radv rip $proto_rpki static "
+all_protocols="$proto_bfd babel bgp ospf pipe radv rip $proto_rpki static"
 
 all_protocols=`echo $all_protocols | sed 's/ /,/g'`
 
index 38be69090f5c52de9d4efb79da769b6430b794bb..73cb5c3bc78c43d27cc467384d726e64f9305b8d 100644 (file)
@@ -53,8 +53,7 @@ static void babel_dump_route(struct babel_route *r);
 static void babel_select_route(struct babel_entry *e);
 static void babel_send_route_request(struct babel_entry *e, struct babel_neighbor *n);
 static void babel_send_wildcard_request(struct babel_iface *ifa);
-static int  babel_cache_seqno_request(struct babel_proto *p, ip_addr prefix, u8 plen,
-                              u64 router_id, u16 seqno);
+static int  babel_cache_seqno_request(struct babel_proto *p, net_addr *n, u64 router_id, u16 seqno);
 static void babel_trigger_iface_update(struct babel_iface *ifa);
 static void babel_trigger_update(struct babel_proto *p);
 static void babel_send_seqno_request(struct babel_entry *e);
@@ -67,27 +66,25 @@ static inline void babel_iface_kick_timer(struct babel_iface *ifa);
  */
 
 static void
-babel_init_entry(struct fib_node *n)
+babel_init_entry(void *E)
 {
-  struct babel_entry *e = (void *) n;
-  e->proto = NULL;
-  e->selected_in = NULL;
-  e->selected_out = NULL;
+  struct babel_entry *e = E;
+
   e->updated = now;
   init_list(&e->sources);
   init_list(&e->routes);
 }
 
 static inline struct babel_entry *
-babel_find_entry(struct babel_proto *p, ip_addr prefix, u8 plen)
+babel_find_entry(struct babel_proto *p, const net_addr *n)
 {
-  return fib_find(&p->rtable, &prefix, plen);
+  return fib_find(&p->rtable, n);
 }
 
 static struct babel_entry *
-babel_get_entry(struct babel_proto *p, ip_addr prefix, u8 plen)
+babel_get_entry(struct babel_proto *p, const net_addr *n)
 {
-  struct babel_entry *e = fib_get(&p->rtable, &prefix, plen);
+  struct babel_entry *e = fib_get(&p->rtable, n);
   e->proto = p;
   return e;
 }
@@ -180,8 +177,8 @@ babel_flush_route(struct babel_route *r)
 {
   struct babel_proto *p = r->e->proto;
 
-  DBG("Babel: Flush route %I/%d router_id %lR neigh %I\n",
-      r->e->n.prefix, r->e->n.pxlen, r->router_id, r->neigh ? r->neigh->addr : IPA_NONE);
+  DBG("Babel: Flush route %N router_id %lR neigh %I\n",
+      r->e->n.addr, r->router_id, r->neigh ? r->neigh->addr : IPA_NONE);
 
   rem_node(NODE r);
 
@@ -203,8 +200,8 @@ babel_expire_route(struct babel_route *r)
   struct babel_proto *p = r->e->proto;
   struct babel_entry *e = r->e;
 
-  TRACE(D_EVENTS, "Route expiry timer for %I/%d router-id %lR fired",
-       e->n.prefix, e->n.pxlen, r->router_id);
+  TRACE(D_EVENTS, "Route expiry timer for %N router-id %lR fired",
+       e->n.addr, r->router_id);
 
   if (r->metric < BABEL_INFINITY)
   {
@@ -229,16 +226,14 @@ babel_refresh_route(struct babel_route *r)
 static void
 babel_expire_routes(struct babel_proto *p)
 {
-  struct babel_entry *e;
   struct babel_route *r, *rx;
   struct fib_iterator fit;
 
   FIB_ITERATE_INIT(&fit, &p->rtable);
 
 loop:
-  FIB_ITERATE_START(&p->rtable, &fit, n)
+  FIB_ITERATE_START(&p->rtable, &fit, struct babel_entry, e)
   {
-    e = (struct babel_entry *) n;
     int changed = 0;
 
     WALK_LIST_DELSAFE(r, rx, e->routes)
@@ -261,7 +256,7 @@ loop:
        * babel_rt_notify() -> p->rtable change, invalidating hidden variables.
        */
 
-      FIB_ITERATE_PUT(&fit, n);
+      FIB_ITERATE_PUT(&fit);
       babel_select_route(e);
       goto loop;
     }
@@ -271,12 +266,12 @@ loop:
     /* Remove empty entries */
     if (EMPTY_LIST(e->sources) && EMPTY_LIST(e->routes))
     {
-      FIB_ITERATE_PUT(&fit, n);
+      FIB_ITERATE_PUT(&fit);
       fib_delete(&p->rtable, e);
       goto loop;
     }
   }
-  FIB_ITERATE_END(n);
+  FIB_ITERATE_END;
 }
 
 static struct babel_neighbor *
@@ -476,8 +471,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
 
   if (r)
   {
-    net *n = net_get(p->p.table, e->n.prefix, e->n.pxlen);
-    rta A = {
+    rta a0 = {
       .src = p->p.main_source,
       .source = RTS_BABEL,
       .scope = SCOPE_UNIVERSE,
@@ -489,22 +483,20 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
     };
 
     if (r->metric < BABEL_INFINITY)
-      A.gw = r->next_hop;
+      a0.gw = r->next_hop;
 
-    rta *a = rta_lookup(&A);
+    rta *a = rta_lookup(&a0);
     rte *rte = rte_get_temp(a);
     rte->u.babel.metric = r->metric;
     rte->u.babel.router_id = r->router_id;
-    rte->net = n;
     rte->pflags = 0;
 
-    rte_update(&p->p, n, rte);
+    rte_update(&p->p, e->n.addr, rte);
   }
   else
   {
     /* Retraction */
-    net *n = net_find(p->p.table, e->n.prefix, e->n.pxlen);
-    rte_update(&p->p, n, NULL);
+    rte_update(&p->p, e->n.addr, NULL);
   }
 }
 
@@ -541,8 +533,8 @@ babel_select_route(struct babel_entry *e)
       ((!e->selected_in && cur->metric < BABEL_INFINITY) ||
        (e->selected_in && cur->metric < e->selected_in->metric)))
   {
-    TRACE(D_EVENTS, "Picked new route for prefix %I/%d: router id %lR metric %d",
-         e->n.prefix, e->n.pxlen, cur->router_id, cur->metric);
+    TRACE(D_EVENTS, "Picked new route for prefix %N: router id %lR metric %d",
+         e->n.addr, cur->router_id, cur->metric);
 
     e->selected_in = cur;
     e->updated = now;
@@ -557,8 +549,8 @@ babel_select_route(struct babel_entry *e)
        babel_build_rte() will set the unreachable flag if the metric is BABEL_INFINITY.*/
     if (e->selected_in)
     {
-      TRACE(D_EVENTS, "Lost feasible route for prefix %I/%d",
-           e->n.prefix, e->n.pxlen);
+      TRACE(D_EVENTS, "Lost feasible route for prefix %N",
+           e->n.addr);
 
       e->selected_in->metric = BABEL_INFINITY;
       e->updated = now;
@@ -576,7 +568,7 @@ babel_select_route(struct babel_entry *e)
       /* No route currently selected, and no new one selected; this means we
         don't have a route to this destination anymore (and were probably
         called from an expiry timer). Remove the route from the nest. */
-      TRACE(D_EVENTS, "Flushing route for prefix %I/%d", e->n.prefix, e->n.pxlen);
+      TRACE(D_EVENTS, "Flushing route for prefix %N", e->n.addr);
 
       e->selected_in = NULL;
       e->updated = now;
@@ -663,12 +655,11 @@ babel_send_route_request(struct babel_entry *e, struct babel_neighbor *n)
   struct babel_iface *ifa = n->ifa;
   union babel_msg msg = {};
 
-  TRACE(D_PACKETS, "Sending route request for %I/%d to %I",
-        e->n.prefix, e->n.pxlen, n->addr);
+  TRACE(D_PACKETS, "Sending route request for %N to %I",
+        e->n.addr, n->addr);
 
   msg.type = BABEL_TLV_ROUTE_REQUEST;
-  msg.route_request.prefix = e->n.prefix;
-  msg.route_request.plen = e->n.pxlen;
+  net_copy(&msg.route_request.net, e->n.addr);
 
   babel_send_unicast(&msg, ifa, n->addr);
 }
@@ -698,18 +689,17 @@ babel_send_seqno_request(struct babel_entry *e)
   union babel_msg msg = {};
 
   s = babel_find_source(e, r->router_id);
-  if (!s || !babel_cache_seqno_request(p, e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1))
+  if (!s || !babel_cache_seqno_request(p, e->n.addr, r->router_id, s->seqno + 1))
     return;
 
-  TRACE(D_PACKETS, "Sending seqno request for %I/%d router-id %lR seqno %d",
-       e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1);
+  TRACE(D_PACKETS, "Sending seqno request for %N router-id %lR seqno %d",
+       e->n.addr, r->router_id, s->seqno + 1);
 
   msg.type = BABEL_TLV_SEQNO_REQUEST;
-  msg.seqno_request.plen = e->n.pxlen;
-  msg.seqno_request.seqno = s->seqno + 1;
   msg.seqno_request.hop_count = BABEL_INITIAL_HOP_COUNT;
+  msg.seqno_request.seqno = s->seqno + 1;
   msg.seqno_request.router_id = r->router_id;
-  msg.seqno_request.prefix = e->n.prefix;
+  net_copy(&msg.seqno_request.net, e->n.addr);
 
   WALK_LIST(ifa, p->interfaces)
     babel_enqueue(&msg, ifa);
@@ -725,18 +715,17 @@ babel_unicast_seqno_request(struct babel_route *r)
   union babel_msg msg = {};
 
   s = babel_find_source(e, r->router_id);
-  if (!s || !babel_cache_seqno_request(p, e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1))
+  if (!s || !babel_cache_seqno_request(p, e->n.addr, r->router_id, s->seqno + 1))
     return;
 
-  TRACE(D_PACKETS, "Sending seqno request for %I/%d router-id %lR seqno %d",
-       e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1);
+  TRACE(D_PACKETS, "Sending seqno request for %N router-id %lR seqno %d",
+       e->n.addr, r->router_id, s->seqno + 1);
 
   msg.type = BABEL_TLV_SEQNO_REQUEST;
-  msg.seqno_request.plen = e->n.pxlen;
-  msg.seqno_request.seqno = s->seqno + 1;
   msg.seqno_request.hop_count = BABEL_INITIAL_HOP_COUNT;
+  msg.seqno_request.seqno = s->seqno + 1;
   msg.seqno_request.router_id = r->router_id;
-  msg.seqno_request.prefix = e->n.prefix;
+  net_copy(&msg.seqno_request.net, e->n.addr);
 
   babel_send_unicast(&msg, ifa, r->neigh->addr);
 }
@@ -756,9 +745,8 @@ babel_send_update(struct babel_iface *ifa, bird_clock_t changed)
 {
   struct babel_proto *p = ifa->proto;
 
-  FIB_WALK(&p->rtable, n)
+  FIB_WALK(&p->rtable, struct babel_entry, e)
   {
-    struct babel_entry *e = (void *) n;
     struct babel_route *r = e->selected_out;
 
     if (!r)
@@ -776,17 +764,16 @@ babel_send_update(struct babel_iface *ifa, bird_clock_t changed)
     if (e->updated < changed)
       continue;
 
-    TRACE(D_PACKETS, "Sending update for %I/%d router-id %lR seqno %d metric %d",
-         e->n.prefix, e->n.pxlen, r->router_id, r->seqno, r->metric);
+    TRACE(D_PACKETS, "Sending update for %N router-id %lR seqno %d metric %d",
+         e->n.addr, r->router_id, r->seqno, r->metric);
 
     union babel_msg msg = {};
     msg.type = BABEL_TLV_UPDATE;
-    msg.update.plen = e->n.pxlen;
     msg.update.interval = ifa->cf->update_interval;
     msg.update.seqno = r->seqno;
     msg.update.metric = r->metric;
-    msg.update.prefix = e->n.prefix;
     msg.update.router_id = r->router_id;
+    net_copy(&msg.update.net, e->n.addr);
 
     babel_enqueue(&msg, ifa);
 
@@ -839,20 +826,18 @@ babel_trigger_update(struct babel_proto *p)
 
 /* A retraction is an update with an infinite metric */
 static void
-babel_send_retraction(struct babel_iface *ifa, ip_addr prefix, int plen)
+babel_send_retraction(struct babel_iface *ifa, net_addr *n)
 {
   struct babel_proto *p = ifa->proto;
   union babel_msg msg = {};
 
-  TRACE(D_PACKETS, "Sending retraction for %I/%d seqno %d",
-       prefix, plen, p->update_seqno);
+  TRACE(D_PACKETS, "Sending retraction for %N seqno %d", n, p->update_seqno);
 
   msg.type = BABEL_TLV_UPDATE;
-  msg.update.plen = plen;
   msg.update.interval = ifa->cf->update_interval;
   msg.update.seqno = p->update_seqno;
   msg.update.metric = BABEL_INFINITY;
-  msg.update.prefix = prefix;
+  msg.update.net = *n;
 
   babel_enqueue(&msg, ifa);
 }
@@ -941,22 +926,20 @@ babel_expire_seqno_requests(struct babel_proto *p)
  * found. Otherwise, a new entry is stored in the cache.
  */
 static int
-babel_cache_seqno_request(struct babel_proto *p, ip_addr prefix, u8 plen,
+babel_cache_seqno_request(struct babel_proto *p, net_addr *n,
                           u64 router_id, u16 seqno)
 {
   struct babel_seqno_request *r;
 
   WALK_LIST(r, p->seqno_cache)
   {
-    if (ipa_equal(r->prefix, prefix) && (r->plen == plen) &&
-       (r->router_id == router_id) && (r->seqno == seqno))
+    if (net_equal(&r->net, n) && (r->router_id == router_id) && (r->seqno == seqno))
       return 0;
   }
 
   /* no entries found */
   r = sl_alloc(p->seqno_slab);
-  r->prefix = prefix;
-  r->plen = plen;
+  net_copy(&r->net, n);
   r->router_id = router_id;
   r->seqno = seqno;
   r->updated = now;
@@ -973,8 +956,8 @@ babel_forward_seqno_request(struct babel_entry *e,
   struct babel_proto *p = e->proto;
   struct babel_route *r;
 
-  TRACE(D_PACKETS, "Forwarding seqno request for %I/%d router-id %lR seqno %d",
-       e->n.prefix, e->n.pxlen, in->router_id, in->seqno);
+  TRACE(D_PACKETS, "Forwarding seqno request for %N router-id %lR seqno %d",
+       e->n.addr, in->router_id, in->seqno);
 
   WALK_LIST(r, e->routes)
   {
@@ -982,16 +965,15 @@ babel_forward_seqno_request(struct babel_entry *e,
        !OUR_ROUTE(r) &&
        !ipa_equal(r->neigh->addr, sender))
     {
-      if (!babel_cache_seqno_request(p, e->n.prefix, e->n.pxlen, in->router_id, in->seqno))
+      if (!babel_cache_seqno_request(p, e->n.addr, in->router_id, in->seqno))
        return;
 
       union babel_msg msg = {};
       msg.type = BABEL_TLV_SEQNO_REQUEST;
-      msg.seqno_request.plen = in->plen;
-      msg.seqno_request.seqno = in->seqno;
       msg.seqno_request.hop_count = in->hop_count-1;
+      msg.seqno_request.seqno = in->seqno;
       msg.seqno_request.router_id = in->router_id;
-      msg.seqno_request.prefix = e->n.prefix;
+      net_copy(&msg.seqno_request.net, e->n.addr);
 
       babel_send_unicast(&msg, r->neigh->ifa, r->neigh->addr);
       return;
@@ -1073,8 +1055,11 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa)
   node *n;
   int feasible;
 
-  TRACE(D_PACKETS, "Handling update for %I/%d with seqno %d metric %d",
-       msg->prefix, msg->plen, msg->seqno, msg->metric);
+  if (msg->wildcard)
+    TRACE(D_PACKETS, "Handling wildcard retraction", msg->seqno);
+  else
+    TRACE(D_PACKETS, "Handling update for %N with seqno %d metric %d",
+         &msg->net, msg->seqno, msg->metric);
 
   nbr = babel_find_neighbor(ifa, msg->sender);
   if (!nbr)
@@ -1140,7 +1125,7 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa)
     }
     else
     {
-      e = babel_find_entry(p, msg->prefix, msg->plen);
+      e = babel_find_entry(p, &msg->net);
 
       if (!e)
        return;
@@ -1159,7 +1144,7 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa)
     return;
   }
 
-  e = babel_get_entry(p, msg->prefix, msg->plen);
+  e = babel_get_entry(p, &msg->net);
   r = babel_find_route(e, nbr); /* the route entry indexed by neighbour */
   s = babel_find_source(e, msg->router_id); /* for feasibility */
   feasible = babel_is_feasible(s, msg->seqno, msg->metric);
@@ -1231,14 +1216,14 @@ babel_handle_route_request(union babel_msg *m, struct babel_iface *ifa)
     return;
   }
 
-  TRACE(D_PACKETS, "Handling route request for %I/%d", msg->prefix, msg->plen);
+  TRACE(D_PACKETS, "Handling route request for %N", &msg->net);
 
   /* Non-wildcard request - see if we have an entry for the route.
      If not, send a retraction, otherwise send an update. */
-  struct babel_entry *e = babel_find_entry(p, msg->prefix, msg->plen);
+  struct babel_entry *e = babel_find_entry(p, &msg->net);
   if (!e)
   {
-    babel_send_retraction(ifa, msg->prefix, msg->plen);
+    babel_send_retraction(ifa, &msg->net);
   }
   else
   {
@@ -1256,11 +1241,11 @@ babel_handle_seqno_request(union babel_msg *m, struct babel_iface *ifa)
 
   /* RFC 6126 3.8.1.2 */
 
-  TRACE(D_PACKETS, "Handling seqno request for %I/%d router-id %lR seqno %d hop count %d",
-       msg->prefix, msg->plen, msg->router_id, msg->seqno, msg->hop_count);
+  TRACE(D_PACKETS, "Handling seqno request for %N router-id %lR seqno %d hop count %d",
+       &msg->net, msg->router_id, msg->seqno, msg->hop_count);
 
   /* Ignore if we have no such entry or entry has infinite metric */
-  struct babel_entry *e = babel_find_entry(p, msg->prefix, msg->plen);
+  struct babel_entry *e = babel_find_entry(p, &msg->net);
   if (!e || !e->selected_out || (e->selected_out->metric == BABEL_INFINITY))
     return;
 
@@ -1668,7 +1653,7 @@ babel_dump_entry(struct babel_entry *e)
   struct babel_source *s;
   struct babel_route *r;
 
-  debug("Babel: Entry %I/%d:\n", e->n.prefix, e->n.pxlen);
+  debug("Babel: Entry %N:\n", e->n.addr);
 
   WALK_LIST(s,e->sources)
   { debug(" "); babel_dump_source(s); }
@@ -1715,9 +1700,9 @@ babel_dump(struct proto *P)
   WALK_LIST(ifa, p->interfaces)
     babel_dump_iface(ifa);
 
-  FIB_WALK(&p->rtable, n)
+  FIB_WALK(&p->rtable, struct babel_entry, e)
   {
-    babel_dump_entry((struct babel_entry *) n);
+    babel_dump_entry(e);
   }
   FIB_WALK_END;
 }
@@ -1828,11 +1813,9 @@ void
 babel_show_entries(struct proto *P)
 {
   struct babel_proto *p = (void *) P;
-  struct babel_entry *e = NULL;
   struct babel_source *s = NULL;
   struct babel_route *r = NULL;
 
-  char ipbuf[STD_ADDRESS_P_LENGTH+5];
   char ridbuf[ROUTER_ID_64_LENGTH+1];
 
   if (p->p.proto_state != PS_UP)
@@ -1846,17 +1829,14 @@ babel_show_entries(struct proto *P)
   cli_msg(-1025, "%-29s %-23s %6s %5s %7s %7s",
          "Prefix", "Router ID", "Metric", "Seqno", "Expires", "Sources");
 
-  FIB_WALK(&p->rtable, n)
+  FIB_WALK(&p->rtable, struct babel_entry, e)
   {
-    e = (struct babel_entry *) n;
     r = e->selected_in ? e->selected_in : e->selected_out;
 
     int srcs = 0;
     WALK_LIST(s, e->sources)
       srcs++;
 
-    bsprintf(ipbuf, "%I/%u", e->n.prefix, e->n.pxlen);
-
     if (r)
     {
       if (r->router_id == p->router_id)
@@ -1865,12 +1845,12 @@ babel_show_entries(struct proto *P)
         bsprintf(ridbuf, "%lR", r->router_id);
 
       int time = r->expires ? r->expires - now : 0;
-      cli_msg(-1025, "%-29s %-23s %6u %5u %7u %7u",
-             ipbuf, ridbuf, r->metric, r->seqno, MAX(time, 0), srcs);
+      cli_msg(-1025, "%-29N %-23s %6u %5u %7u %7u",
+             e->n.addr, ridbuf, r->metric, r->seqno, MAX(time, 0), srcs);
     }
     else
     {
-      cli_msg(-1025, "%-29s %-44s %7u", ipbuf, "<pending>", srcs);
+      cli_msg(-1025, "%-29N %-44s %7u", e->n.addr, "<pending>", srcs);
     }
   }
   FIB_WALK_END;
@@ -1964,7 +1944,7 @@ babel_store_tmp_attrs(struct rte *rt, struct ea_list *attrs)
  * so store it into our data structures.
  */
 static void
-babel_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net,
+babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
                struct rte *new, struct rte *old UNUSED, struct ea_list *attrs UNUSED)
 {
   struct babel_proto *p = (void *) P;
@@ -1974,7 +1954,7 @@ babel_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *ne
   if (new)
   {
     /* Update */
-    e = babel_get_entry(p, net->n.prefix, net->n.pxlen);
+    e = babel_get_entry(p, net->n.addr);
 
     if (new->attrs->src->proto != P)
     {
@@ -1996,7 +1976,7 @@ babel_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *ne
   else
   {
     /* Withdraw */
-    e = babel_find_entry(p, net->n.prefix, net->n.pxlen);
+    e = babel_find_entry(p, net->n.addr);
     if (!e || !e->selected_out)
       return;
 
@@ -2046,11 +2026,12 @@ babel_rte_same(struct rte *new, struct rte *old)
 
 
 static struct proto *
-babel_init(struct proto_config *cfg)
+babel_init(struct proto_config *CF)
 {
-  struct proto *P = proto_new(cfg, sizeof(struct babel_proto));
+  struct proto *P = proto_new(CF);
+
+  P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
 
-  P->accept_ra_types = RA_OPTIMAL;
   P->if_notify = babel_if_notify;
   P->rt_notify = babel_rt_notify;
   P->import_control = babel_import_control;
@@ -2068,7 +2049,8 @@ babel_start(struct proto *P)
   struct babel_proto *p = (void *) P;
   struct babel_config *cf = (void *) P->cf;
 
-  fib_init(&p->rtable, P->pool, sizeof(struct babel_entry), 0, babel_init_entry);
+  fib_init(&p->rtable, P->pool, NET_IP6, sizeof(struct babel_entry),
+          OFFSETOF(struct babel_entry, n), 0, babel_init_entry);
   init_list(&p->interfaces);
   p->timer = tm_new_set(P->pool, babel_timer, p, 0, 1);
   tm_start(p->timer, 2);
@@ -2111,14 +2093,17 @@ babel_shutdown(struct proto *P)
 }
 
 static int
-babel_reconfigure(struct proto *P, struct proto_config *c)
+babel_reconfigure(struct proto *P, struct proto_config *CF)
 {
   struct babel_proto *p = (void *) P;
-  struct babel_config *new = (void *) c;
+  struct babel_config *new = (void *) CF;
 
   TRACE(D_EVENTS, "Reconfiguring");
 
-  p->p.cf = c;
+  if (!proto_configure_channel(P, &P->main_channel, proto_cf_main_channel(CF)))
+    return 0;
+
+  p->p.cf = CF;
   babel_reconfigure_ifaces(p, new);
 
   babel_trigger_update(p);
@@ -2133,6 +2118,8 @@ struct protocol proto_babel = {
   .template =          "babel%d",
   .attr_class =                EAP_BABEL,
   .preference =                DEF_PREF_BABEL,
+  .channel_mask =      NB_IP6,
+  .proto_size =                sizeof(struct babel_proto),
   .config_size =       sizeof(struct babel_config),
   .init =              babel_init,
   .dump =              babel_dump,
index e8b6c3149d42e703ab1b27f1f88cdf75f62db65b..792c9d60140b3a5fac7e303f872a974c1f7fc33c 100644 (file)
@@ -52,7 +52,7 @@
 /* Max interval that will not overflow when carried as 16-bit centiseconds */
 #define BABEL_MAX_INTERVAL             (0xFFFF/BABEL_TIME_UNITS)
 
-#define BABEL_OVERHEAD         (SIZE_OF_IP_HEADER+UDP_HEADER_LENGTH)
+#define BABEL_OVERHEAD         (IP6_HEADER_LENGTH+UDP_HEADER_LENGTH)
 #define BABEL_MIN_MTU          (512 + BABEL_OVERHEAD)
 
 
@@ -208,7 +208,6 @@ struct babel_route {
 };
 
 struct babel_entry {
-  struct fib_node n;
   struct babel_proto *proto;
   struct babel_route *selected_in;
   struct babel_route *selected_out;
@@ -217,13 +216,14 @@ struct babel_entry {
 
   list sources;                                /* Source entries for this prefix (struct babel_source). */
   list routes;                         /* Routes for this prefix (struct babel_route) */
+
+  struct fib_node n;
 };
 
 /* Stores forwarded seqno requests for duplicate suppression. */
 struct babel_seqno_request {
   node n;
-  ip_addr prefix;
-  u8  plen;
+  net_addr net;
   u64 router_id;
   u16 seqno;
   bird_clock_t updated;
@@ -265,12 +265,11 @@ struct babel_msg_ihu {
 struct babel_msg_update {
   u8 type;
   u8 wildcard;
-  u8 plen;
   u16 interval;
   u16 seqno;
   u16 metric;
-  ip_addr prefix;
   u64 router_id;
+  net_addr net;
   ip_addr next_hop;
   ip_addr sender;
 };
@@ -278,17 +277,15 @@ struct babel_msg_update {
 struct babel_msg_route_request {
   u8 type;
   u8 full;
-  u8 plen;
-  ip_addr prefix;
+  net_addr net;
 };
 
 struct babel_msg_seqno_request {
   u8 type;
-  u8 plen;
-  u16 seqno;
   u8 hop_count;
+  u16 seqno;
   u64 router_id;
-  ip_addr prefix;
+  net_addr net;
   ip_addr sender;
 };
 
index b6170852a14fe6fcf1fbb8eff5eb8e35556c9aa4..cf8983fa43bbe3b90288f16376bdc6d873e1d4d2 100644 (file)
@@ -30,11 +30,13 @@ CF_ADDTO(proto, babel_proto)
 babel_proto_start: proto_start BABEL
 {
   this_proto = proto_config_new(&proto_babel, $1);
+  this_proto->net_type = NET_IP6;
   init_list(&BABEL_CFG->iface_list);
 };
 
 babel_proto_item:
    proto_item
+ | proto_channel
  | INTERFACE babel_iface
  ;
 
index 08054832839d4444fcc3d157426fd368ab03fcd9..70cfc1961b22bff88b5ad6bf92e33a8ec262ac11 100644 (file)
@@ -146,7 +146,8 @@ struct babel_write_state {
 #define TLV_HDR(tlv,t,l) ({ tlv->type = t; tlv->length = l - sizeof(struct babel_tlv); })
 #define TLV_HDR0(tlv,t) TLV_HDR(tlv, t, tlv_data[t].min_length)
 
-#define BYTES(n) ((((uint) n) + 7) / 8)
+#define NET_SIZE(n) BYTES(net_pxlen(n))
+
 
 static inline u16
 get_time16(const void *p)
@@ -161,19 +162,19 @@ put_time16(void *p, u16 v)
   put_u16(p, v * BABEL_TIME_UNITS);
 }
 
-static inline ip6_addr
-get_ip6_px(const void *p, uint plen)
+static inline void
+read_ip6_px(net_addr *n, const void *p, uint plen)
 {
   ip6_addr addr = IPA_NONE;
   memcpy(&addr, p, BYTES(plen));
-  return ip6_ntoh(addr);
+  net_fill_ip6(n, ip6_ntoh(addr), plen);
 }
 
 static inline void
-put_ip6_px(void *p, ip6_addr addr, uint plen)
+put_ip6_px(void *p, net_addr *n)
 {
-  addr = ip6_hton(addr);
-  memcpy(p, &addr, BYTES(plen));
+  ip6_addr addr = ip6_hton(net6_prefix(n));
+  memcpy(p, &addr, NET_SIZE(n));
 }
 
 static inline ip6_addr
@@ -480,6 +481,9 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
     if (tlv->plen > 0)
       return PARSE_ERROR;
 
+    if (msg->metric != 65535)
+      return PARSE_ERROR;
+
     msg->wildcard = 1;
     break;
 
@@ -488,7 +492,7 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
     return PARSE_IGNORE;
 
   case BABEL_AE_IP6:
-    if (tlv->plen > MAX_PREFIX_LENGTH)
+    if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
       return PARSE_ERROR;
 
     /* Cannot omit data if there is no saved prefix */
@@ -499,18 +503,18 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
     memcpy(buf, state->def_ip6_prefix, tlv->omitted);
     memcpy(buf + tlv->omitted, tlv->addr, len);
 
-    msg->plen = tlv->plen;
-    msg->prefix = ipa_from_ip6(get_ip6(buf));
+    ip6_addr prefix = get_ip6(buf);
+    net_fill_ip6(&msg->net, prefix, tlv->plen);
 
     if (tlv->flags & BABEL_FLAG_DEF_PREFIX)
     {
-      put_ip6(state->def_ip6_prefix, msg->prefix);
+      put_ip6(state->def_ip6_prefix, prefix);
       state->def_ip6_prefix_seen = 1;
     }
 
     if (tlv->flags & BABEL_FLAG_ROUTER_ID)
     {
-      state->router_id = ((u64) _I2(msg->prefix)) << 32 | _I3(msg->prefix);
+      state->router_id = ((u64) _I2(prefix)) << 32 | _I3(prefix);
       state->router_id_seen = 1;
     }
     break;
@@ -559,7 +563,7 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
     tlv = (struct babel_tlv_update *) NEXT_TLV(tlv);
   }
 
-  uint len = sizeof(struct babel_tlv_update) + BYTES(msg->plen);
+  uint len = sizeof(struct babel_tlv_update) + NET_SIZE(&msg->net);
 
   if (len0 + len > max_len)
     return 0;
@@ -575,8 +579,8 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
   else
   {
     tlv->ae = BABEL_AE_IP6;
-    tlv->plen = msg->plen;
-    put_ip6_px(tlv->addr, msg->prefix, msg->plen);
+    tlv->plen = net6_pxlen(&msg->net);
+    put_ip6_px(tlv->addr, &msg->net);
   }
 
   put_time16(&tlv->interval, msg->interval);
@@ -610,14 +614,13 @@ babel_read_route_request(struct babel_tlv *hdr, union babel_msg *m,
     return PARSE_IGNORE;
 
   case BABEL_AE_IP6:
-    if (tlv->plen > MAX_PREFIX_LENGTH)
+    if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
       return PARSE_ERROR;
 
     if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
       return PARSE_ERROR;
 
-    msg->plen = tlv->plen;
-    msg->prefix = get_ip6_px(tlv->addr, tlv->plen);
+    read_ip6_px(&msg->net, tlv->addr, tlv->plen);
     return PARSE_SUCCESS;
 
   case BABEL_AE_IP6_LL:
@@ -637,7 +640,7 @@ babel_write_route_request(struct babel_tlv *hdr, union babel_msg *m,
   struct babel_tlv_route_request *tlv = (void *) hdr;
   struct babel_msg_route_request *msg = &m->route_request;
 
-  uint len = sizeof(struct babel_tlv_route_request) + BYTES(msg->plen);
+  uint len = sizeof(struct babel_tlv_route_request) + NET_SIZE(&msg->net);
 
   if (len > max_len)
     return 0;
@@ -652,8 +655,8 @@ babel_write_route_request(struct babel_tlv *hdr, union babel_msg *m,
   else
   {
     tlv->ae = BABEL_AE_IP6;
-    tlv->plen = msg->plen;
-    put_ip6_px(tlv->addr, msg->prefix, msg->plen);
+    tlv->plen = net6_pxlen(&msg->net);
+    put_ip6_px(tlv->addr, &msg->net);
   }
 
   return len;
@@ -685,14 +688,13 @@ babel_read_seqno_request(struct babel_tlv *hdr, union babel_msg *m,
     return PARSE_IGNORE;
 
   case BABEL_AE_IP6:
-    if (tlv->plen > MAX_PREFIX_LENGTH)
+    if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
       return PARSE_ERROR;
 
     if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
       return PARSE_ERROR;
 
-    msg->plen = tlv->plen;
-    msg->prefix = get_ip6_px(tlv->addr, tlv->plen);
+    read_ip6_px(&msg->net, tlv->addr, tlv->plen);
     return PARSE_SUCCESS;
 
   case BABEL_AE_IP6_LL:
@@ -712,18 +714,18 @@ babel_write_seqno_request(struct babel_tlv *hdr, union babel_msg *m,
   struct babel_tlv_seqno_request *tlv = (void *) hdr;
   struct babel_msg_seqno_request *msg = &m->seqno_request;
 
-  uint len = sizeof(struct babel_tlv_seqno_request) + BYTES(msg->plen);
+  uint len = sizeof(struct babel_tlv_seqno_request) + NET_SIZE(&msg->net);
 
   if (len > max_len)
     return 0;
 
   TLV_HDR(tlv, BABEL_TLV_SEQNO_REQUEST, len);
   tlv->ae = BABEL_AE_IP6;
-  tlv->plen = msg->plen;
+  tlv->plen = net6_pxlen(&msg->net);
   put_u16(&tlv->seqno, msg->seqno);
   tlv->hop_count = msg->hop_count;
   put_u64(&tlv->router_id, msg->router_id);
-  put_ip6_px(tlv->addr, msg->prefix, msg->plen);
+  put_ip6_px(tlv->addr, &msg->net);
 
   return len;
 }