diff options
| author | Roy Marples <roy@marples.name> | 2014-12-09 09:39:30 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2014-12-09 09:39:30 +0000 |
| commit | 0ddc18a90d17f56377a0c7d3fcbedbd2252512b3 (patch) | |
| tree | 6263011ec7c0ba8a606c0a0cb4491b47d347fc0d /dhcpcd.c | |
| parent | e7afdb1d82974ccbb011e5dc3df5cccd74eba8eb (diff) | |
| download | dhcpcd-0ddc18a90d17f56377a0c7d3fcbedbd2252512b3.tar.xz | |
Instead if giving up if we receive a LINK_UP event before the kernel has set
IFF_UP, poll for it until it's set or carrier goes down.
Diffstat (limited to 'dhcpcd.c')
| -rw-r--r-- | dhcpcd.c | 36 |
1 files changed, 28 insertions, 8 deletions
@@ -538,6 +538,25 @@ configure_interface(struct interface *ifp, int argc, char **argv) configure_interface1(ifp); } +static void +dhcpcd_pollup(void *arg) +{ + struct interface *ifp = arg; + int carrier; + + carrier = if_carrier(ifp); /* will set ifp->flags */ + if (carrier == LINK_UP && !(ifp->flags & IFF_UP)) { + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = IF_POLL_UP * 1000; + eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcpcd_pollup, ifp); + return; + } + + dhcpcd_handlecarrier(ifp->ctx, carrier, ifp->flags, ifp->name); +} + void dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags, const char *ifname) @@ -553,14 +572,15 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags, carrier = if_carrier(ifp); /* will set ifp->flags */ break; case LINK_UP: - /* we have a carrier! however, we need to ignore the flags - * set in the kernel message as sometimes this message is - * reported before IFF_UP is set by the kernel even though - * dhcpcd has already set it. - * - * So we check the flags now. If IFF_UP is still not set - * then we should expect an accompanying link_down message */ - if_setflag(ifp, 0); /* will set ifp->flags */ + /* we have a carrier! Still need to check for IFF_UP */ + if (flags & IFF_UP) + ifp->flags = flags; + else { + /* So we need to poll for IFF_UP as there is no + * kernel notification when it's set. */ + dhcpcd_pollup(ifp); + return; + } break; default: ifp->flags = flags; |
