diff options
Diffstat (limited to 'zebra/ioctl.c')
-rw-r--r-- | zebra/ioctl.c | 33 |
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)); } |