]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements handling of BSD iface arrival/departure notifications.
authorOndrej Zajicek <santiago@crfreenet.org>
Mon, 23 Jan 2012 02:15:12 +0000 (03:15 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 23 Jan 2012 02:15:12 +0000 (03:15 +0100)
Thanks to Alexander V. Chernikov for original patch.

nest/iface.c
sysdep/bsd/krt-sock.c
sysdep/unix/krt.c
sysdep/unix/krt.h

index d871ff335d261da344565a8d834afb2daf48a827..eea3d3b1ac8f24b53c0051b2953a13954de9efcc 100644 (file)
@@ -306,6 +306,7 @@ if_update(struct iface *new)
            new->addr = i->addr;
            memcpy(&new->addrs, &i->addrs, sizeof(i->addrs));
            memcpy(i, new, sizeof(*i));
+           i->flags &= ~IF_UP; /* IF_TMP_DOWN will be added later */
            goto newif;
          }
 
index f831327b9597d00a12c4fafdd4326bb1be34fc28..4ee5495f1e238a06c57e37924a2ed484c9a3c351 100644 (file)
@@ -409,6 +409,33 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
     krt_got_route_async(p, e, new);
 }
 
+static void
+krt_read_ifannounce(struct ks_msg *msg)
+{
+  struct if_announcemsghdr *ifam = (struct if_announcemsghdr *)&msg->rtm;
+
+  if (ifam->ifan_what == IFAN_ARRIVAL)
+  {
+    /* Not enough info to create the iface, so we just trigger iface scan */
+    kif_request_scan();
+  }
+  else if (ifam->ifan_what == IFAN_DEPARTURE)
+  {
+    struct iface *iface = if_find_by_index(ifam->ifan_index);
+
+    /* Interface is destroyed */
+    if (!iface)
+    {
+      DBG("KRT: unknown interface (%s, #%d) going down. Ignoring\n", ifam->ifan_name, ifam->ifan_index);
+      return;
+    }
+
+    if_delete(iface);
+  }
+
+  DBG("KRT: IFANNOUNCE what: %d index %d name %s\n", ifam->ifan_what, ifam->ifan_index, ifam->ifan_name);
+}
+
 static void
 krt_read_ifinfo(struct ks_msg *msg)
 {
@@ -435,7 +462,7 @@ krt_read_ifinfo(struct ks_msg *msg)
 
   if (dl && (dl->sdl_family != AF_LINK))
   {
-    log("Ignoring strange IFINFO");
+    log(L_WARN "Ignoring strange IFINFO");
     return;
   }
 
@@ -599,6 +626,9 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan)
     case RTM_DELETE:
       krt_read_rt(msg, (struct krt_proto *)p, scan);
       break;
+    case RTM_IFANNOUNCE:
+      krt_read_ifannounce(msg);
+      break;
     case RTM_IFINFO:
       krt_read_ifinfo(msg);
       break;
index e5a8ce1758c22ad193bf00e641f282413fe49125..ad8ea6b6d88e4324bf08a59e9c64b667596e360b 100644 (file)
@@ -104,6 +104,13 @@ kif_force_scan(void)
     }
 }
 
+void
+kif_request_scan(void)
+{
+  if (kif_proto && kif_scan_timer->expires > now)
+    tm_start(kif_scan_timer, 1);
+}
+
 static struct proto *
 kif_init(struct proto_config *c)
 {
index 7bb4fe702100012c40d6bf22d813c1fe29d6ab7b..b0c4dc5e5c8a92060ebcd0f17aa6b9839dd5cce2 100644 (file)
@@ -77,6 +77,7 @@ extern pool *krt_pool;
   if (pr->p.debug & fl)                                \
     { log(L_TRACE "%s: " msg, pr->p.name , ## args); } } while(0)
 
+void kif_request_scan(void);
 void krt_got_route(struct krt_proto *p, struct rte *e);
 void krt_got_route_async(struct krt_proto *p, struct rte *e, int new);