diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 8204838b..67e1d8be 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -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
diff --git a/proto/babel/babel.h b/proto/babel/babel.h
index 7b5037ab..481c88a7 100644
--- a/proto/babel/babel.h
+++ b/proto/babel/babel.h
@@ -268,7 +268,7 @@ struct babel_msg_ihu {
 
 struct babel_msg_update {
   u8 type;
-  u8 ae;
+  u8 wildcard;
   u8 plen;
   u16 interval;
   u16 seqno;
diff --git a/proto/babel/packets.c b/proto/babel/packets.c
index d0cc613e..65dd6853 100644
--- a/proto/babel/packets.c
+++ b/proto/babel/packets.c
@@ -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;
 }