Re-introduce our loop to poll interface flags when the interface does

not support link states, but this time ensure we don't call IFF_UP inside
the loop. This now works nicely with PPP interfaces on NetBSD at least.
This commit is contained in:
Roy Marples 2014-10-08 12:30:27 +00:00
parent f775cf5cd7
commit 559da5b05d
2 changed files with 48 additions and 22 deletions

View File

@ -640,10 +640,8 @@ dhcpcd_startinterface(void *arg)
struct if_options *ifo = ifp->options;
size_t i;
char buf[DUID_LEN * 3];
pre_start(ifp);
if (if_up(ifp) == -1)
syslog(LOG_ERR, "%s: if_up: %m", ifp->name);
int carrier;
struct timeval tv;
if (ifo->options & DHCPCD_LINK) {
switch (ifp->carrier) {
@ -654,17 +652,14 @@ dhcpcd_startinterface(void *arg)
return;
case LINK_UNKNOWN:
/* No media state available.
* Any change on state such as IFF_UP and IFF_RUNNING
* should be reported to us via the route socket
* as we've done the best we can to bring the interface
* up at this point. */
ifp->carrier = if_carrier(ifp);
if (ifp->carrier == LINK_UNKNOWN) {
syslog(LOG_INFO, "%s: unknown carrier",
ifp->name);
return;
}
dhcpcd_handlecarrier(ifp->ctx, ifp->carrier,
* Loop until both IFF_UP and IFF_RUNNING are set */
if ((carrier = if_carrier(ifp)) == LINK_UNKNOWN) {
tv.tv_sec = 0;
tv.tv_usec = IF_POLL_UP * 1000;
eloop_timeout_add_tv(ifp->ctx->eloop,
&tv, dhcpcd_startinterface, ifp);
} else
dhcpcd_handlecarrier(ifp->ctx, carrier,
ifp->flags, ifp->name);
return;
}
@ -745,6 +740,33 @@ dhcpcd_startinterface(void *arg)
dhcp_start(ifp);
}
static void
dhcpcd_prestartinterface(void *arg)
{
struct interface *ifp = arg;
pre_start(ifp);
if (if_up(ifp) == -1)
syslog(LOG_ERR, "%s: if_up: %m", ifp->name);
if (ifp->options->options & DHCPCD_LINK &&
ifp->carrier == LINK_UNKNOWN)
{
int carrier;
if ((carrier = if_carrier(ifp)) != LINK_UNKNOWN) {
dhcpcd_handlecarrier(ifp->ctx, carrier,
ifp->flags, ifp->name);
return;
}
syslog(LOG_INFO,
"%s: unknown carrier, waiting for interface flags",
ifp->name);
}
dhcpcd_startinterface(ifp);
}
static void
handle_link(void *arg)
{
@ -803,8 +825,7 @@ run_preinit(struct interface *ifp)
script_runreason(ifp, "PREINIT");
if (ifp->carrier != LINK_UNKNOWN &&
ifp->options->options & DHCPCD_LINK)
if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN)
script_runreason(ifp,
ifp->carrier == LINK_UP ? "CARRIER" : "NOCARRIER");
}
@ -864,7 +885,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname)
iff = ifp;
}
if (action > 0)
dhcpcd_startinterface(iff);
dhcpcd_prestartinterface(iff);
}
/* Free our discovered list */
@ -915,7 +936,7 @@ if_reboot(struct interface *ifp, int argc, char **argv)
configure_interface(ifp, argc, argv);
dhcp_reboot_newopts(ifp, oldopts);
dhcp6_reboot(ifp);
dhcpcd_startinterface(ifp);
dhcpcd_prestartinterface(ifp);
}
static void
@ -941,7 +962,7 @@ reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi)
TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next);
dhcpcd_initstate1(ifp, argc, argv);
run_preinit(ifp);
dhcpcd_startinterface(ifp);
dhcpcd_prestartinterface(ifp);
}
}
free(ifs);
@ -1691,7 +1712,8 @@ main(int argc, char **argv)
ipv4_sortinterfaces(&ctx);
TAILQ_FOREACH(ifp, ctx.ifaces, next) {
eloop_timeout_add_sec(ctx.eloop, 0, dhcpcd_startinterface, ifp);
eloop_timeout_add_sec(ctx.eloop, 0,
dhcpcd_prestartinterface, ifp);
}
i = eloop_start(&ctx);

View File

@ -52,6 +52,10 @@
#define IF_DATA_DHCP6 4
#define IF_DATA_MAX 5
/* If the interface does not support carrier status (ie PPP),
* dhcpcd can poll it for the relevant flags periodically */
#define IF_POLL_UP 100 /* milliseconds */
struct interface {
struct dhcpcd_ctx *ctx;
TAILQ_ENTRY(interface) next;