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.
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)) {
}
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;
}
#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;
#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 *);