]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixes longstanding issue with interfaces staying in IF_TMP_DOWN.
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 26 Feb 2014 11:52:00 +0000 (12:52 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 26 Feb 2014 11:52:00 +0000 (12:52 +0100)
Thanks to Pierluigi Rolando and others for the bugreport.

sysdep/bsd/krt-sock.c
sysdep/linux/netlink.c

index 176e11ed66830070ecc2c4bee091d16af168eeed..aaeb7d9044c9b3b148a15ed6fa68de5eef07d518 100644 (file)
@@ -535,7 +535,7 @@ krt_read_ifannounce(struct ks_msg *msg)
 }
 
 static void
-krt_read_ifinfo(struct ks_msg *msg)
+krt_read_ifinfo(struct ks_msg *msg, int scan)
 {
   struct if_msghdr *ifm = (struct if_msghdr *)&msg->rtm;
   void *body = (void *)(ifm + 1);
@@ -608,11 +608,14 @@ krt_read_ifinfo(struct ks_msg *msg)
   else
     f.flags |= IF_MULTIACCESS;      /* NBMA */
 
-  if_update(&f);
+  iface = if_update(&f);
+
+  if (!scan)
+    if_end_partial_update(iface);
 }
 
 static void
-krt_read_addr(struct ks_msg *msg)
+krt_read_addr(struct ks_msg *msg, int scan)
 {
   struct ifa_msghdr *ifam = (struct ifa_msghdr *)&msg->rtm;
   void *body = (void *)(ifam + 1);
@@ -715,6 +718,9 @@ krt_read_addr(struct ks_msg *msg)
     ifa_update(&ifa);
   else
     ifa_delete(&ifa);
+
+  if (!scan)
+    if_end_partial_update(iface);
 }
 
 static void
@@ -734,11 +740,11 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan)
       krt_read_ifannounce(msg);
       break;
     case RTM_IFINFO:
-      krt_read_ifinfo(msg);
+      krt_read_ifinfo(msg, scan);
       break;
     case RTM_NEWADDR:
     case RTM_DELADDR:
-      krt_read_addr(msg);
+      krt_read_addr(msg, scan);
       break;
     default:
       break;
index ed8769b70507210d6d23f1b28851e6081f2c59ae..7063e2ca57dd3735442715875b9a3ce3d8f89d81 100644 (file)
@@ -437,12 +437,16 @@ nl_parse_link(struct nlmsghdr *h, int scan)
        f.flags |= IF_MULTIACCESS | IF_BROADCAST | IF_MULTICAST;
       else
        f.flags |= IF_MULTIACCESS;      /* NBMA */
-      if_update(&f);
+
+      ifi = if_update(&f);
+
+      if (!scan)
+       if_end_partial_update(ifi);
     }
 }
 
 static void
-nl_parse_addr(struct nlmsghdr *h)
+nl_parse_addr(struct nlmsghdr *h, int scan)
 {
   struct ifaddrmsg *i;
   struct rtattr *a[IFA_ANYCAST+1];
@@ -542,10 +546,14 @@ nl_parse_addr(struct nlmsghdr *h)
       ifi->index, ifi->name,
       new ? "added" : "removed",
       ifa.ip, ifa.flags, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
+
   if (new)
     ifa_update(&ifa);
   else
     ifa_delete(&ifa);
+
+  if (!scan)
+    if_end_partial_update(ifi);
 }
 
 void
@@ -565,7 +573,7 @@ kif_do_scan(struct kif_proto *p UNUSED)
   nl_request_dump(RTM_GETADDR);
   while (h = nl_get_scan())
     if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
-      nl_parse_addr(h);
+      nl_parse_addr(h, 1);
     else
       log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
 
@@ -967,7 +975,7 @@ nl_async_msg(struct nlmsghdr *h)
     case RTM_NEWADDR:
     case RTM_DELADDR:
       DBG("KRT: Received async address notification (%d)\n", h->nlmsg_type);
-      nl_parse_addr(h);
+      nl_parse_addr(h, 0);
       break;
     default:
       DBG("KRT: Received unknown async notification (%d)\n", h->nlmsg_type);