diff options
author | Andrew J. Schorr <ajschorr@alumni.princeton.edu> | 2008-01-10 15:24:32 +0000 |
---|---|---|
committer | Andrew J. Schorr <ajschorr@alumni.princeton.edu> | 2008-01-10 15:24:32 +0000 |
commit | c543a1737173fb438f1d8c06f650b2d0d479f45c (patch) | |
tree | ba940242e22f7e6798e6fd24b19864b5702474db | |
parent | 3f087670efa606021cde2f6a9615ac7e07aec2a5 (diff) |
[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.
-rw-r--r-- | ChangeLog | 5 | ||||
-rwxr-xr-x | configure.ac | 7 | ||||
-rw-r--r-- | lib/ChangeLog | 4 | ||||
-rw-r--r-- | lib/zebra.h | 3 | ||||
-rw-r--r-- | zebra/ChangeLog | 9 | ||||
-rw-r--r-- | zebra/ioctl.c | 33 | ||||
-rw-r--r-- | zebra/kernel_socket.c | 21 |
7 files changed, 82 insertions, 0 deletions
@@ -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 diff --git a/configure.ac b/configure.ac index a76649b5..7f061bb1 100755 --- a/configure.ac +++ b/configure.ac @@ -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 ----------------------- diff --git a/lib/ChangeLog b/lib/ChangeLog index bbbdfab0..21d08dd0 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -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, diff --git a/lib/zebra.h b/lib/zebra.h index 150aa2c5..1c9eb39f 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -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> diff --git a/zebra/ChangeLog b/zebra/ChangeLog index 3457c785..ba6d3070 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -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 diff --git a/zebra/ioctl.c b/zebra/ioctl.c index c9ec8d57..4f99a6cd 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -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)); } diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index a91d76f5..cd30631b 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -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); |