summaryrefslogtreecommitdiff
path: root/zebra/ioctl.c
diff options
context:
space:
mode:
authorAndrew J. Schorr <ajschorr@alumni.princeton.edu>2008-01-10 15:24:32 +0000
committerAndrew J. Schorr <ajschorr@alumni.princeton.edu>2008-01-10 15:24:32 +0000
commitc543a1737173fb438f1d8c06f650b2d0d479f45c (patch)
treeba940242e22f7e6798e6fd24b19864b5702474db /zebra/ioctl.c
parent3f087670efa606021cde2f6a9615ac7e07aec2a5 (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.
Diffstat (limited to 'zebra/ioctl.c')
-rw-r--r--zebra/ioctl.c33
1 files changed, 33 insertions, 0 deletions
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));
}