[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.
This commit is contained in:
Andrew J. Schorr 2008-01-10 15:24:32 +00:00
parent 3f087670ef
commit c543a17371
7 changed files with 82 additions and 0 deletions

View file

@ -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

View file

@ -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 -----------------------

View 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,

View 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>

View 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

View 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));
}

View 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);