]> git.puffer.fish Git - mirror/frr.git/commitdiff
[link-detect] Try to get BSD link-detect to work properly.
authorAndrew J. Schorr <ajschorr@alumni.princeton.edu>
Thu, 10 Jan 2008 15:24:32 +0000 (15:24 +0000)
committerAndrew J. Schorr <ajschorr@alumni.princeton.edu>
Thu, 10 Jan 2008 15:24:32 +0000 (15:24 +0000)
2008-01-10 Ingo Flaschberger <if@xip.at>

* configure.ac: Define HAVE_BSD_LINK_DETECT if <net/if_media.h> is
  present.
* lib/zebra.h: If HAVE_BSD_LINK_DETECT is defined,
  include <net/if_media.h>.
* zebra/ioctl.c: (if_get_flags) If HAVE_BSD_LINK_DETECT, use the
  SIOCGIFMEDIA ioctl to ascertain link state.
* zebra/kernel_socket.c: (bsd_linkdetect_translate) New function to
  map the ifm_data.ifi_link_state value into the IFF_RUNNING flag.
  (ifm_read) Call bsd_linkdetect_translate to fix the IFF_RUNNING
  flag before calling if_flags_update.

ChangeLog
configure.ac
lib/ChangeLog
lib/zebra.h
zebra/ChangeLog
zebra/ioctl.c
zebra/kernel_socket.c

index 6cde4262ba63a0682060e1ef074ea3137eb7fe47..539720e986eebd9b9adfff067e69416297dbbd94 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-10 Ingo Flaschberger <if@xip.at>
+
+       * configure.ac: Define HAVE_BSD_LINK_DETECT if <net/if_media.h> is
+         present.
+
 2007-10-14 Paul Jakma <paul.jakma@sun.com>
 
        * NEWS: Note that MRT dumps are now version 2
index a76649b5d3666d6f49dd15c337f913747966e40c..7f061bb1a361aa07736319cf655c669472768de9 100755 (executable)
@@ -890,6 +890,13 @@ AC_TRY_COMPILE([#ifdef HAVE_SYS_PARAM_H
 AC_DEFINE(HAVE_BSD_STRUCT_IP_MREQ_HACK,,[Can pass ifindex in struct ip_mreq])],
 AC_MSG_RESULT(no))
 
+dnl ---------------------------------------------------------------
+dnl figure out how to check link-state
+dnl ---------------------------------------------------------------
+AC_CHECK_HEADER([net/if_media.h],
+  [AC_DEFINE(HAVE_BSD_LINK_DETECT,,[BSD link-detect])],
+  [], QUAGGA_INCLUDES)
+
 dnl -----------------------
 dnl check proc file system.
 dnl -----------------------
index bbbdfab01c1ab3c9b77a7607776a2d78dbbcaaff..21d08dd031bbbca76ee5129d12f2c8a6d2cfe56c 100644 (file)
@@ -1,3 +1,7 @@
+2008-01-10 Ingo Flaschberger <if@xip.at>
+
+       * zebra.h: If HAVE_BSD_LINK_DETECT is defined, include <net/if_media.h>.
+
 2008-01-08 Pavol Rusnak <prusnak@suse.cz>
 
        * memory.c: (mtype_memstr) Fix accidental shift past width of type,
index 150aa2c59cf977ddc31545ffaa20d10f49a77448..1c9eb39ff81533c1271520090ac9d647bc2d783a 100644 (file)
@@ -116,6 +116,9 @@ typedef int socklen_t;
 #endif /* !va_copy */
 #endif /* !C99 */
 
+#ifdef HAVE_BSD_LINK_DETECT
+#include <net/if_media.h>
+#endif /* HAVE_BSD_LINK_DETECT*/
 
 #ifdef HAVE_LCAPS
 #include <sys/capability.h>
