From: Roy Marples Date: Tue, 22 Jul 2014 18:03:34 +0000 (+0000) Subject: When starting an interface and the carrier is UNKNOWN, wait 100ms before trying to... X-Git-Tag: v6.4.3~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bfeb5ecd10290ec769e1b3883717bcb923294fd5;p=thirdparty%2Fdhcpcd.git When starting an interface and the carrier is UNKNOWN, wait 100ms before trying to start again. UNKNOWN should only be reported for BSD systems where the carrier medium reports an error or is not valid. In this case the carrier is only UP when IFF_RUNNING is set. --- diff --git a/dhcpcd.c b/dhcpcd.c index f9e12ca5..79e48ec8 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -610,14 +610,27 @@ dhcpcd_startinterface(void *arg) struct if_options *ifo = ifp->options; size_t i; char buf[DUID_LEN * 3]; + struct timeval tv; pre_start(ifp); if (if_up(ifp) == -1) syslog(LOG_ERR, "%s: if_up: %m", ifp->name); - if (ifp->carrier == LINK_DOWN && ifo->options & DHCPCD_LINK) { - syslog(LOG_INFO, "%s: waiting for carrier", ifp->name); - return; + if (ifo->options & DHCPCD_LINK) { + switch (ifp->carrier) { + case LINK_UP: + break; + case LINK_DOWN: + syslog(LOG_INFO, "%s: waiting for carrier", ifp->name); + return; + case LINK_UNKNOWN: + syslog(LOG_INFO, "%s: unknown carrier", ifp->name); + tv.tv_sec = 0; + tv.tv_usec = 100; + eloop_timeout_add_tv(ifp->ctx->eloop, &tv, + dhcpcd_startinterface, ifp); + return; + } } if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6)) { diff --git a/if.c b/if.c index 67eadcf6..ba374452 100644 --- a/if.c +++ b/if.c @@ -118,16 +118,17 @@ if_carrier(struct interface *iface) } iface->flags = (unsigned int)ifr.ifr_flags; - r = LINK_UNKNOWN; #ifdef SIOCGIFMEDIA memset(&ifmr, 0, sizeof(ifmr)); strlcpy(ifmr.ifm_name, iface->name, sizeof(ifmr.ifm_name)); if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 && ifmr.ifm_status & IFM_AVALID) r = (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN; + else + r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_UNKNOWN; +#else + r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN; #endif - if (r == LINK_UNKNOWN) - r = (ifr.ifr_flags & IFF_RUNNING) ? LINK_UP : LINK_DOWN; close(s); return r; } @@ -152,7 +153,7 @@ if_setflag(struct interface *ifp, short flag) #endif r = -1; if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { - if (flag == 0 || ifr.ifr_flags & flag) + if (flag == 0 || (ifr.ifr_flags & flag) == flag) r = 0; else { ifr.ifr_flags |= flag; diff --git a/if.h b/if.h index 2f6e25b5..c829b7ea 100644 --- a/if.h +++ b/if.h @@ -91,7 +91,7 @@ #define RAW_PARTIALCSUM 2 << 0 int if_setflag(struct interface *ifp, short flag); -#define if_up(ifp) if_setflag((ifp), IFF_UP) +#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING)) struct if_head *if_discover(struct dhcpcd_ctx *, int, char * const *); struct interface *if_find(struct dhcpcd_ctx *, const char *); void if_free(struct interface *);