]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Babel: Send wildcard retractions on shutdown and startup
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 19 Jul 2016 12:23:41 +0000 (14:23 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 19 Jul 2016 12:23:41 +0000 (14:23 +0200)
This makes BIRD send a wildcard retraction on all interfaces before
shutting down and right after starting up. This helps ensure that
neighbours will discard the announced routes as soon as possible,
rather than only after the normal timeout procedures.

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
proto/babel/babel.c
proto/babel/babel.h
proto/babel/packets.c

index 8204838b66e40dd282e99b0db2c84b873212732e..67e1d8befd3bbb61cafefd27c6e4542f98124286 100644 (file)
@@ -834,8 +834,8 @@ babel_send_retraction(struct babel_iface *ifa, ip_addr prefix, int plen)
   struct babel_proto *p = ifa->proto;
   union babel_msg msg = {};
 
-  TRACE(D_PACKETS, "Sending retraction for %I/%d router-id %lR seqno %d",
-       prefix, plen, p->router_id, p->update_seqno);
+  TRACE(D_PACKETS, "Sending retraction for %I/%d seqno %d",
+       prefix, plen, p->update_seqno);
 
   msg.type = BABEL_TLV_UPDATE;
   msg.update.plen = plen;
@@ -843,7 +843,23 @@ babel_send_retraction(struct babel_iface *ifa, ip_addr prefix, int plen)
   msg.update.seqno = p->update_seqno;
   msg.update.metric = BABEL_INFINITY;
   msg.update.prefix = prefix;
-  msg.update.router_id = p->router_id;
+
+  babel_enqueue(&msg, ifa);
+}
+
+static void
+babel_send_wildcard_retraction(struct babel_iface *ifa)
+{
+  struct babel_proto *p = ifa->proto;
+  union babel_msg msg = {};
+
+  TRACE(D_PACKETS, "Sending wildcard retraction on %s", ifa->ifname);
+
+  msg.type = BABEL_TLV_UPDATE;
+  msg.update.wildcard = 1;
+  msg.update.interval = ifa->cf->update_interval;
+  msg.update.seqno = p->update_seqno;
+  msg.update.metric = BABEL_INFINITY;
 
   babel_enqueue(&msg, ifa);
 }
@@ -1099,7 +1115,7 @@ babel_handle_update(union babel_msg *m, struct babel_iface *ifa)
   /* Retraction */
   if (msg->metric == BABEL_INFINITY)
   {
-    if (msg->ae == BABEL_AE_WILDCARD)
+    if (msg->wildcard)
     {
       /*
        * Special case: This is a retraction of all prefixes announced by this
@@ -1347,6 +1363,7 @@ babel_iface_start(struct babel_iface *ifa)
   ifa->up = 1;
 
   babel_send_hello(ifa, 0);
+  babel_send_wildcard_retraction(ifa);
   babel_send_wildcard_request(ifa);
   babel_send_update(ifa, 0);   /* Full update */
 }
@@ -2056,6 +2073,30 @@ babel_start(struct proto *P)
   return PS_UP;
 }
 
+static inline void
+babel_iface_shutdown(struct babel_iface *ifa)
+{
+  if (ifa->sk)
+  {
+    babel_send_wildcard_retraction(ifa);
+    babel_send_queue(ifa);
+  }
+}
+
+static int
+babel_shutdown(struct proto *P)
+{
+  struct babel_proto *p = (void *) P;
+  struct babel_iface *ifa;
+
+  TRACE(D_EVENTS, "Shutdown requested");
+
+  WALK_LIST(ifa, p->interfaces)
+    babel_iface_shutdown(ifa);
+
+  return PS_DOWN;
+}
+
 static int
 babel_reconfigure(struct proto *P, struct proto_config *c)
 {
@@ -2083,6 +2124,7 @@ struct protocol proto_babel = {
   .init =              babel_init,
   .dump =              babel_dump,
   .start =             babel_start,
+  .shutdown =          babel_shutdown,
   .reconfigure =       babel_reconfigure,
   .get_route_info =    babel_get_route_info,
   .get_attr =          babel_get_attr
index 7b5037ab9223244b70954dd41f1660a85e362eed..481c88a7042ba9031c03f2c0f77ddcbf28b27c57 100644 (file)
@@ -268,7 +268,7 @@ struct babel_msg_ihu {
 
 struct babel_msg_update {
   u8 type;
-  u8 ae;
+  u8 wildcard;
   u8 plen;
   u16 interval;
   u16 seqno;
index d0cc613efbb88b18c01241ade16b0dd75a266cd4..65dd685312c83fff35675df376077e56de0a5158 100644 (file)
@@ -462,7 +462,6 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
   struct babel_msg_update *msg = &m->update;
 
   msg->type = BABEL_TLV_UPDATE;
-  msg->ae = tlv->ae;
   msg->interval = get_time16(&tlv->interval);
   msg->seqno = get_u16(&tlv->seqno);
   msg->metric = get_u16(&tlv->metric);
@@ -480,8 +479,7 @@ babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
     if (tlv->plen > 0)
       return PARSE_ERROR;
 
-    msg->plen = 0;
-    msg->prefix = IPA_NONE;
+    msg->wildcard = 1;
     break;
 
   case BABEL_AE_IP4:
@@ -550,8 +548,11 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
    * When needed, we write Router-ID TLV before Update TLV and return size of
    * both of them. There is enough space for the Router-ID TLV, because
    * sizeof(struct babel_tlv_router_id) == sizeof(struct babel_tlv_update).
+   *
+   * Router ID is not used for retractions, so do not us it in such case.
    */
-  if (!state->router_id_seen || (msg->router_id != state->router_id))
+  if ((msg->metric < BABEL_INFINITY) &&
+      (!state->router_id_seen || (msg->router_id != state->router_id)))
   {
     len0 = babel_write_router_id(hdr, msg->router_id, state, max_len);
     tlv = (struct babel_tlv_update *) NEXT_TLV(tlv);
@@ -564,12 +565,22 @@ babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
 
   memset(tlv, 0, sizeof(struct babel_tlv_update));
   TLV_HDR(tlv, BABEL_TLV_UPDATE, len);
-  tlv->ae = BABEL_AE_IP6;
-  tlv->plen = msg->plen;
+
+  if (msg->wildcard)
+  {
+    tlv->ae = BABEL_AE_WILDCARD;
+    tlv->plen = 0;
+  }
+  else
+  {
+    tlv->ae = BABEL_AE_IP6;
+    tlv->plen = msg->plen;
+    put_ip6_px(tlv->addr, msg->prefix, msg->plen);
+  }
+
   put_time16(&tlv->interval, msg->interval);
   put_u16(&tlv->seqno, msg->seqno);
   put_u16(&tlv->metric, msg->metric);
-  put_ip6_px(tlv->addr, msg->prefix, msg->plen);
 
   return len0 + len;
 }