]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Only reset the IPv4LL conflict counter after we have finished
authorRoy Marples <roy@marples.name>
Tue, 21 Oct 2014 11:06:36 +0000 (11:06 +0000)
committerRoy Marples <roy@marples.name>
Tue, 21 Oct 2014 11:06:36 +0000 (11:06 +0000)
announcing our address or we bind a non IPv4LL address.

arp.c
dhcp.c
ipv4ll.c
ipv4ll.h

diff --git a/arp.c b/arp.c
index f8dd9c22c4492a3d902a7ad1016db78f3cfbd7e3..7fdfd09e60bb4e4be9c9eabb9e05cc7fe03fd429 100644 (file)
--- a/arp.c
+++ b/arp.c
@@ -277,16 +277,21 @@ arp_announce(void *arg)
                return;
        }
        if (state->new->cookie != htonl(MAGIC_COOKIE)) {
+               /* Reset the conflict counter when we finish announcing. */
+               eloop_timeout_add_sec(ifp->ctx->eloop,
+                   ANNOUNCE_WAIT, ipv4ll_claimed, ifp);
                /* Check if doing DHCP */
                if (!(ifp->options->options & DHCPCD_DHCP))
                        return;
                /* We should pretend to be at the end
                 * of the DHCP negotation cycle unless we rebooted */
-               if (state->interval != 0)
-                       state->interval = 64;
+               if (state->interval)
+                       state->interval = 64 + DHCP_RAND_MIN;
+               else
+                       state->interval = ANNOUNCE_WAIT;
                state->probes = 0;
                state->claims = 0;
-               tv.tv_sec = state->interval - DHCP_RAND_MIN;
+               tv.tv_sec = state->interval;
                tv.tv_usec = (suseconds_t)arc4random_uniform(
                    (DHCP_RAND_MAX - DHCP_RAND_MIN) * 1000000);
                timernorm(&tv);
diff --git a/dhcp.c b/dhcp.c
index 9131ba69b60f7dd02ca7fa59ce83d7aad74fa0ef..e0498647eb774e9e43fd141536091cbb57f9c467 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -1964,8 +1964,12 @@ dhcp_bind(void *arg)
 applyaddr:
        ipv4_applyaddr(ifp);
        if (dhcpcd_daemonise(ifp->ctx) == 0) {
-               if (!ipv4ll)
+               if (!ipv4ll) {
+                       /* We bound a non IPv4LL address so reset the
+                        * conflict counter */
+                       state->conflicts = 0;
                        arp_close(ifp);
+               }
                if (ifo->options & DHCPCD_ARP) {
                        state->claims = 0;
                        if (state->added)
index c3afd11cf4a3da29ae2f259d53072ceeccd77d92..1d59bc9dbee1590fc3869fb15d5923a27fff72a9 100644 (file)
--- a/ipv4ll.c
+++ b/ipv4ll.c
@@ -85,6 +85,15 @@ ipv4ll_find_lease(uint32_t old_addr)
        return ipv4ll_make_lease(addr);
 }
 
+void
+ipv4ll_claimed(void *arg)
+{
+       struct interface *ifp = arg;
+       struct dhcp_state *state = D_STATE(ifp);
+
+       state->conflicts = 0;
+}
+
 void
 ipv4ll_start(void *arg)
 {
@@ -96,7 +105,6 @@ ipv4ll_start(void *arg)
        state->probes = 0;
        state->claims = 0;
        if (state->addr.s_addr) {
-               state->conflicts = 0;
                if (IN_LINKLOCAL(htonl(state->addr.s_addr))) {
                        arp_announce(ifp);
                        return;
@@ -144,7 +152,6 @@ ipv4ll_handle_failure(void *arg)
                            "%s: IPv4LL %d second defence failed for %s",
                            ifp->name, DEFEND_INTERVAL, inet_ntoa(state->addr));
                        dhcp_drop(ifp, "EXPIRE");
-                       state->conflicts = -1;
                } else {
                        syslog(LOG_DEBUG, "%s: defended IPv4LL address %s",
                            ifp->name, inet_ntoa(state->addr));
index 462b6312a61ea658648b6c19c02946f65989f9e3..803f63fd907a12cc0ab0cfb17f7c89532b3c15cc 100644 (file)
--- a/ipv4ll.h
+++ b/ipv4ll.h
@@ -29,6 +29,7 @@
 #define IPV4LL_H
 
 void ipv4ll_start(void *);
+void ipv4ll_claimed(void *);
 void ipv4ll_handle_failure(void *);
 
 #endif