announcing our address or we bind a non IPv4LL address.
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);
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)
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)
{
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;
"%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));
#define IPV4LL_H
void ipv4ll_start(void *);
+void ipv4ll_claimed(void *);
void ipv4ll_handle_failure(void *);
#endif