]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Expire DHCP lease and then run no carrier as a seperate operation.
authorRoy Marples <roy@marples.name>
Mon, 3 Mar 2014 12:10:58 +0000 (12:10 +0000)
committerRoy Marples <roy@marples.name>
Mon, 3 Mar 2014 12:10:58 +0000 (12:10 +0000)
Instead of waiting the maximum amount of time to report DAD failure/completion, poll the address flags periodically.

dhcp6.c
dhcpcd.c
ipv6.c
ipv6.h
ipv6nd.c

diff --git a/dhcp6.c b/dhcp6.c
index 1edf8d69901f1bf5fd228739b1b83c5b676b1a78..22c6b1f454dc0787de1e988e7c371b3879c0a1b9 100644 (file)
--- 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;
index 6350dd9ef3cc7f46ca2bf4fdb37746b6ea120ed5..7bd9124e78256162710462d243c3d3a19f350aa2 100644 (file)
--- 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 03810a91560f20af2e3bfe5d1bc638387e6fc2db..8e917e64d59624968b3fdb9d7e509cb4d2cbb9a7 100644 (file)
--- 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 d0b8002c4a3758959b6d7e83d80bac42d948013c..b94cdf8aa89b0d7064091610d98e4134b104f0de 100644 (file)
--- 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 *);
index 5a12c69a3c3fcd516ba47783952a7ba223e21684..b05f3a07d2fa53e1e74fb4b7eee7e06b0697f43c 100644 (file)
--- 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 */