[PATCH 3/3] babel: Add option to randomise router ID

Toke Høiland-Jørgensen toke at toke.dk
Mon Apr 30 17:15:19 CEST 2018


When a Babel node restarts, it loses its sequence number, which can cause
its routes to be rejected by peers until the state is cleared out by other
nodes in the network (which can take on the order of minutes).

There are two ways to fix this: Having stable storage to keep the sequence
number across restarts, or picking a different router ID each time.

This implements the latter, by introducing a new option that will cause
Bird to pick a random router ID every time it starts up. This avoids the
problem at the cost of not having stable router IDs in the network.

Signed-off-by: Toke Høiland-Jørgensen <toke at toke.dk>
---
 doc/bird.sgml        | 10 ++++++++++
 proto/babel/babel.c  | 14 ++++++++++++++
 proto/babel/babel.h  |  1 +
 proto/babel/config.Y |  3 ++-
 4 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/doc/bird.sgml b/doc/bird.sgml
index 1191fa03..47a6a60a 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -1691,6 +1691,7 @@ supports the following per-interface configuration options:
 protocol babel [<name>] {
 	ipv4 { <channel config> };
 	ipv6 [sadr] { <channel config> };
+        random router id <switch>;
 	interface <interface pattern> {
 		type <wired|wireless>;
 		rxcost <number>;
@@ -1713,6 +1714,15 @@ protocol babel [<name>] {
       <tag><label id="babel-channel">ipv4 | ipv6 [sadr] <m/channel config/</tag>
       The supported channels are IPv4, IPv6, and IPv6 SADR.
 
+      <tag><label id="babel-random-router-id">check link <m/switch/</tag>
+      If enabled, Bird will randomise the top 32 bits of its router ID whenever
+      the protocol instance starts up. If a Babel node restarts, it loses its sequence
+      number, which can cause its routes to be rejected by peers until the state
+      is cleared out by other nodes in the network (which can take on the order
+      of minutes). Enabling this option causes Bird to pick a random router ID
+      every time it starts up, which avoids this problem at the cost of not
+      having stable router IDs in the network.
+
       <tag><label id="babel-type">type wired|wireless </tag>
       This option specifies the interface type: Wired or wireless. On wired
       interfaces a neighbor is considered unreachable after a small number of
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index f7981333..5f1adca3 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -2236,6 +2236,13 @@ babel_init(struct proto_config *CF)
   return P;
 }
 
+static inline void
+babel_randomise_router_id(struct babel_proto *p)
+{
+  p->router_id |= ((u64) random()) << 32;
+  TRACE(D_EVENTS, "Randomised router ID to %lR", p->router_id);
+}
+
 static int
 babel_start(struct proto *P)
 {
@@ -2254,6 +2261,9 @@ babel_start(struct proto *P)
   p->update_seqno = 1;
   p->router_id = proto_get_router_id(&cf->c);
 
+  if (cf->random_router_id)
+    babel_randomise_router_id(p);
+
   p->route_slab = sl_new(P->pool, sizeof(struct babel_route));
   p->source_slab = sl_new(P->pool, sizeof(struct babel_source));
   p->msg_slab = sl_new(P->pool, sizeof(struct babel_msg_node));
@@ -2293,6 +2303,7 @@ babel_reconfigure(struct proto *P, struct proto_config *CF)
 {
   struct babel_proto *p = (void *) P;
   struct babel_config *new = (void *) CF;
+  struct babel_config *old = (void *) p->p.cf;
   u8 ip6_type = new->ip6_channel ? new->ip6_channel->net_type : NET_IP6;
 
   TRACE(D_EVENTS, "Reconfiguring");
@@ -2304,6 +2315,9 @@ babel_reconfigure(struct proto *P, struct proto_config *CF)
       !proto_configure_channel(P, &p->ip6_channel, new->ip6_channel))
     return 0;
 
+  if (new->random_router_id && !old->random_router_id)
+    babel_randomise_router_id(p);
+
   p->p.cf = CF;
   babel_reconfigure_ifaces(p, new);
 
diff --git a/proto/babel/babel.h b/proto/babel/babel.h
index b194ce30..830c18ee 100644
--- a/proto/babel/babel.h
+++ b/proto/babel/babel.h
@@ -112,6 +112,7 @@ struct babel_config {
   struct proto_config c;
   list iface_list;			/* List of iface configs (struct babel_iface_config) */
   uint hold_time;			/* Time to hold stale entries and unreachable routes */
+  u8 random_router_id;
 
   struct channel_config *ip4_channel;
   struct channel_config *ip6_channel;
diff --git a/proto/babel/config.Y b/proto/babel/config.Y
index 7adfb4bb..25a0c2f0 100644
--- a/proto/babel/config.Y
+++ b/proto/babel/config.Y
@@ -25,7 +25,7 @@ CF_DECLS
 CF_KEYWORDS(BABEL, INTERFACE, METRIC, RXCOST, HELLO, UPDATE, INTERVAL, PORT,
 	TYPE, WIRED, WIRELESS, RX, TX, BUFFER, PRIORITY, LENGTH, CHECK, LINK,
 	NEXT, HOP, IPV4, IPV6, BABEL_METRIC, SHOW, INTERFACES, NEIGHBORS,
-	ENTRIES)
+	ENTRIES, RANDOM, ROUTER, ID)
 
 CF_GRAMMAR
 
@@ -42,6 +42,7 @@ babel_proto_item:
    proto_item
  | proto_channel
  | INTERFACE babel_iface
+ | RANDOM ROUTER ID bool { BABEL_CFG->random_router_id = $4; }
  ;
 
 babel_proto_opts:
-- 
2.17.0



More information about the Bird-users mailing list