index 3457c785ae4f49f8198c65b5ceaa2f097348de1e..ba6d30701732021856428eb48e381201f2cd01bf 100644 (file)
@@ -1,3 +1,12 @@
+2008-01-10 Ingo Flaschberger <if@xip.at>
+
+       * ioctl.c: (if_get_flags) If HAVE_BSD_LINK_DETECT, use the SIOCGIFMEDIA
+         ioctl to ascertain link state.
+       * kernel_socket.c: (bsd_linkdetect_translate) New function to
+         map the ifm_data.ifi_link_state value into the IFF_RUNNING flag.
+         (ifm_read) Call bsd_linkdetect_translate to fix the IFF_RUNNING
+         flag before calling if_flags_update.
+
 2008-01-08 Michael Larson <mike@vyatta.com>
 
        * zebra_rib.c: (nexthop_active_check) Replace if_is_up with
index c9ec8d5774a2370d6fb5698852c0d59d44a82427..4f99a6cd62dc294d936cda9d38dd8f22729c0230 100644 (file)
@@ -344,6 +344,9 @@ if_get_flags (struct interface *ifp)
 {
   int ret;
   struct ifreq ifreq;
+#ifdef HAVE_BSD_LINK_DETECT
+  struct ifmediareq ifmr;
+#endif /* HAVE_BSD_LINK_DETECT */
 
   ifreq_set_name (&ifreq, ifp);
 
@@ -353,6 +356,36 @@ if_get_flags (struct interface *ifp)
       zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno));
       return;
     }
+#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */
+  (void) memset(&ifmr, 0, sizeof(ifmr));
+  strncpy (&ifmr.ifm_name, ifp->name, IFNAMSIZ);
+  if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0)
+    {
+      zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno));
+      return;
+    }
+  if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
+    {
+      if (ifmr.ifm_status & IFM_ACTIVE)
+        {
+         SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+         zlog_debug("%s: BSD link state to up at interface %s, ifindex %d",
+                    __func__, ifp->name, ifp->ifindex);
+        }
+      else
+        {
+         UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+         zlog_debug("%s: BSD link state to down at interface %s, ifindex %d",
+                    __func__, ifp->name, ifp->ifindex);
+        }
+    }
+  else /* Force always up */
+    {
+      SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+      zlog_debug("%s: BSD link state invalid, forced up at interface %s, ifindex %d",
+                __func__, ifp->name, ifp->ifindex);
+    }
+#endif /* HAVE_BSD_LINK_DETECT */
 
   if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff));
 }
index a91d76f593430ab36f42fc7b6c7e9c2511facaf5..cd30631b38f48800a1fbe2cb0378b9393218bd72 100644 (file)
@@ -295,6 +295,18 @@ ifan_read (struct if_announcemsghdr *ifan)
 }
 #endif /* RTM_IFANNOUNCE */
 
+#ifdef HAVE_BSD_LINK_DETECT
+/* BSD link detect translation */
+static void
+bsd_linkdetect_translate (struct if_msghdr *ifm)
+{
+  if (ifm->ifm_data.ifi_link_state >= LINK_STATE_UP)
+    SET_FLAG(ifm->ifm_flags, IFF_RUNNING);
+  else
+    UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING);
+}
+#endif /* HAVE_BSD_LINK_DETECT */
+
 /*
  * Handle struct if_msghdr obtained from reading routing socket or
  * sysctl (from interface_list).  There may or may not be sockaddrs
@@ -426,6 +438,11 @@ ifm_read (struct if_msghdr *ifm)
        * structure with ifindex IFINDEX_INTERNAL.
        */
       ifp->ifindex = ifm->ifm_index;
+      
+#ifdef HAVE_BSD_LINK_DETECT /* translate BSD kernel msg for link-state */
+      bsd_linkdetect_translate(ifm);
+#endif /* HAVE_BSD_LINK_DETECT */
+
       if_flags_update (ifp, ifm->ifm_flags);
 #if defined(__bsdi__)
       if_kvm_get_mtu (ifp);
@@ -453,6 +470,10 @@ ifm_read (struct if_msghdr *ifm)
           return -1;
         }
       
+#ifdef HAVE_BSD_LINK_DETECT /* translate BSD kernel msg for link-state */
+      bsd_linkdetect_translate(ifm);
+#endif /* HAVE_BSD_LINK_DETECT */
+
       /* update flags and handle operative->inoperative transition, if any */
       if_flags_update (ifp, ifm->ifm_flags);