[link-detect] Try to get BSD link-detect to work properly.

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.
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index a91d76f..cd30631 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -295,6 +295,18 @@
 }
 #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 @@
        * 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 @@
           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);