Module Name: src
Committed By: roy
Date: Wed Oct 29 01:08:31 UTC 2014
Modified Files:
src/external/bsd/dhcpcd/dist: arp.c arp.h auth.c auth.h bpf-filter.h
common.c common.h config.h control.c control.h defs.h dev.h
dhcp-common.c dhcp-common.h dhcp.c dhcp.h dhcp6.c dhcp6.h
dhcpcd-definitions.conf dhcpcd-embedded.c dhcpcd-embedded.h
dhcpcd-run-hooks.8.in dhcpcd-run-hooks.in dhcpcd.8.in dhcpcd.c
dhcpcd.conf dhcpcd.conf.5.in dhcpcd.h duid.c duid.h eloop.c eloop.h
if-bsd.c if-options.c if-options.h if.c if.h ipv4.c ipv4.h ipv4ll.c
ipv4ll.h ipv6.c ipv6.h ipv6nd.c ipv6nd.h script.c script.h
Log Message:
Sync
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/dhcpcd/dist/arp.c \
src/external/bsd/dhcpcd/dist/arp.h src/external/bsd/dhcpcd/dist/auth.c \
src/external/bsd/dhcpcd/dist/auth.h src/external/bsd/dhcpcd/dist/common.c \
src/external/bsd/dhcpcd/dist/common.h \
src/external/bsd/dhcpcd/dist/config.h \
src/external/bsd/dhcpcd/dist/control.c \
src/external/bsd/dhcpcd/dist/control.h \
src/external/bsd/dhcpcd/dist/defs.h src/external/bsd/dhcpcd/dist/dev.h \
src/external/bsd/dhcpcd/dist/dhcp-common.c \
src/external/bsd/dhcpcd/dist/dhcp-common.h \
src/external/bsd/dhcpcd/dist/dhcp.h src/external/bsd/dhcpcd/dist/dhcp6.c \
src/external/bsd/dhcpcd/dist/dhcp6.h \
src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf \
src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c \
src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h \
src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in \
src/external/bsd/dhcpcd/dist/dhcpcd.h src/external/bsd/dhcpcd/dist/duid.c \
src/external/bsd/dhcpcd/dist/duid.h src/external/bsd/dhcpcd/dist/eloop.c \
src/external/bsd/dhcpcd/dist/eloop.h \
src/external/bsd/dhcpcd/dist/if-options.h \
src/external/bsd/dhcpcd/dist/if.c src/external/bsd/dhcpcd/dist/if.h \
src/external/bsd/dhcpcd/dist/ipv4.c src/external/bsd/dhcpcd/dist/ipv4.h \
src/external/bsd/dhcpcd/dist/ipv4ll.c \
src/external/bsd/dhcpcd/dist/ipv4ll.h src/external/bsd/dhcpcd/dist/ipv6.c \
src/external/bsd/dhcpcd/dist/ipv6.h src/external/bsd/dhcpcd/dist/ipv6nd.h \
src/external/bsd/dhcpcd/dist/script.h
cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/bpf-filter.h
cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
cvs rdiff -u -r1.33 -r1.34 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/dhcpcd.c \
src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/dhcpcd.conf \
src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/if-options.c \
src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/script.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/bsd/dhcpcd/dist/arp.c
diff -u src/external/bsd/dhcpcd/dist/arp.c:1.3 src/external/bsd/dhcpcd/dist/arp.c:1.4
--- src/external/bsd/dhcpcd/dist/arp.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/arp.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: arp.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: arp.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -42,7 +42,7 @@
#include <syslog.h>
#include <unistd.h>
-#define ELOOP_QUEUE 2
+#define ELOOP_QUEUE 5
#include "config.h"
#include "arp.h"
#include "ipv4.h"
@@ -97,31 +97,15 @@ eexit:
return -1;
}
-static void
-arp_failure(struct interface *ifp)
+void
+arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
{
- const struct dhcp_state *state = D_CSTATE(ifp);
-
- /* If we failed without a magic cookie then we need to try
- * and defend our IPv4LL address. */
- if ((state->offer != NULL &&
- state->offer->cookie != htonl(MAGIC_COOKIE)) ||
- (state->new != NULL &&
- state->new->cookie != htonl(MAGIC_COOKIE)))
- {
- ipv4ll_handle_failure(ifp);
- return;
- }
+ char buf[HWADDR_LEN * 3];
- unlink(state->leasefile);
- if (!state->lease.frominfo)
- dhcp_decline(ifp);
- eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- if (state->lease.frominfo)
- dhcpcd_startinterface(ifp);
- else
- eloop_timeout_add_sec(ifp->ctx->eloop,
- DHCP_ARP_FAIL, dhcpcd_startinterface, ifp);
+ syslog(LOG_ERR, "%s: hardware address %s claims %s",
+ astate->iface->name,
+ hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf)),
+ inet_ntoa(astate->failed));
}
static void
@@ -131,19 +115,14 @@ arp_packet(void *arg)
const struct interface *ifn;
uint8_t arp_buffer[ARP_LEN];
struct arphdr ar;
- uint32_t reply_s;
- uint32_t reply_t;
- uint8_t *hw_s, *hw_t;
+ struct arp_msg arm;
ssize_t bytes;
struct dhcp_state *state;
- struct if_options *opts = ifp->options;
- const char *hwaddr;
- struct in_addr ina;
- char hwbuf[HWADDR_LEN * 3];
+ struct arp_state *astate, *astaten;
+ unsigned char *hw_s, *hw_t;
int flags;
state = D_STATE(ifp);
- state->fail.s_addr = 0;
flags = 0;
while (!(flags & RAW_EOF)) {
bytes = if_readrawpacket(ifp, ETHERTYPE_ARP,
@@ -158,10 +137,13 @@ arp_packet(void *arg)
if ((size_t)bytes < sizeof(ar))
continue;
memcpy(&ar, arp_buffer, sizeof(ar));
+ /* Families must match */
+ if (ar.ar_hrd != htons(ifp->family))
+ continue;
/* Protocol must be IP. */
if (ar.ar_pro != htons(ETHERTYPE_IP))
continue;
- if (ar.ar_pln != sizeof(reply_s))
+ if (ar.ar_pln != sizeof(arm.sip.s_addr))
continue;
/* Only these types are recognised */
if (ar.ar_op != htons(ARPOP_REPLY) &&
@@ -182,77 +164,26 @@ arp_packet(void *arg)
}
if (ifn)
continue;
- /* Copy out the IP addresses */
- memcpy(&reply_s, hw_s + ar.ar_hln, ar.ar_pln);
- memcpy(&reply_t, hw_t + ar.ar_hln, ar.ar_pln);
-
- /* Check for arping */
- if (state->arping_index &&
- state->arping_index <= opts->arping_len &&
- (reply_s == opts->arping[state->arping_index - 1] ||
- (reply_s == 0 &&
- reply_t == opts->arping[state->arping_index - 1])))
- {
- ina.s_addr = reply_s;
- hwaddr = hwaddr_ntoa((unsigned char *)hw_s,
- (size_t)ar.ar_hln, hwbuf, sizeof(hwbuf));
- syslog(LOG_INFO,
- "%s: found %s on hardware address %s",
- ifp->name, inet_ntoa(ina), hwaddr);
- if (dhcpcd_selectprofile(ifp, hwaddr) == -1 &&
- dhcpcd_selectprofile(ifp, inet_ntoa(ina)) == -1)
- {
- state->probes = 0;
- /* We didn't find a profile for this
- * address or hwaddr, so move to the next
- * arping profile */
- if (state->arping_index <
- ifp->options->arping_len)
- {
- arp_probe(ifp);
- return;
- }
- }
- dhcp_close(ifp);
- eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- dhcpcd_startinterface(ifp);
- return;
- }
-
- /* RFC 2131 3.1.5, Client-server interaction
- * RFC 3927 2.2.1, Probe Conflict Detection */
- if (state->offer &&
- (reply_s == state->offer->yiaddr ||
- (reply_s == 0 && reply_t == state->offer->yiaddr)))
- state->fail.s_addr = state->offer->yiaddr;
-
- /* RFC 3927 2.5, Conflict Defense */
- if (IN_LINKLOCAL(htonl(state->addr.s_addr)) &&
- reply_s == state->addr.s_addr)
- state->fail.s_addr = state->addr.s_addr;
-
- if (state->fail.s_addr) {
- syslog(LOG_ERR, "%s: hardware address %s claims %s",
- ifp->name,
- hwaddr_ntoa((unsigned char *)hw_s,
- (size_t)ar.ar_hln, hwbuf, sizeof(hwbuf)),
- inet_ntoa(state->fail));
- errno = EEXIST;
- arp_failure(ifp);
- return;
+ /* Copy out the HW and IP addresses */
+ memcpy(&arm.sha, hw_s, ar.ar_hln);
+ memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
+ memcpy(&arm.tha, hw_t, ar.ar_hln);
+ memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);
+
+ /* Run the conflicts */
+ TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
+ if (astate->conflicted_cb)
+ astate->conflicted_cb(astate, &arm);
}
}
}
-void
-arp_announce(void *arg)
+static void
+arp_open(struct interface *ifp)
{
- struct interface *ifp = arg;
- struct dhcp_state *state = D_STATE(ifp);
- struct timeval tv;
+ struct dhcp_state *state;
- if (state->new == NULL)
- return;
+ state = D_STATE(ifp);
if (state->arp_fd == -1) {
state->arp_fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
if (state->arp_fd == -1) {
@@ -262,126 +193,157 @@ arp_announce(void *arg)
eloop_event_add(ifp->ctx->eloop, state->arp_fd,
arp_packet, ifp, NULL, NULL);
}
- if (++state->claims < ANNOUNCE_NUM)
+}
+
+static void
+arp_announced(void *arg)
+{
+ struct arp_state *astate = arg;
+
+ if (astate->announced_cb) {
+ astate->announced_cb(astate);
+ return;
+ }
+
+ /* Nothing more to do, so free us */
+ arp_free(astate);
+}
+
+static void
+arp_announce1(void *arg)
+{
+ struct arp_state *astate = arg;
+ struct interface *ifp = astate->iface;
+
+ if (++astate->claims < ANNOUNCE_NUM)
syslog(LOG_DEBUG,
"%s: sending ARP announce (%d of %d), "
"next in %d.0 seconds",
- ifp->name, state->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
+ ifp->name, astate->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
else
syslog(LOG_DEBUG,
"%s: sending ARP announce (%d of %d)",
- ifp->name, state->claims, ANNOUNCE_NUM);
+ ifp->name, astate->claims, ANNOUNCE_NUM);
if (arp_send(ifp, ARPOP_REQUEST,
- state->new->yiaddr, state->new->yiaddr) == -1)
+ astate->addr.s_addr, astate->addr.s_addr) == -1)
syslog(LOG_ERR, "send_arp: %m");
- if (state->claims < ANNOUNCE_NUM) {
- eloop_timeout_add_sec(ifp->ctx->eloop,
- ANNOUNCE_WAIT, arp_announce, ifp);
- return;
- }
- if (state->new->cookie != htonl(MAGIC_COOKIE)) {
- /* 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;
- state->probes = 0;
- state->claims = 0;
- tv.tv_sec = state->interval - DHCP_RAND_MIN;
- tv.tv_usec = (suseconds_t)arc4random_uniform(
- (DHCP_RAND_MAX - DHCP_RAND_MIN) * 1000000);
- timernorm(&tv);
- eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_discover, ifp);
- } else {
- eloop_event_delete(ifp->ctx->eloop, state->arp_fd, 0);
- close(state->arp_fd);
- state->arp_fd = -1;
- }
+ eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
+ astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
+ astate);
}
void
-arp_probe(void *arg)
+arp_announce(struct arp_state *astate)
{
- struct interface *ifp = arg;
- struct dhcp_state *state = D_STATE(ifp);
- struct in_addr addr;
- struct timeval tv;
- int arping = 0;
- if (state->arp_fd == -1) {
- state->arp_fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
- if (state->arp_fd == -1) {
- syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name);
- return;
- }
- eloop_event_add(ifp->ctx->eloop,
- state->arp_fd, arp_packet, ifp, NULL, NULL);
- }
+ arp_open(astate->iface);
+ astate->claims = 0;
+ arp_announce1(astate);
+}
- if (state->arping_index < ifp->options->arping_len) {
- addr.s_addr = ifp->options->arping[state->arping_index];
- arping = 1;
- } else if (state->offer) {
- if (state->offer->yiaddr)
- addr.s_addr = state->offer->yiaddr;
- else
- addr.s_addr = state->offer->ciaddr;
- } else
- addr.s_addr = state->addr.s_addr;
-
- if (state->probes == 0) {
- if (arping)
- syslog(LOG_DEBUG, "%s: searching for %s",
- ifp->name, inet_ntoa(addr));
- else
- syslog(LOG_DEBUG, "%s: checking for %s",
- ifp->name, inet_ntoa(addr));
- }
- if (++state->probes < PROBE_NUM) {
+static void
+arp_probed(void *arg)
+{
+ struct arp_state *astate = arg;
+
+ astate->probed_cb(astate);
+}
+
+static void
+arp_probe1(void *arg)
+{
+ struct arp_state *astate = arg;
+ struct interface *ifp = astate->iface;
+ struct timeval tv;
+
+ if (++astate->probes < PROBE_NUM) {
tv.tv_sec = PROBE_MIN;
tv.tv_usec = (suseconds_t)arc4random_uniform(
(PROBE_MAX - PROBE_MIN) * 1000000);
timernorm(&tv);
- eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe, ifp);
+ eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate);
} else {
tv.tv_sec = ANNOUNCE_WAIT;
tv.tv_usec = 0;
- if (arping) {
- state->probes = 0;
- if (++state->arping_index < ifp->options->arping_len)
- eloop_timeout_add_tv(ifp->ctx->eloop,
- &tv, arp_probe, ifp);
- else
- eloop_timeout_add_tv(ifp->ctx->eloop,
- &tv, dhcpcd_startinterface, ifp);
- } else
- eloop_timeout_add_tv(ifp->ctx->eloop,
- &tv, dhcp_bind, ifp);
+ eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
}
syslog(LOG_DEBUG,
"%s: sending ARP probe (%d of %d), next in %0.1f seconds",
- ifp->name, state->probes ? state->probes : PROBE_NUM, PROBE_NUM,
+ ifp->name, astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
timeval_to_double(&tv));
- if (arp_send(ifp, ARPOP_REQUEST, 0, addr.s_addr) == -1)
+ if (arp_send(ifp, ARPOP_REQUEST, 0, astate->addr.s_addr) == -1)
syslog(LOG_ERR, "send_arp: %m");
}
void
-arp_start(struct interface *ifp)
+arp_probe(struct arp_state *astate)
{
- struct dhcp_state *state = D_STATE(ifp);
- state->probes = 0;
- state->arping_index = 0;
- arp_probe(ifp);
+ arp_open(astate->iface);
+ astate->probes = 0;
+ syslog(LOG_DEBUG, "%s: probing for %s",
+ astate->iface->name, inet_ntoa(astate->addr));
+ arp_probe1(astate);
+}
+
+
+struct arp_state *
+arp_new(struct interface *ifp) {
+ struct arp_state *astate;
+ struct dhcp_state *state;
+
+ astate = calloc(1, sizeof(*astate));
+ if (astate == NULL) {
+ syslog(LOG_ERR, "%s: %s: %m", ifp->name, __func__);
+ return NULL;
+ }
+
+ astate->iface = ifp;
+ state = D_STATE(ifp);
+ TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
+ return astate;
+}
+
+void
+arp_cancel(struct arp_state *astate)
+{
+
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
+}
+
+void
+arp_free(struct arp_state *astate)
+{
+ struct dhcp_state *state;
+
+ if (astate) {
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
+ state = D_STATE(astate->iface);
+ TAILQ_REMOVE(&state->arp_states, astate, next);
+ if (state->arp_ipv4ll == astate)
+ state->arp_ipv4ll = NULL;
+ free(astate);
+ }
+}
+
+void
+arp_free_but(struct arp_state *astate)
+{
+ struct arp_state *p, *n;
+ struct dhcp_state *state;
+
+ state = D_STATE(astate->iface);
+ TAILQ_FOREACH_SAFE(p, &state->arp_states, next, n) {
+ if (p != astate)
+ arp_free(p);
+ }
}
void
arp_close(struct interface *ifp)
{
struct dhcp_state *state = D_STATE(ifp);
+ struct arp_state *astate;
if (state == NULL)
return;
@@ -391,5 +353,8 @@ arp_close(struct interface *ifp)
close(state->arp_fd);
state->arp_fd = -1;
}
-}
+ while ((astate = TAILQ_FIRST(&state->arp_states))) {
+ arp_free(astate);
+ }
+}
Index: src/external/bsd/dhcpcd/dist/arp.h
diff -u src/external/bsd/dhcpcd/dist/arp.h:1.3 src/external/bsd/dhcpcd/dist/arp.h:1.4
--- src/external/bsd/dhcpcd/dist/arp.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/arp.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: arp.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: arp.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -44,8 +44,35 @@
#include "dhcpcd.h"
-void arp_announce(void *);
-void arp_probe(void *);
-void arp_start(struct interface *);
+struct arp_msg {
+ uint16_t op;
+ unsigned char sha[HWADDR_LEN];
+ struct in_addr sip;
+ unsigned char tha[HWADDR_LEN];
+ struct in_addr tip;
+};
+
+struct arp_state {
+ TAILQ_ENTRY(arp_state) next;
+ struct interface *iface;
+
+ void (*probed_cb)(struct arp_state *);
+ void (*announced_cb)(struct arp_state *);
+ void (*conflicted_cb)(struct arp_state *, const struct arp_msg *);
+
+ struct in_addr addr;
+ int probes;
+ int claims;
+ struct in_addr failed;
+};
+TAILQ_HEAD(arp_statehead, arp_state);
+
+void arp_report_conflicted(const struct arp_state *, const struct arp_msg *);
+void arp_announce(struct arp_state *);
+void arp_probe(struct arp_state *);
+struct arp_state *arp_new(struct interface *);
+void arp_cancel(struct arp_state *);
+void arp_free(struct arp_state *);
+void arp_free_but(struct arp_state *);
void arp_close(struct interface *);
#endif
Index: src/external/bsd/dhcpcd/dist/auth.c
diff -u src/external/bsd/dhcpcd/dist/auth.c:1.3 src/external/bsd/dhcpcd/dist/auth.c:1.4
--- src/external/bsd/dhcpcd/dist/auth.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/auth.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: auth.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: auth.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/auth.h
diff -u src/external/bsd/dhcpcd/dist/auth.h:1.3 src/external/bsd/dhcpcd/dist/auth.h:1.4
--- src/external/bsd/dhcpcd/dist/auth.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/auth.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: auth.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: auth.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/common.c
diff -u src/external/bsd/dhcpcd/dist/common.c:1.3 src/external/bsd/dhcpcd/dist/common.c:1.4
--- src/external/bsd/dhcpcd/dist/common.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/common.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: common.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: common.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/common.h
diff -u src/external/bsd/dhcpcd/dist/common.h:1.3 src/external/bsd/dhcpcd/dist/common.h:1.4
--- src/external/bsd/dhcpcd/dist/common.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/common.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: common.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: common.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/config.h
diff -u src/external/bsd/dhcpcd/dist/config.h:1.3 src/external/bsd/dhcpcd/dist/config.h:1.4
--- src/external/bsd/dhcpcd/dist/config.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/config.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: config.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: config.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/* netbsd */
#define SYSCONFDIR "/etc"
Index: src/external/bsd/dhcpcd/dist/control.c
diff -u src/external/bsd/dhcpcd/dist/control.c:1.3 src/external/bsd/dhcpcd/dist/control.c:1.4
--- src/external/bsd/dhcpcd/dist/control.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/control.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: control.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: control.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/control.h
diff -u src/external/bsd/dhcpcd/dist/control.h:1.3 src/external/bsd/dhcpcd/dist/control.h:1.4
--- src/external/bsd/dhcpcd/dist/control.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/control.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: control.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: control.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.3 src/external/bsd/dhcpcd/dist/defs.h:1.4
--- src/external/bsd/dhcpcd/dist/defs.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/defs.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: defs.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
-#define VERSION "6.5.1"
+#define VERSION "6.6.0"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
Index: src/external/bsd/dhcpcd/dist/dev.h
diff -u src/external/bsd/dhcpcd/dist/dev.h:1.3 src/external/bsd/dhcpcd/dist/dev.h:1.4
--- src/external/bsd/dhcpcd/dist/dev.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dev.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dev.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: dev.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcp-common.c
diff -u src/external/bsd/dhcpcd/dist/dhcp-common.c:1.3 src/external/bsd/dhcpcd/dist/dhcp-common.c:1.4
--- src/external/bsd/dhcpcd/dist/dhcp-common.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcp-common.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp-common.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: dhcp-common.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcp-common.h
diff -u src/external/bsd/dhcpcd/dist/dhcp-common.h:1.3 src/external/bsd/dhcpcd/dist/dhcp-common.h:1.4
--- src/external/bsd/dhcpcd/dist/dhcp-common.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcp-common.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp-common.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: dhcp-common.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcp.h
diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.3 src/external/bsd/dhcpcd/dist/dhcp.h:1.4
--- src/external/bsd/dhcpcd/dist/dhcp.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcp.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: dhcp.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -36,6 +36,7 @@
#include <limits.h>
#include <stdint.h>
+#include "arp.h"
#include "auth.h"
#include "dhcp-common.h"
@@ -68,7 +69,6 @@
#define DHCP_MAX 64
#define DHCP_RAND_MIN -1
#define DHCP_RAND_MAX 1
-#define DHCP_ARP_FAIL 2
#ifdef RFC2131_STRICT
/* Be strictly conformant for section 4.1.1 */
@@ -198,7 +198,7 @@ enum DHS {
DHS_REBOOT,
DHS_INFORM,
DHS_RENEW_REQUESTED,
- DHS_INIT_IPV4LL,
+ DHS_IPV4LL_BOUND,
DHS_PROBE
};
@@ -214,12 +214,6 @@ struct dhcp_state {
time_t nakoff;
uint32_t xid;
int socket;
- int probes;
- int claims;
- int conflicts;
- time_t defend;
- struct in_addr fail;
- size_t arping_index;
int raw_fd;
int arp_fd;
@@ -237,6 +231,14 @@ struct dhcp_state {
unsigned char *clientid;
struct authstate auth;
+ struct arp_statehead arp_states;
+
+ size_t arping_index;
+
+ struct arp_state *arp_ipv4ll;
+ unsigned int conflicts;
+ time_t defend;
+ char randomstate[128];
};
#define D_STATE(ifp) \
@@ -283,7 +285,8 @@ void dhcp_stop(struct interface *);
void dhcp_decline(struct interface *);
void dhcp_discover(void *);
void dhcp_inform(struct interface *);
-void dhcp_bind(void *);
+void dhcp_probe(struct interface *);
+void dhcp_bind(struct interface *, struct arp_state *);
void dhcp_reboot_newopts(struct interface *, unsigned long long);
void dhcp_close(struct interface *);
void dhcp_free(struct interface *);
Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.3 src/external/bsd/dhcpcd/dist/dhcp6.c:1.4
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcp6.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcp6.h
diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.3 src/external/bsd/dhcpcd/dist/dhcp6.h:1.4
--- src/external/bsd/dhcpcd/dist/dhcp6.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcp6.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp6.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: dhcp6.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.3 src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.4
--- src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-# $NetBSD: dhcpcd-definitions.conf,v 1.3 2014/10/17 23:42:24 roy Exp $
+# $NetBSD: dhcpcd-definitions.conf,v 1.4 2014/10/29 01:08:31 roy Exp $
# Copyright (c) 2006-2014 Roy Marples
# All rights reserved
Index: src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.3 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.4
--- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* DO NOT EDIT
Index: src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.3 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.4
--- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd-embedded.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: dhcpcd-embedded.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.3 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.4
--- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#!/bin/sh
-# $NetBSD: dhcpcd-run-hooks.in,v 1.3 2014/10/17 23:42:24 roy Exp $
+# $NetBSD: dhcpcd-run-hooks.in,v 1.4 2014/10/29 01:08:31 roy Exp $
# dhcpcd client configuration script
Index: src/external/bsd/dhcpcd/dist/dhcpcd.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.3 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.4
--- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: dhcpcd.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/duid.c
diff -u src/external/bsd/dhcpcd/dist/duid.c:1.3 src/external/bsd/dhcpcd/dist/duid.c:1.4
--- src/external/bsd/dhcpcd/dist/duid.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/duid.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: duid.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: duid.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/duid.h
diff -u src/external/bsd/dhcpcd/dist/duid.h:1.3 src/external/bsd/dhcpcd/dist/duid.h:1.4
--- src/external/bsd/dhcpcd/dist/duid.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/duid.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: duid.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: duid.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/eloop.c
diff -u src/external/bsd/dhcpcd/dist/eloop.c:1.3 src/external/bsd/dhcpcd/dist/eloop.c:1.4
--- src/external/bsd/dhcpcd/dist/eloop.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/eloop.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: eloop.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: eloop.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/eloop.h
diff -u src/external/bsd/dhcpcd/dist/eloop.h:1.3 src/external/bsd/dhcpcd/dist/eloop.h:1.4
--- src/external/bsd/dhcpcd/dist/eloop.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/eloop.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: eloop.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: eloop.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/if-options.h
diff -u src/external/bsd/dhcpcd/dist/if-options.h:1.3 src/external/bsd/dhcpcd/dist/if-options.h:1.4
--- src/external/bsd/dhcpcd/dist/if-options.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/if-options.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: if-options.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: if-options.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -65,6 +65,7 @@
#define DHCPCD_LASTLEASE (1ULL << 7)
#define DHCPCD_INFORM (1ULL << 8)
#define DHCPCD_REQUEST (1ULL << 9)
+
#define DHCPCD_IPV4LL (1ULL << 10)
#define DHCPCD_DUID (1ULL << 11)
#define DHCPCD_PERSISTENT (1ULL << 12)
@@ -78,7 +79,7 @@
#define DHCPCD_QUIET (1ULL << 21)
#define DHCPCD_BACKGROUND (1ULL << 22)
#define DHCPCD_VENDORRAW (1ULL << 23)
-#define DHCPCD_TIMEOUT_IPV4LL (1ULL << 24)
+#define DHCPCD_NOWAITIP (1ULL << 24) /* To force daemonise */
#define DHCPCD_WAITIP (1ULL << 25)
#define DHCPCD_SLAACPRIVATE (1ULL << 26)
#define DHCPCD_CSR_WARNED (1ULL << 27)
Index: src/external/bsd/dhcpcd/dist/if.c
diff -u src/external/bsd/dhcpcd/dist/if.c:1.3 src/external/bsd/dhcpcd/dist/if.c:1.4
--- src/external/bsd/dhcpcd/dist/if.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/if.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: if.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/if.h
diff -u src/external/bsd/dhcpcd/dist/if.h:1.3 src/external/bsd/dhcpcd/dist/if.h:1.4
--- src/external/bsd/dhcpcd/dist/if.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/if.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: if.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.3 src/external/bsd/dhcpcd/dist/ipv4.c:1.4
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv4.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -136,6 +136,22 @@ ipv4_iffindaddr(struct interface *ifp,
}
struct ipv4_addr *
+ipv4_iffindlladdr(struct interface *ifp)
+{
+ struct ipv4_state *state;
+ struct ipv4_addr *ap;
+
+ state = IPV4_STATE(ifp);
+ if (state) {
+ TAILQ_FOREACH(ap, &state->addrs, next) {
+ if (IN_LINKLOCAL(htonl(ap->addr.s_addr)))
+ return ap;
+ }
+ }
+ return NULL;
+}
+
+struct ipv4_addr *
ipv4_findaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
{
struct interface *ifp;
@@ -770,10 +786,7 @@ ipv4_applyaddr(void *arg)
if (ifn->options->options &
DHCPCD_ARP)
{
- nstate->claims = 0;
- nstate->probes = 0;
- nstate->conflicts = 0;
- arp_probe(ifn);
+ dhcp_bind(ifn, NULL);
} else {
ipv4_addaddr(ifn,
&nstate->lease);
@@ -855,6 +868,7 @@ ipv4_applyaddr(void *arg)
delete_address(ifp);
state->added = 1;
+ state->defend = 0;
state->addr.s_addr = lease->addr.s_addr;
state->net.s_addr = lease->net.s_addr;
Index: src/external/bsd/dhcpcd/dist/ipv4.h
diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.3 src/external/bsd/dhcpcd/dist/ipv4.h:1.4
--- src/external/bsd/dhcpcd/dist/ipv4.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv4.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: ipv4.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -74,6 +74,7 @@ int ipv4_routedeleted(struct dhcpcd_ctx
struct ipv4_addr *ipv4_iffindaddr(struct interface *,
const struct in_addr *, const struct in_addr *);
+struct ipv4_addr *ipv4_iffindlladdr(struct interface *);
struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *,
const struct in_addr *, const struct in_addr *, const struct in_addr *);
Index: src/external/bsd/dhcpcd/dist/ipv4ll.c
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.3 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.4
--- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv4ll.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4ll.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: ipv4ll.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -35,7 +35,7 @@
#include <syslog.h>
#include <unistd.h>
-#define ELOOP_QUEUE 2
+#define ELOOP_QUEUE 6
#include "config.h"
#include "arp.h"
#include "common.h"
@@ -73,101 +73,183 @@ ipv4ll_make_lease(uint32_t addr)
return dhcp;
}
-static struct dhcp_message *
-ipv4ll_find_lease(uint32_t old_addr)
+static in_addr_t
+ipv4ll_pick_addr(const struct arp_state *astate)
{
- uint32_t addr;
+ in_addr_t addr;
+ struct interface *ifp;
+ const struct dhcp_state *state;
for (;;) {
- addr = htonl(LINKLOCAL_ADDR |
- (uint32_t)(abs((int)arc4random_uniform(0xFD00)) + 0x0100));
- if (addr != old_addr &&
- IN_LINKLOCAL(ntohl(addr)))
+ /* RFC 3927 Section 2.1 states that the first 256 and
+ * last 256 addresses are reserved for future use.
+ * See ipv4ll_start for why we don't use arc4_random. */
+ addr = ntohl(LINKLOCAL_ADDR | ((random() % 0xFD00) + 0x0100));
+
+ /* No point using a failed address */
+ if (addr == astate->failed.s_addr)
+ continue;
+
+ state = D_CSTATE(astate->iface);
+ /* Ensure we don't have the address on another interface */
+ TAILQ_FOREACH(ifp, astate->iface->ctx->ifaces, next) {
+ state = D_CSTATE(ifp);
+ if (state && state->addr.s_addr == addr)
+ break;
+ }
+
+ /* Yay, this should be a unique and workable IPv4LL address */
+ if (ifp == NULL)
break;
}
- return ipv4ll_make_lease(addr);
+ return addr;
}
-void
-ipv4ll_start(void *arg)
+static void
+ipv4ll_probed(struct arp_state *astate)
{
- struct interface *ifp = arg;
- struct dhcp_state *state = D_STATE(ifp);
- uint32_t addr;
+ struct dhcp_state *state = D_STATE(astate->iface);
- eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- 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;
- }
- }
-
- if (state->offer == NULL)
- addr = 0;
- else {
- addr = state->offer->yiaddr;
- free(state->offer);
- }
- /* We maybe rebooting an IPv4LL address. */
- if (!IN_LINKLOCAL(htonl(addr))) {
- syslog(LOG_INFO, "%s: probing for an IPv4LL address",
- ifp->name);
- addr = 0;
- }
- if (addr == 0)
- state->offer = ipv4ll_find_lease(addr);
- else
- state->offer = ipv4ll_make_lease(addr);
- if (state->offer == NULL)
+ free(state->offer);
+ state->offer = ipv4ll_make_lease(astate->addr.s_addr);
+ if (state->offer == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
- else {
- state->lease.frominfo = 0;
- arp_probe(ifp);
+ return;
}
+ dhcp_bind(astate->iface, astate);
}
-void
-ipv4ll_handle_failure(void *arg)
+static void
+ipv4ll_announced(struct arp_state *astate)
{
- struct interface *ifp = arg;
- struct dhcp_state *state = D_STATE(ifp);
- time_t up;
+ struct dhcp_state *state = D_STATE(astate->iface);
+
+ state->conflicts = 0;
+ /* Need to keep the arp state so we can defend our IP. */
+}
+
+static void
+ipv4ll_probe(void *arg)
+{
+
+ arp_probe(arg);
+}
+
+static void
+ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
+{
+ struct dhcp_state *state = D_STATE(astate->iface);
+ in_addr_t fail;
+
+ fail = 0;
+ /* RFC 3927 2.2.1, Probe Conflict Detection */
+ if (amsg->sip.s_addr == astate->addr.s_addr ||
+ (amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr))
+ fail = astate->addr.s_addr;
+
+ /* RFC 3927 2.5, Conflict Defense */
+ if (IN_LINKLOCAL(htonl(state->addr.s_addr)) &&
+ amsg->sip.s_addr == state->addr.s_addr)
+ fail = state->addr.s_addr;
+
+ if (fail == 0)
+ return;
+
+ astate->failed.s_addr = fail;
+ arp_report_conflicted(astate, amsg);
+
+ if (astate->failed.s_addr == state->addr.s_addr) {
+ time_t up;
- if (state->fail.s_addr == state->addr.s_addr) {
/* RFC 3927 Section 2.5 */
up = uptime();
if (state->defend + DEFEND_INTERVAL > up) {
syslog(LOG_WARNING,
- "%s: IPv4LL %d second defence failed",
- ifp->name, DEFEND_INTERVAL);
- dhcp_drop(ifp, "EXPIRE");
- state->conflicts = -1;
+ "%s: IPv4LL %d second defence failed for %s",
+ astate->iface->name, DEFEND_INTERVAL,
+ inet_ntoa(state->addr));
+ dhcp_drop(astate->iface, "EXPIRE");
} else {
- syslog(LOG_DEBUG, "%s: defended IPv4LL address",
- ifp->name);
+ syslog(LOG_DEBUG, "%s: defended IPv4LL address %s",
+ astate->iface->name, inet_ntoa(state->addr));
state->defend = up;
return;
}
}
- free(state->offer);
- state->offer = NULL;
- eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- if (++state->conflicts > MAX_CONFLICTS) {
+ arp_cancel(astate);
+ if (++state->conflicts == MAX_CONFLICTS)
syslog(LOG_ERR, "%s: failed to acquire an IPv4LL address",
- ifp->name);
- if (ifp->options->options & DHCPCD_DHCP) {
- state->interval = RATE_LIMIT_INTERVAL / 2;
- dhcp_discover(ifp);
+ astate->iface->name);
+ astate->addr.s_addr = ipv4ll_pick_addr(astate);
+ eloop_timeout_add_sec(astate->iface->ctx->eloop,
+ state->conflicts >= MAX_CONFLICTS ?
+ RATE_LIMIT_INTERVAL : PROBE_WAIT,
+ ipv4ll_probe, astate);
+}
+
+void
+ipv4ll_start(void *arg)
+{
+ struct interface *ifp = arg;
+ struct dhcp_state *state = D_STATE(ifp);
+ struct arp_state *astate;
+ struct ipv4_addr *ap;
+
+ if (state->arp_ipv4ll)
+ return;
+
+ /* RFC 3927 Section 2.1 states that the random number generator
+ * SHOULD be seeded with a value derived from persistent information
+ * such as the IEEE 802 MAC address so that it usually picks
+ * the same address without persistent storage. */
+ if (state->conflicts == 0) {
+ unsigned int seed;
+
+ if (sizeof(seed) > ifp->hwlen) {
+ seed = 0;
+ memcpy(&seed, ifp->hwaddr, ifp->hwlen);
} else
- eloop_timeout_add_sec(ifp->ctx->eloop,
- RATE_LIMIT_INTERVAL, ipv4ll_start, ifp);
- } else {
- eloop_timeout_add_sec(ifp->ctx->eloop,
- PROBE_WAIT, ipv4ll_start, ifp);
+ memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed),
+ sizeof(seed));
+ initstate(seed, state->randomstate, sizeof(state->randomstate));
+ }
+
+ if ((astate = arp_new(ifp)) == NULL)
+ return;
+
+ state->arp_ipv4ll = astate;
+ astate->probed_cb = ipv4ll_probed;
+ astate->announced_cb = ipv4ll_announced;
+ astate->conflicted_cb = ipv4ll_conflicted;
+
+ if (IN_LINKLOCAL(htonl(state->addr.s_addr))) {
+ astate->addr = state->addr;
+ arp_announce(astate);
+ return;
+ }
+
+ if (state->offer && IN_LINKLOCAL(ntohl(state->offer->yiaddr))) {
+ astate->addr.s_addr = state->offer->yiaddr;
+ free(state->offer);
+ state->offer = NULL;
+ ap = ipv4_iffindaddr(ifp, &astate->addr, NULL);
+ } else
+ ap = ipv4_iffindlladdr(ifp);
+ if (ap) {
+ astate->addr = ap->addr;
+ ipv4ll_probed(astate);
+ return;
+ }
+
+ setstate(state->randomstate);
+ /* We maybe rebooting an IPv4LL address. */
+ if (!IN_LINKLOCAL(htonl(astate->addr.s_addr))) {
+ syslog(LOG_INFO, "%s: probing for an IPv4LL address",
+ ifp->name);
+ astate->addr.s_addr = INADDR_ANY;
}
+ if (astate->addr.s_addr == INADDR_ANY)
+ astate->addr.s_addr = ipv4ll_pick_addr(astate);
+ arp_probe(astate);
}
Index: src/external/bsd/dhcpcd/dist/ipv4ll.h
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.h:1.3 src/external/bsd/dhcpcd/dist/ipv4ll.h:1.4
--- src/external/bsd/dhcpcd/dist/ipv4ll.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv4ll.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4ll.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: ipv4ll.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
@@ -31,6 +31,7 @@
#define IPV4LL_H
void ipv4ll_start(void *);
+void ipv4ll_claimed(void *);
void ipv4ll_handle_failure(void *);
#endif
Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.3 src/external/bsd/dhcpcd/dist/ipv6.c:1.4
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv6.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.4 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.3 src/external/bsd/dhcpcd/dist/ipv6.h:1.4
--- src/external/bsd/dhcpcd/dist/ipv6.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv6.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/ipv6nd.h
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.h:1.3 src/external/bsd/dhcpcd/dist/ipv6nd.h:1.4
--- src/external/bsd/dhcpcd/dist/ipv6nd.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6nd.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: ipv6nd.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/script.h
diff -u src/external/bsd/dhcpcd/dist/script.h:1.3 src/external/bsd/dhcpcd/dist/script.h:1.4
--- src/external/bsd/dhcpcd/dist/script.h:1.3 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/script.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: script.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: script.h,v 1.4 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/bpf-filter.h
diff -u src/external/bsd/dhcpcd/dist/bpf-filter.h:1.6 src/external/bsd/dhcpcd/dist/bpf-filter.h:1.7
--- src/external/bsd/dhcpcd/dist/bpf-filter.h:1.6 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/bpf-filter.h Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf-filter.h,v 1.6 2014/10/17 23:42:24 roy Exp $ */
+/* $NetBSD: bpf-filter.h,v 1.7 2014/10/29 01:08:31 roy Exp $ */
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.19 src/external/bsd/dhcpcd/dist/dhcp.c:1.20
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.19 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcp.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.19 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.20 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -1418,11 +1418,6 @@ dhcp_close(struct interface *ifp)
if (state == NULL)
return;
- if (state->arp_fd != -1) {
- eloop_event_delete(ifp->ctx->eloop, state->arp_fd, 0);
- close(state->arp_fd);
- state->arp_fd = -1;
- }
if (state->raw_fd != -1) {
eloop_event_delete(ifp->ctx->eloop, state->raw_fd, 0);
close(state->raw_fd);
@@ -1676,7 +1671,7 @@ send_message(struct interface *iface, ui
default:
if (!(iface->ctx->options & DHCPCD_TEST))
dhcp_drop(iface, "FAIL");
- dhcp_close(iface);
+ dhcp_free(iface);
eloop_timeout_delete(iface->ctx->eloop,
NULL, iface);
callback = NULL;
@@ -1738,16 +1733,13 @@ dhcp_discover(void *arg)
struct if_options *ifo = ifp->options;
time_t timeout = ifo->timeout;
- /* If we're rebooting and we're not daemonised then we need
- * to shorten the normal timeout to ensure we try correctly
- * for a fallback or IPv4LL address. */
- if (state->state == DHS_REBOOT &&
- !(ifp->ctx->options & DHCPCD_DAEMONISED))
- {
+ /* If we're rebooting then we need to shorten the normal timeout
+ * to ensure we try for a fallback or IPv4LL address. */
+ if (state->state == DHS_REBOOT) {
if (ifo->reboot >= timeout)
timeout = 2;
else
- timeout -= ifo->reboot;
+ timeout = ifo->reboot;
}
state->state = DHS_DISCOVER;
@@ -1758,12 +1750,8 @@ dhcp_discover(void *arg)
timeout, dhcp_fallback, ifp);
else if (ifo->options & DHCPCD_IPV4LL &&
!IN_LINKLOCAL(htonl(state->addr.s_addr)))
- {
- if (IN_LINKLOCAL(htonl(state->fail.s_addr)))
- timeout = RATE_LIMIT_INTERVAL;
eloop_timeout_add_sec(ifp->ctx->eloop,
timeout, ipv4ll_start, ifp);
- }
if (ifo->options & DHCPCD_REQUEST)
syslog(LOG_INFO, "%s: soliciting a DHCP lease (requesting %s)",
ifp->name, inet_ntoa(ifo->req_addr));
@@ -1792,7 +1780,6 @@ dhcp_expire(void *arg)
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
dhcp_drop(ifp, "EXPIRE");
unlink(state->leasefile);
-
state->interval = 0;
dhcp_discover(ifp);
}
@@ -1823,6 +1810,13 @@ dhcp_renew(void *arg)
}
static void
+dhcp_arp_announced(struct arp_state *astate)
+{
+
+ arp_close(astate->iface);
+}
+
+static void
dhcp_rebind(void *arg)
{
struct interface *ifp = arg;
@@ -1841,9 +1835,8 @@ dhcp_rebind(void *arg)
}
void
-dhcp_bind(void *arg)
+dhcp_bind(struct interface *ifp, struct arp_state *astate)
{
- struct interface *ifp = arg;
struct dhcp_state *state = D_STATE(ifp);
struct if_options *ifo = ifp->options;
struct dhcp_lease *lease = &state->lease;
@@ -1853,7 +1846,6 @@ dhcp_bind(void *arg)
if (state->state == DHS_BOUND)
goto applyaddr;
state->reason = NULL;
- state->xid = 0;
free(state->old);
state->old = state->new;
state->new = state->offer;
@@ -1933,7 +1925,7 @@ dhcp_bind(void *arg)
return;
}
if (state->reason == NULL) {
- if (state->old) {
+ if (state->old && state->new->cookie != htonl(MAGIC_COOKIE)) {
if (state->old->yiaddr == state->new->yiaddr &&
lease->server.s_addr)
state->reason = "RENEW";
@@ -1958,7 +1950,11 @@ dhcp_bind(void *arg)
" seconds",
ifp->name, lease->renewaltime, lease->rebindtime);
}
- state->state = DHS_BOUND;
+ if (!(ifo->options & DHCPCD_STATIC) &&
+ state->new->cookie != htonl(MAGIC_COOKIE))
+ state->state = DHS_IPV4LL_BOUND;
+ else
+ state->state = DHS_BOUND;
if (!state->lease.frominfo &&
!(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))
if (write_lease(ifp, state->new) == -1)
@@ -1966,14 +1962,23 @@ dhcp_bind(void *arg)
applyaddr:
ipv4_applyaddr(ifp);
- if (dhcpcd_daemonise(ifp->ctx) == 0) {
- if (!ipv4ll)
+ if (dhcpcd_daemonise(ifp->ctx))
+ return;
+ if (ifo->options & DHCPCD_ARP) {
+ if (state->added) {
+ if (astate == NULL) {
+ /* We don't care about what happens
+ * to the ARP announcement */
+ astate = arp_new(ifp);
+ astate->announced_cb =
+ dhcp_arp_announced;
+ }
+ if (astate) {
+ arp_announce(astate);
+ arp_free_but(astate);
+ }
+ } else if (!ipv4ll)
arp_close(ifp);
- if (ifo->options & DHCPCD_ARP) {
- state->claims = 0;
- if (state->added)
- arp_announce(ifp);
- }
}
}
@@ -1983,7 +1988,7 @@ dhcp_timeout(void *arg)
struct interface *ifp = arg;
struct dhcp_state *state = D_STATE(ifp);
- dhcp_bind(ifp);
+ dhcp_bind(ifp, NULL);
state->interval = 0;
dhcp_discover(ifp);
}
@@ -2029,7 +2034,7 @@ dhcp_static(struct interface *ifp)
state->offer = dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
if (state->offer) {
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- dhcp_bind(ifp);
+ dhcp_bind(ifp, NULL);
}
}
@@ -2065,7 +2070,7 @@ dhcp_inform(struct interface *ifp)
dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
if (state->offer) {
ifo->options |= DHCPCD_STATIC;
- dhcp_bind(ifp);
+ dhcp_bind(ifp, NULL);
ifo->options &= ~DHCPCD_STATIC;
}
}
@@ -2102,6 +2107,7 @@ dhcp_reboot(struct interface *ifp)
if (state == NULL)
return;
ifo = ifp->options;
+ state->state = DHS_REBOOT;
state->interval = 0;
if (ifo->options & DHCPCD_LINK && ifp->carrier == LINK_DOWN) {
@@ -2120,21 +2126,21 @@ dhcp_reboot(struct interface *ifp)
syslog(LOG_INFO, "%s: informing address of %s",
ifp->name, inet_ntoa(state->lease.addr));
} else if (state->offer->cookie == 0) {
- if (ifo->options & DHCPCD_IPV4LL) {
- state->claims = 0;
- if (state->added)
- arp_announce(ifp);
- } else
- dhcp_discover(ifp);
return;
} else {
syslog(LOG_INFO, "%s: rebinding lease of %s",
ifp->name, inet_ntoa(state->lease.addr));
}
- state->state = DHS_REBOOT;
state->xid = dhcp_xid(ifp);
state->lease.server.s_addr = 0;
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+
+ /* Need to add this before dhcp_expire and friends. */
+ if (!ifo->fallback && ifo->reboot && ifo->options & DHCPCD_IPV4LL &&
+ !IN_LINKLOCAL(htonl(state->addr.s_addr)))
+ eloop_timeout_add_sec(ifp->ctx->eloop,
+ ifo->reboot, ipv4ll_start, ifp);
+
if (ifo->fallback)
eloop_timeout_add_sec(ifp->ctx->eloop,
ifo->reboot, dhcp_fallback, ifp);
@@ -2162,16 +2168,19 @@ dhcp_drop(struct interface *ifp, const c
struct timespec ts;
#endif
+ state = D_STATE(ifp);
/* dhcp_start may just have been called and we don't yet have a state
* but we do have a timeout, so punt it. */
- eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
-
- state = D_STATE(ifp);
- if (state == NULL)
+ if (state == NULL) {
+ eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
return;
- dhcp_auth_reset(&state->auth);
- dhcp_close(ifp);
- arp_close(ifp);
+ }
+ /* Don't reset DHCP state if we have an IPv4LL address and link is up */
+ if (state->state != DHS_IPV4LL_BOUND || ifp->carrier != LINK_UP) {
+ eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+ dhcp_auth_reset(&state->auth);
+ dhcp_close(ifp);
+ }
if (ifp->options->options & DHCPCD_RELEASE) {
unlink(state->leasefile);
if (ifp->carrier != LINK_DOWN &&
@@ -2299,6 +2308,103 @@ whitelisted_ip(const struct if_options *
}
static void
+dhcp_arp_probed(struct arp_state *astate)
+{
+ struct dhcp_state *state;
+ struct if_options *ifo;
+
+ /* We didn't find a profile for this
+ * address or hwaddr, so move to the next
+ * arping profile */
+ state = D_STATE(astate->iface);
+ ifo = astate->iface->options;
+ if (state->arping_index < ifo->arping_len) {
+ if (++state->arping_index < ifo->arping_len) {
+ astate->addr.s_addr =
+ ifo->arping[state->arping_index - 1];
+ arp_probe(astate);
+ }
+ dhcpcd_startinterface(astate->iface);
+ return;
+ }
+ dhcp_close(astate->iface);
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate->iface);
+ dhcp_bind(astate->iface, astate);
+}
+
+static void
+dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
+{
+ struct dhcp_state *state;
+ struct if_options *ifo;
+
+ state = D_STATE(astate->iface);
+ ifo = astate->iface->options;
+ if (state->arping_index &&
+ state->arping_index <= ifo->arping_len &&
+ (amsg->sip.s_addr == ifo->arping[state->arping_index - 1] ||
+ (amsg->sip.s_addr == 0 &&
+ amsg->tip.s_addr == ifo->arping[state->arping_index - 1])))
+ {
+ char buf[HWADDR_LEN * 3];
+
+ astate->failed.s_addr = ifo->arping[state->arping_index - 1];
+ arp_report_conflicted(astate, amsg);
+ hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf));
+ if (dhcpcd_selectprofile(astate->iface, buf) == -1 &&
+ dhcpcd_selectprofile(astate->iface,
+ inet_ntoa(astate->failed)) == -1)
+ {
+ /* We didn't find a profile for this
+ * address or hwaddr, so move to the next
+ * arping profile */
+ dhcp_arp_probed(astate);
+ return;
+ }
+ dhcp_close(astate->iface);
+ arp_close(astate->iface);
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
+ astate->iface);
+ dhcpcd_startinterface(astate->iface);
+ }
+
+ if (state->offer == NULL)
+ return;
+
+ /* RFC 2131 3.1.5, Client-server interaction */
+ if (amsg->sip.s_addr == state->offer->yiaddr ||
+ (amsg->sip.s_addr == 0 && amsg->tip.s_addr == state->offer->yiaddr))
+ {
+ astate->failed.s_addr = state->offer->yiaddr;
+ arp_report_conflicted(astate, amsg);
+ unlink(state->leasefile);
+ if (!state->lease.frominfo)
+ dhcp_decline(astate->iface);
+ eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
+ astate->iface);
+ eloop_timeout_add_sec(astate->iface->ctx->eloop,
+ DHCP_RAND_MAX, dhcp_discover, astate->iface);
+ }
+}
+
+void
+dhcp_probe(struct interface *ifp)
+{
+ const struct dhcp_state *state;
+ struct arp_state *astate;
+
+ astate = arp_new(ifp);
+ if (astate) {
+ state = D_CSTATE(ifp);
+ astate->addr = state->addr;
+ astate->probed_cb = dhcp_arp_probed;
+ astate->conflicted_cb = dhcp_arp_conflicted;
+ astate->announced_cb = dhcp_arp_announced;
+ arp_probe(astate);
+ }
+}
+
+static void
dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp,
const struct in_addr *from)
{
@@ -2438,7 +2544,8 @@ dhcp_handledhcp(struct interface *iface,
iface->name, msg);
free(msg);
}
- if (state->state == DHS_DISCOVER &&
+ if ((state->state == DHS_DISCOVER ||
+ state->state == DHS_IPV4LL_BOUND) &&
get_option_uint8(iface->ctx, &tmp, dhcp,
DHO_AUTOCONFIGURE) == 0)
{
@@ -2446,7 +2553,8 @@ dhcp_handledhcp(struct interface *iface,
case 0:
log_dhcp(LOG_WARNING, "IPv4LL disabled from",
iface, dhcp, from);
- dhcp_close(iface);
+ dhcp_drop(iface, "EXPIRE");
+ arp_close(iface);
eloop_timeout_delete(iface->ctx->eloop,
NULL, iface);
eloop_timeout_add_sec(iface->ctx->eloop,
@@ -2499,7 +2607,7 @@ dhcp_handledhcp(struct interface *iface,
}
if ((type == 0 || type == DHCP_OFFER) &&
- state->state == DHS_DISCOVER)
+ (state->state == DHS_DISCOVER || state->state == DHS_IPV4LL_BOUND))
{
lease->frominfo = 0;
lease->addr.s_addr = dhcp->yiaddr;
@@ -2580,15 +2688,20 @@ dhcp_handledhcp(struct interface *iface,
* then we can't ARP for duplicate detection. */
addr.s_addr = state->offer->yiaddr;
if (!ipv4_iffindaddr(iface, &addr, NULL)) {
- state->claims = 0;
- state->probes = 0;
- state->conflicts = 0;
- arp_probe(iface);
+ struct arp_state *astate;
+
+ astate = arp_new(iface);
+ if (astate) {
+ astate->addr = addr;
+ astate->probed_cb = dhcp_arp_probed;
+ astate->conflicted_cb = dhcp_arp_conflicted;
+ arp_probe(astate);
+ }
return;
}
}
- dhcp_bind(iface);
+ dhcp_bind(iface, NULL);
}
static size_t
@@ -2672,6 +2785,7 @@ dhcp_handlepacket(void *arg)
syslog(LOG_ERR, "%s: dhcp if_readrawpacket: %m",
ifp->name);
dhcp_close(ifp);
+ arp_close(ifp);
break;
}
if (valid_udp_packet(ifp->ctx->packet, bytes,
@@ -2793,6 +2907,8 @@ dhcp_dump(struct interface *ifp)
ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
if (state == NULL)
goto eexit;
+ state->raw_fd = state->arp_fd = -1;
+ TAILQ_INIT(&state->arp_states);
snprintf(state->leasefile, sizeof(state->leasefile),
LEASEFILE, ifp->name);
state->new = read_lease(ifp);
@@ -2819,6 +2935,8 @@ dhcp_free(struct interface *ifp)
struct dhcp_state *state = D_STATE(ifp);
struct dhcpcd_ctx *ctx;
+ dhcp_close(ifp);
+ arp_close(ifp);
if (state) {
free(state->old);
free(state->new);
@@ -2868,6 +2986,7 @@ dhcp_init(struct interface *ifp)
return -1;
/* 0 is a valid fd, so init to -1 */
state->raw_fd = state->arp_fd = -1;
+ TAILQ_INIT(&state->arp_states);
}
state->state = DHS_INIT;
@@ -2963,16 +3082,20 @@ dhcp_start1(void *arg)
return;
}
- /* Close any pre-existing sockets as we're starting over */
- dhcp_close(ifp);
-
state = D_STATE(ifp);
state->start_uptime = uptime();
free(state->offer);
state->offer = NULL;
if (state->arping_index < ifo->arping_len) {
- arp_start(ifp);
+ struct arp_state *astate;
+
+ astate = arp_new(ifp);
+ if (astate) {
+ astate->probed_cb = dhcp_arp_probed;
+ astate->conflicted_cb = dhcp_arp_conflicted;
+ dhcp_arp_probed(astate);
+ }
return;
}
@@ -3041,11 +3164,13 @@ dhcp_start1(void *arg)
return;
}
- if (state->offer == NULL)
+ if (state->offer == NULL || state->offer->cookie == 0) {
+ /* If we don't have an address yet, enter the reboot
+ * state to ensure at least fallback in short order. */
+ if (state->addr.s_addr == INADDR_ANY)
+ state->state = DHS_REBOOT;
dhcp_discover(ifp);
- else if (state->offer->cookie == 0 && ifo->options & DHCPCD_IPV4LL)
- ipv4ll_start(ifp);
- else
+ } else
dhcp_reboot(ifp);
}
Index: src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.9 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.10
--- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.9 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.9 2014/10/17 23:42:24 roy Exp $
+.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.10 2014/10/29 01:08:31 roy Exp $
.\" Copyright (c) 2006-2014 Roy Marples
.\" All rights reserved
.\"
Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.33 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.34
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.33 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd.8.in,v 1.33 2014/10/17 23:42:24 roy Exp $
+.\" $NetBSD: dhcpcd.8.in,v 1.34 2014/10/29 01:08:31 roy Exp $
.\" Copyright (c) 2006-2014 Roy Marples
.\" All rights reserved
.\"
Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.13 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.14
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.13 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.13 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.14 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -188,28 +188,15 @@ static void
handle_exit_timeout(void *arg)
{
struct dhcpcd_ctx *ctx;
- int timeout;
ctx = arg;
syslog(LOG_ERR, "timed out");
- if (!(ctx->options & DHCPCD_IPV4) ||
- !(ctx->options & DHCPCD_TIMEOUT_IPV4LL))
- {
- if (ctx->options & DHCPCD_MASTER) {
- /* We've timed out, so remove the waitip requirements.
- * If the user doesn't like this they can always set
- * an infinite timeout. */
- ctx->options &=
- ~(DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6);
- dhcpcd_daemonise(ctx);
- } else
- eloop_exit(ctx->eloop, EXIT_FAILURE);
+ if (!(ctx->options & DHCPCD_MASTER)) {
+ eloop_exit(ctx->eloop, EXIT_FAILURE);
return;
}
- ctx->options &= ~DHCPCD_TIMEOUT_IPV4LL;
- timeout = (PROBE_NUM * PROBE_MAX) + (PROBE_WAIT * 2) + DHCP_MAX_DELAY;
- syslog(LOG_WARNING, "allowing %d seconds for IPv4LL timeout", timeout);
- eloop_timeout_add_sec(ctx->eloop, timeout, handle_exit_timeout, ctx);
+ ctx->options |= DHCPCD_NOWAITIP;
+ dhcpcd_daemonise(ctx);
}
int
@@ -260,7 +247,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
int sidpipe[2], fd;
if (ctx->options & DHCPCD_DAEMONISE &&
- !(ctx->options & DHCPCD_DAEMONISED))
+ !(ctx->options & (DHCPCD_DAEMONISED | DHCPCD_NOWAITIP)))
{
if (!dhcpcd_ipwaited(ctx))
return 0;
@@ -329,6 +316,7 @@ stop_interface(struct interface *ifp)
dhcp6_drop(ifp, NULL);
ipv6nd_drop(ifp);
dhcp_drop(ifp, "STOP");
+ arp_close(ifp);
eloop_timeout_delete(ctx->eloop, NULL, ifp);
if (ifp->options->options & DHCPCD_DEPARTED)
script_runreason(ifp, "DEPARTED");
@@ -371,14 +359,20 @@ configure_interface1(struct interface *i
if (ifo->metric != -1)
ifp->metric = (unsigned int)ifo->metric;
+ if (!(ifo->options & DHCPCD_IPV4))
+ ifo->options &= ~(DHCPCD_DHCP | DHCPCD_IPV4LL);
+
if (!(ifo->options & DHCPCD_IPV6))
- ifo->options &= ~DHCPCD_IPV6RS;
+ ifo->options &= ~(DHCPCD_IPV6RS | DHCPCD_DHCP6);
if (ifo->options & DHCPCD_SLAACPRIVATE)
ifo->options |= DHCPCD_IPV6RA_OWN;
/* We want to disable kernel interface RA as early as possible. */
if (ifo->options & DHCPCD_IPV6RS) {
+ /* If not doing any DHCP, disable the RDNSS requirement. */
+ if (!(ifo->options & (DHCPCD_DHCP | DHCPCD_DHCP6)))
+ ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS;
ra_global = if_checkipv6(ifp->ctx, NULL,
ifp->ctx->options & DHCPCD_IPV6RA_OWN ? 1 : 0);
ra_iface = if_checkipv6(ifp->ctx, ifp,
@@ -574,6 +568,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
* do nothing. */
ipv6_free_ll_callbacks(ifp);
dhcp_drop(ifp, "EXPIRE");
+ arp_close(ifp);
}
} else if (carrier == LINK_UP && ifp->flags & IFF_UP) {
if (ifp->carrier != LINK_UP) {
@@ -1706,8 +1701,6 @@ main(int argc, char **argv)
if (dhcpcd_daemonise(&ctx))
goto exit_success;
} else if (t > 0) {
- if (ctx.options & DHCPCD_IPV4LL)
- ctx.options |= DHCPCD_TIMEOUT_IPV4LL;
eloop_timeout_add_sec(ctx.eloop, t,
handle_exit_timeout, &ctx);
}
Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.13 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.14
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.13 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-.\" $NetBSD: dhcpcd.conf.5.in,v 1.13 2014/10/17 23:42:24 roy Exp $
+.\" $NetBSD: dhcpcd.conf.5.in,v 1.14 2014/10/29 01:08:31 roy Exp $
.\" Copyright (c) 2006-2014 Roy Marples
.\" All rights reserved
.\"
@@ -456,7 +456,8 @@ Suppress any dhcpcd output to the consol
.It Ic reboot Ar seconds
Allow
.Ar reboot
-seconds before moving to the DISCOVER phase if we have an old lease to use.
+seconds before moving to the DISCOVER phase if we have an old lease to use
+and moving from DISCOVER to IPv4LL if no reply.
The default is 5 seconds.
A setting of 0 seconds causes
.Nm dhcpcd
Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.12 src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.13
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.12 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf Wed Oct 29 01:08:31 2014
@@ -1,4 +1,4 @@
-# $NetBSD: dhcpcd.conf,v 1.12 2014/10/17 23:42:24 roy Exp $
+# $NetBSD: dhcpcd.conf,v 1.13 2014/10/29 01:08:31 roy Exp $
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.
Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.12 src/external/bsd/dhcpcd/dist/if-bsd.c:1.13
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.12 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/if-bsd.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.12 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.13 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.14 src/external/bsd/dhcpcd/dist/if-options.c:1.15
--- src/external/bsd/dhcpcd/dist/if-options.c:1.14 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/if-options.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.14 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.15 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.14 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.15
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.14 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.14 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.15 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -1610,7 +1610,7 @@ ipv6nd_startrs(struct interface *ifp)
MAX_RTR_SOLICITATION_DELAY * 1000000);
timernorm(&tv);
syslog(LOG_DEBUG,
- "%s: delaying IPv6 router solictation for %0.1f seconds",
+ "%s: delaying IPv6 router solicitation for %0.1f seconds",
ifp->name, timeval_to_double(&tv));
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp);
return;
Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.11 src/external/bsd/dhcpcd/dist/script.c:1.12
--- src/external/bsd/dhcpcd/dist/script.c:1.11 Fri Oct 17 23:42:24 2014
+++ src/external/bsd/dhcpcd/dist/script.c Wed Oct 29 01:08:31 2014
@@ -1,5 +1,5 @@
#include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.11 2014/10/17 23:42:24 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.12 2014/10/29 01:08:31 roy Exp $");
/*
* dhcpcd - DHCP client daemon
@@ -338,7 +338,11 @@ make_env(const struct interface *ifp, co
}
}
*--p = '\0';
- if (strcmp(reason, "TEST") == 0) {
+ if (strcmp(reason, "TEST") == 0 ||
+ strcmp(reason, "PREINIT") == 0 ||
+ strcmp(reason, "CARRIER") == 0 ||
+ strcmp(reason, "UNKNOWN") == 0)
+ {
env[9] = strdup("if_up=false");
env[10] = strdup("if_down=false");
} else if (1 == 2 /* appease ifdefs */