From: Roy Marples Date: Fri, 24 Jul 2015 20:47:08 +0000 (+0000) Subject: When dropping IPv4LL state, remove the address and rebuild routes before X-Git-Tag: v6.9.2~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b34ac49dde0d43a4c059107676209ccc922cd17;p=thirdparty%2Fdhcpcd.git When dropping IPv4LL state, remove the address and rebuild routes before calling dhcpcd-run-hooks. Ensure that the IPv4LL random state is only used when picking addresses and the original state is restored. --- diff --git a/dhcpcd.h b/dhcpcd.h index 31b6959e..5c5fc18a 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -123,6 +123,8 @@ struct dhcpcd_ctx { struct dhcp_opt *vivso; size_t vivso_len; + char *randomstate; /* original state */ + #ifdef INET struct dhcp_opt *dhcp_opts; size_t dhcp_opts_len; diff --git a/ipv4ll.c b/ipv4ll.c index c119778f..564f98f4 100644 --- a/ipv4ll.c +++ b/ipv4ll.c @@ -52,6 +52,10 @@ static in_addr_t ipv4ll_pick_addr(const struct arp_state *astate) { struct in_addr addr; + struct ipv4ll_state *istate; + + istate = IPV4LL_STATE(astate->iface); + setstate(istate->randomstate); do { /* RFC 3927 Section 2.1 states that the first 256 and @@ -66,6 +70,9 @@ ipv4ll_pick_addr(const struct arp_state *astate) /* Ensure we don't have the address on another interface */ } while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL); + /* Restore the original random state */ + setstate(astate->iface->ctx->randomstate); + return addr.s_addr; } @@ -315,6 +322,7 @@ ipv4ll_start(void *arg) * the same address without persistent storage. */ if (state->conflicts == 0) { unsigned int seed; + char *orig; if (sizeof(seed) > ifp->hwlen) { seed = 0; @@ -322,7 +330,15 @@ ipv4ll_start(void *arg) } else memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed), sizeof(seed)); - initstate(seed, state->randomstate, sizeof(state->randomstate)); + orig = initstate(seed, + state->randomstate, sizeof(state->randomstate)); + + /* Save the original state. */ + if (ifp->ctx->randomstate == NULL) + ifp->ctx->randomstate = orig; + + /* Set back the original state until we need the seeded one. */ + setstate(ifp->ctx->randomstate); } if ((astate = arp_new(ifp, NULL)) == NULL) @@ -358,7 +374,6 @@ ipv4ll_start(void *arg) return; } - setstate(state->randomstate); logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address", ifp->name); astate->addr.s_addr = ipv4ll_pick_addr(astate); @@ -407,16 +422,15 @@ ipv4ll_freedrop(struct interface *ifp, int drop) } } } - - if (dropped) - script_runreason(ifp, "IPV4LL"); } if (state) { free(state); ifp->if_data[IF_DATA_IPV4LL] = NULL; - if (dropped) + if (dropped) { ipv4_buildroutes(ifp->ctx); + script_runreason(ifp, "IPV4LL"); + } } }