From: Roy Marples Date: Mon, 3 Mar 2014 12:10:58 +0000 (+0000) Subject: Expire DHCP lease and then run no carrier as a seperate operation. X-Git-Tag: v6.3.2~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4145d2b68a071aafcd0284b9f0ce0effb3aa7dd7;p=thirdparty%2Fdhcpcd.git Expire DHCP lease and then run no carrier as a seperate operation. Instead of waiting the maximum amount of time to report DAD failure/completion, poll the address flags periodically. --- diff --git a/dhcp6.c b/dhcp6.c index 1edf8d69..22c6b1f4 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -2409,9 +2409,9 @@ recv: /* If all addresses have completed DAD run the script */ TAILQ_FOREACH(ap, &state->addrs, next) { if (ap->flags & IPV6_AF_ONLINK) { - if (!(ap->flags & IPV6_AF_DADCOMPLETED) && - ipv6_findaddr(ap->iface, &ap->addr)) - ap->flags |= IPV6_AF_DADCOMPLETED; +// if (!(ap->flags & IPV6_AF_DADCOMPLETED) && +// ipv6_findaddr(ap->iface, &ap->addr)) +// ap->flags |= IPV6_AF_DADCOMPLETED; if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) { len = 0; break; diff --git a/dhcpcd.c b/dhcpcd.c index 6350dd9e..7bd9124e 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -519,7 +519,8 @@ handle_carrier(struct dhcpcd_ctx *ctx, int carrier, int flags, * them as some OS's will remove, mark tentative or * do nothing. */ ipv6_free_ll_callbacks(ifp); - dhcp_drop(ifp, "NOCARRIER"); + dhcp_drop(ifp, "EXPIRE"); + script_runreason(ifp, "NOCARRIER"); } } else if (carrier == LINK_UP && ifp->flags & IFF_UP) { if (ifp->carrier != LINK_UP) { diff --git a/ipv6.c b/ipv6.c index 03810a91..8e917e64 100644 --- a/ipv6.c +++ b/ipv6.c @@ -418,6 +418,31 @@ ipv6_userprefix( return 0; } +#ifdef LISTEN_DAD +void +ipv6_checkaddrflags(void *arg) +{ + struct ipv6_addr *ap; + int ifa_flags; + + ap = arg; + ifa_flags = in6_addr_flags(ap->iface->name, &ap->addr); + if (ifa_flags == -1) + syslog(LOG_ERR, "%s: in6_addr_flags: %m", ap->iface->name); + else if (!(ifa_flags & IN6_IFF_TENTATIVE)) { + ipv6_handleifa(ap->iface->ctx, RTM_NEWADDR, + ap->iface->ctx->ifaces, ap->iface->name, + &ap->addr, ifa_flags); + } else { + struct timeval tv; + + ms_to_tv(&tv, RETRANS_TIMER / 2); + eloop_timeout_add_tv(ap->iface->ctx->eloop, &tv, + ipv6_checkaddrflags, ap); + } +} +#endif + int ipv6_addaddr(struct ipv6_addr *ap) { @@ -866,7 +891,6 @@ make_prefix(const struct interface * ifp, const struct ra *rap, return r; } - static struct rt6 * make_router(const struct ra *rap) { diff --git a/ipv6.h b/ipv6.h index d0b8002c..b94cdf8a 100644 --- a/ipv6.h +++ b/ipv6.h @@ -175,6 +175,7 @@ int ipv6_mask(struct in6_addr *, int); int ipv6_prefixlen(const struct in6_addr *); int ipv6_userprefix( const struct in6_addr *, short prefix_len, uint64_t user_number, struct in6_addr *result, short result_len); +void ipv6_checkaddrflags(void *); int ipv6_addaddr(struct ipv6_addr *); void ipv6_freedrop_addrs(struct ipv6_addrhead *, int, const struct interface *); diff --git a/ipv6nd.c b/ipv6nd.c index 5a12c69a..b05f3a07 100644 --- a/ipv6nd.c +++ b/ipv6nd.c @@ -1338,6 +1338,7 @@ ipv6nd_cancelprobeaddr(struct ipv6_addr *ap) if (ap->dadcallback) eloop_timeout_delete(ap->iface->ctx->eloop, ap->dadcallback,ap); } + #endif void @@ -1351,11 +1352,10 @@ ipv6nd_probeaddr(void *arg) struct cmsghdr *cm; struct in6_pktinfo pi; int hoplimit = HOPLIMIT; + struct timeval tv, rtv; #else #ifdef LISTEN_DAD - struct timeval tv, rtv; - struct timeval mtv; - int i; + struct timeval tv; #endif #endif @@ -1474,18 +1474,11 @@ ipv6nd_probeaddr(void *arg) #ifdef LISTEN_DAD /* Let the kernel handle DAD. - * We don't know the timings, so just wait for the max */ + * We don't know the timings, so just poll the address flags */ if (ap->dadcallback) { - mtv.tv_sec = 0; - mtv.tv_usec = 0; - for (i = 0; i < ap->iface->options->dadtransmits; i++) { - ms_to_tv(&tv, RETRANS_TIMER); - ms_to_tv(&rtv, MAX_RANDOM_FACTOR); - timeradd(&tv, &rtv, &tv); - timeradd(&mtv, &tv, &mtv); - } + ms_to_tv(&tv, RETRANS_TIMER / 2); eloop_timeout_add_tv(ap->iface->ctx->eloop, - &mtv, ap->dadcallback, ap); + &tv, ipv6_checkaddrflags, ap); } #endif #endif /* IPV6_SEND_DAD */