Import dhcpcd-6.3.2 with the following changes: trunk
authorroy <roy@NetBSD.org>
Fri, 14 Mar 2014 11:27:36 +0000
branchtrunk
changeset 225535 f0fcba9d6b16
parent 225534 f724a0c6933b
child 225536 52a1e76c99b3
Import dhcpcd-6.3.2 with the following changes: * Improvements to autoconf build emulation * CARRIER/NOCARRIER are now run outside of the IPv4 runs * validate domains correctly which contain a - on non bash shells * don't remove IPv6 addresses from internal state when added as tentative * HUP now rebinds, ALRM now releases - the -x and -k flags work as they used to * Add -M, --master option to force dhcpcd into master mode even if one interface is specified on the command line * Fix a crash when receiving a reconfigure key * Dumping a DHCPv4 lease works again * SEND_DAD code removed * hoplimit is no longer defined for DHCPv6 messages * hoplimit of 255 for IPv6 RS/ND message is now defined at the socket instead of ancillary data with the message
external/bsd/dhcpcd/dist/auth.c
external/bsd/dhcpcd/dist/bpf.c
external/bsd/dhcpcd/dist/defs.h
external/bsd/dhcpcd/dist/dhcp.h
external/bsd/dhcpcd/dist/dhcp6.c
external/bsd/dhcpcd/dist/dhcpcd-embedded.c
external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test
external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump
external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf
external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in
external/bsd/dhcpcd/dist/if-options.h
external/bsd/dhcpcd/dist/ipv4.c
external/bsd/dhcpcd/dist/ipv6.c
external/bsd/dhcpcd/dist/ipv6.h
external/bsd/dhcpcd/dist/ipv6nd.h
external/bsd/dhcpcd/dist/net.h
external/bsd/dhcpcd/dist/platform-bsd.c
--- a/external/bsd/dhcpcd/dist/auth.c	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/auth.c	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: auth.c,v 1.1.1.2 2014/03/01 11:00:43 roy Exp $");
+ __RCSID("$NetBSD: auth.c,v 1.1.1.3 2014/03/14 11:27:37 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -142,8 +142,14 @@
 		    algorithm != auth->algorithm ||
 		    rdm != auth->rdm)
 	{
-		errno = EPERM;
-		return NULL;
+		/* As we don't require authentication, we should still
+		 * accept a reconfigure key */
+		if (protocol != AUTH_PROTO_RECONFKEY ||
+		    auth->options & DHCPCD_AUTH_REQUIRE)
+		{
+			errno = EPERM;
+			return NULL;
+		}
 	}
 	dlen -= 3;
 
@@ -234,6 +240,11 @@
 			}
 			if (state->reconf == NULL)
 				errno = ENOENT;
+			/* Free the old token so we log acceptance */
+			if (state->token) {
+				free(state->token);
+				state->token = NULL;
+			}
 			/* Nothing to validate, just accepting the key */
 			return state->reconf;
 		case 2:
--- a/external/bsd/dhcpcd/dist/bpf.c	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/bpf.c	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: bpf.c,v 1.1.1.8 2014/02/25 13:14:29 roy Exp $");
+ __RCSID("$NetBSD: bpf.c,v 1.1.1.9 2014/03/14 11:27:36 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -122,6 +122,14 @@
 	}
 	if (ioctl(fd, BIOCSETF, &pf) == -1)
 		goto eexit;
+
+#ifdef __OpenBSD__
+	/* For some reason OpenBSD fails to open the fd as non blocking */
+	if ((flags = fcntl(fd, F_GETFL, 0)) == -1 ||
+	    fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
+		goto eexit;
+#endif
+
 	return fd;
 
 eexit:
--- a/external/bsd/dhcpcd/dist/defs.h	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/defs.h	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.1.1.36 2014/03/01 11:00:43 roy Exp $ */
+/* $NetBSD: defs.h,v 1.1.1.37 2014/03/14 11:27:38 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
 #define CONFIG_H
 
 #define PACKAGE			"dhcpcd"
-#define VERSION			"6.3.1"
+#define VERSION			"6.3.2"
 
 #ifndef CONFIG
 # define CONFIG			SYSCONFDIR "/" PACKAGE ".conf"
--- a/external/bsd/dhcpcd/dist/dhcp.h	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/dhcp.h	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp.h,v 1.1.1.17 2014/02/25 13:14:30 roy Exp $ */
+/* $NetBSD: dhcp.h,v 1.1.1.18 2014/03/14 11:27:38 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -287,7 +287,7 @@
 void dhcp_reboot_newopts(struct interface *, int);
 void dhcp_close(struct interface *);
 void dhcp_free(struct interface *);
-int dhcp_dump(const char *);
+int dhcp_dump(struct dhcpcd_ctx *, const char *);
 #else
 #define dhcp_printoptions
 #define dhcp_drop(a, b)
--- a/external/bsd/dhcpcd/dist/dhcp6.c	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/dhcp6.c	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.1.1.8 2014/03/01 11:00:43 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.1.1.9 2014/03/14 11:27:37 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -85,6 +85,7 @@
 	{ DHCP6_CONFIRM, "CONFIRM6" },
 	{ DHCP6_INFORMATION_REQ, "INFORM6" },
 	{ DHCP6_RELEASE, "RELEASE6" },
+	{ DHCP6_RECONFIGURE, "RECONFIURE6" },
 	{ 0, NULL }
 };
 
@@ -706,7 +707,7 @@
 {
 	struct dhcp6_state *state;
 	struct ipv6_ctx *ctx;
-	struct sockaddr_in6 to;
+	struct sockaddr_in6 dst;
 	struct cmsghdr *cm;
 	struct in6_pktinfo pi;
 	struct timeval RTprev;
@@ -716,11 +717,11 @@
 	const char *broad_uni;
 	const struct in6_addr alldhcp = IN6ADDR_LINKLOCAL_ALLDHCP_INIT;
 
-	memset(&to, 0, sizeof(to));
-	to.sin6_family = AF_INET6;
-	to.sin6_port = htons(DHCP6_SERVER_PORT);
+	memset(&dst, 0, sizeof(dst));
+	dst.sin6_family = AF_INET6;
+	dst.sin6_port = htons(DHCP6_SERVER_PORT);
 #ifdef SIN6_LEN
-	to.sin6_len = sizeof(to);
+	dst.sin6_len = sizeof(dst);
 #endif
 
 	state = D6_STATE(ifp);
@@ -731,10 +732,10 @@
 	    (state->state == DH6S_REQUEST &&
 	    (!IN6_IS_ADDR_LINKLOCAL(&state->unicast) || !ipv6_linklocal(ifp))))
 	{
-		to.sin6_addr = alldhcp;
+		dst.sin6_addr = alldhcp;
 		broad_uni = "broadcasting";
 	} else {
-		to.sin6_addr = state->unicast;
+		dst.sin6_addr = state->unicast;
 		broad_uni = "unicasting";
 	}
 
@@ -831,8 +832,8 @@
 	}
 
 	ctx = ifp->ctx->ipv6;
-	to.sin6_scope_id = ifp->index;
-	ctx->sndhdr.msg_name = (caddr_t)&to;
+	dst.sin6_scope_id = ifp->index;
+	ctx->sndhdr.msg_name = (caddr_t)&dst;
 	ctx->sndhdr.msg_iov[0].iov_base = (caddr_t)state->send;
 	ctx->sndhdr.msg_iov[0].iov_len = state->send_len;
 
@@ -1261,17 +1262,12 @@
 	int wascompleted;
 
 	wascompleted = (ap->flags & IPV6_AF_DADCOMPLETED);
-	ipv6nd_cancelprobeaddr(ap);
 	ap->flags |= IPV6_AF_DADCOMPLETED;
 	if (ap->flags & IPV6_AF_DUPLICATED)
 		/* XXX FIXME
 		 * We should decline the address */
 		syslog(LOG_WARNING, "%s: DAD detected %s",
 		    ap->iface->name, ap->saddr);
-#ifdef IPV6_SEND_DAD
-	else
-		ipv6_addaddr(ap);
-#endif
 
 	if (!wascompleted) {
 		ifp = ap->iface;
@@ -1468,14 +1464,14 @@
 	const struct if_options *ifo;
 	const struct dhcp6_option *o;
 	const uint8_t *p;
-	int i;
+	int i, e;
 	uint32_t u32, renew, rebind;
 	uint8_t iaid[4];
 	size_t ol;
 	struct ipv6_addr *ap, *nap;
 
 	ifo = ifp->options;
-	i = 0;
+	i = e = 0;
 	state = D6_STATE(ifp);
 	TAILQ_FOREACH(ap, &state->addrs, next) {
 		ap->flags |= IPV6_AF_STALE;
@@ -1508,8 +1504,10 @@
 			ol -= sizeof(u32);
 		} else
 			renew = rebind = 0; /* appease gcc */
-		if (dhcp6_checkstatusok(ifp, NULL, p, ol) == -1)
+		if (dhcp6_checkstatusok(ifp, NULL, p, ol) == -1) {
+			e = 1;
 			continue;
+		}
 		if (ifo->ia_type == D6_OPTION_IA_PD) {
 			if (dhcp6_findpd(ifp, iaid, p, ol) == 0) {
 				syslog(LOG_WARNING,
@@ -1548,10 +1546,12 @@
 			TAILQ_REMOVE(&state->addrs, ap, next);
 			if (ap->dadcallback)
 				eloop_q_timeout_delete(ap->iface->ctx->eloop,
-				    0, NULL, ap->dadcallback);
+				    0, NULL, ap);
 			free(ap);
 		}
 	}
+	if (i == 0 && e)
+		return -1;
 	return i;
 }
 
@@ -1667,8 +1667,12 @@
 			    ifp->name);
 			goto ex;
 		}
-		syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
-		    ifp->name, state->auth.token->secretid);
+		if (state->auth.token)
+			syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
+			    ifp->name, state->auth.token->secretid);
+		else
+			syslog(LOG_DEBUG, "%s: accepted reconfigure key",
+			    ifp->name);
 	} else if (ifp->options->auth.options & DHCPCD_AUTH_REQUIRE) {
 		syslog(LOG_ERR, "%s: authentication now required", ifp->name);
 		goto ex;
@@ -1902,7 +1906,7 @@
 		}
 		if (k && !carrier_warned) {
 			ifd_state = D6_STATE(ifd);
-			ipv6nd_probeaddrs(&ifd_state->addrs);
+			ipv6_addaddrs(&ifd_state->addrs);
 		}
 	}
 
@@ -1982,7 +1986,7 @@
 		syslog(LOG_INFO, "%s: adding delegated prefixes", ifp->name);
 		state = D6_STATE(ifp);
 		state->state = DH6S_DELEGATED;
-		ipv6nd_probeaddrs(&state->addrs);
+		ipv6_addaddrs(&state->addrs);
 		ipv6_buildroutes(ifp->ctx);
 	}
 	return k;
@@ -2012,6 +2016,7 @@
 
 	dhcpcd_ctx = arg;
 	ctx = dhcpcd_ctx->ipv6;
+	ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
 	len = recvmsg(ctx->dhcp_fd, &ctx->rcvhdr, 0);
 	if (len == -1) {
 		syslog(LOG_ERR, "recvmsg: %m");
@@ -2063,10 +2068,13 @@
 		    ifp->name);
 		return;
 	}
+
+	r = (struct dhcp6_message *)ctx->rcvhdr.msg_iov[0].iov_base;
+
 	/* We're already bound and this message is for another machine */
 	/* XXX DELEGATED? */
-	if (state->state == DH6S_BOUND ||
-	    state->state == DH6S_INFORMED)
+	if (r->type != DHCP6_RECONFIGURE &&
+	    (state->state == DH6S_BOUND || state->state == DH6S_INFORMED))
 		return;
 
 	r = (struct dhcp6_message *)ctx->rcvhdr.msg_iov[0].iov_base;
@@ -2129,8 +2137,12 @@
 			    ifp->name, ctx->sfrom);
 			return;
 		}
-		syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
-		    ifp->name, state->auth.token->secretid);
+		if (state->auth.token)
+			syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
+			    ifp->name, state->auth.token->secretid);
+		else
+			syslog(LOG_DEBUG, "%s: accepted reconfigure key",
+			    ifp->name);
 	} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
 		syslog(LOG_ERR, "%s: no authentication from %s",
 		    ifp->name, ctx->sfrom);
@@ -2165,7 +2177,8 @@
 			if (error == 1)
 				goto recv;
 			if (error == -1 ||
-			    dhcp6_validatelease(ifp, r, len, ctx->sfrom) == -1){
+			    dhcp6_validatelease(ifp, r, len, ctx->sfrom) == -1)
+			{
 				dhcp6_startdiscover(ifp);
 				return;
 			}
@@ -2229,12 +2242,12 @@
 	case DHCP6_RECONFIGURE:
 		if (auth == NULL) {
 			syslog(LOG_ERR,
-			    "%s: unauthenticated Force Renew from %s",
-			    ifp->name, ctx->sfrom);
+			    "%s: unauthenticated %s from %s",
+			    ifp->name, op, ctx->sfrom);
 			return;
 		}
-		syslog(LOG_INFO, "%s: Force Renew from %s",
-		    ifp->name, ctx->sfrom);
+		syslog(LOG_INFO, "%s: %s from %s",
+		    ifp->name, op, ctx->sfrom);
 		o = dhcp6_getmoption(D6_OPTION_RECONF_MSG, r, len);
 		if (o == NULL) {
 			syslog(LOG_ERR,
@@ -2252,8 +2265,8 @@
 		case DHCP6_RENEW:
 			if (state->state != DH6S_BOUND) {
 				syslog(LOG_ERR,
-				    "%s: not bound, ignoring Force Renew",
-				    ifp->name);
+				    "%s: not bound, ignoring %s",
+				    ifp->name, op);
 				return;
 			}
 			eloop_timeout_delete(ifp->ctx->eloop,
@@ -2263,8 +2276,8 @@
 		case DHCP6_INFORMATION_REQ:
 			if (state->state != DH6S_INFORMED) {
 				syslog(LOG_ERR,
-				    "%s: not informed, ignoring Force Renew",
-				    ifp->name);
+				    "%s: not informed, ignoring %s",
+				    ifp->name, op);
 				return;
 			}
 			eloop_timeout_delete(ifp->ctx->eloop,
@@ -2273,11 +2286,11 @@
 			break;
 		default:
 			syslog(LOG_ERR,
-			    "%s: unsupported Reconfigure Message type",
-			    ifp->name);
-			return;
+			    "%s: unsupported %s type %d",
+			    ifp->name, op, *D6_COPTION_DATA(o));
+			break;
 		}
-		break;
+		return;
 	default:
 		syslog(LOG_ERR, "%s: invalid DHCP6 type %s (%d)",
 		    ifp->name, op, r->type);
@@ -2395,7 +2408,8 @@
 			    dhcp6_startexpire, ifp);
 		if (ifp->options->ia_type == D6_OPTION_IA_PD)
 			dhcp6_delegate_prefix(ifp);
-		ipv6nd_probeaddrs(&state->addrs);
+
+		ipv6_addaddrs(&state->addrs);
 		if (state->state == DH6S_INFORMED)
 			syslog(has_new ? LOG_INFO : LOG_DEBUG,
 			    "%s: refresh in %"PRIu32" seconds",
@@ -2503,13 +2517,7 @@
 	    &n, sizeof(n)) == -1)
 		goto errexit;
 
-	n = 1;
-	if (setsockopt(ctx->dhcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
-	    &n, sizeof(n)) == -1)
-		goto errexit;
-
 	eloop_event_add(dctx->eloop, ctx->dhcp_fd, dhcp6_handledata, dctx);
-
 	return 0;
 
 errexit:
@@ -2636,14 +2644,16 @@
 {
 	struct dhcp6_state *state;
 	struct dhcpcd_ctx *ctx;
-	int options;
+	unsigned long long options;
 
-	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+	if (ifp->ctx->eloop)
+		eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
 	if (ifp->options)
 		options = ifp->options->options;
 	else
 		options = 0;
+
 	/*
 	 * As the interface is going away from dhcpcd we need to
 	 * remove the delegated addresses, otherwise we lose track
@@ -2751,7 +2761,7 @@
 	const struct if_options *ifo;
 	struct dhcp_opt *opt, *vo;
 	const struct dhcp6_option *o;
-	size_t i, n;
+	size_t i, l, n;
 	uint16_t ol, oc;
 	char *v, *val, *pfx;
 	const struct ipv6_addr *ap;
@@ -2850,40 +2860,48 @@
 	if (TAILQ_FIRST(&state->addrs)) {
 		if (env) {
 			if (ifo->ia_type == D6_OPTION_IA_PD) {
-				i = strlen(prefix) +
+				l = strlen(prefix) +
 				    strlen("_dhcp6_prefix=");
 				TAILQ_FOREACH(ap, &state->addrs, next) {
-					i += strlen(ap->saddr) + 1;
+					l += strlen(ap->saddr) + 1;
 				}
-				v = val = env[n] = malloc(i);
+				v = val = env[n] = malloc(l);
 				if (v == NULL) {
 					syslog(LOG_ERR, "%s: %m", __func__);
 					return -1;
 				}
-				v += snprintf(val, i, "%s_dhcp6_prefix=",
-					prefix);
+				i = snprintf(v, l, "%s_dhcp6_prefix=",
+				    prefix);
+				v += i;
+				l -= i;
 				TAILQ_FOREACH(ap, &state->addrs, next) {
-					strcpy(v, ap->saddr);
-					v += strlen(ap->saddr);
+					i = strlen(ap->saddr);
+					strlcpy(v, ap->saddr, l);
+					v += i;
+					l -= i;
 					*v++ = ' ';
 				}
 				*--v = '\0';
 			} else {
-				i = strlen(prefix) +
+				l = strlen(prefix) +
 				    strlen("_dhcp6_ip_address=");
 				TAILQ_FOREACH(ap, &state->addrs, next) {
-					i += strlen(ap->saddr) + 1;
+					l += strlen(ap->saddr) + 1;
 				}
-				v = val = env[n] = malloc(i);
+				v = val = env[n] = malloc(l);
 				if (v == NULL) {
 					syslog(LOG_ERR, "%s: %m", __func__);
 					return -1;
 				}
-				v += snprintf(val, i, "%s_dhcp6_ip_address=",
-					prefix);
+				i = snprintf(v, l, "%s_dhcp6_ip_address=",
+				    prefix);
+				v += i;
+				l -= i;
 				TAILQ_FOREACH(ap, &state->addrs, next) {
-					strcpy(v, ap->saddr);
-					v += strlen(ap->saddr);
+					i = strlen(ap->saddr);
+					strlcpy(v, ap->saddr, l);
+					v += i;
+					l -= i;
 					*v++ = ' ';
 				}
 				*--v = '\0';
--- a/external/bsd/dhcpcd/dist/dhcpcd-embedded.c	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/dhcpcd-embedded.c	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.1.1.3 2014/02/25 13:14:29 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.1.1.4 2014/03/14 11:27:36 roy Exp $");
 
 /*
  * DO NOT EDIT
@@ -36,7 +36,7 @@
 
 #include <unistd.h>
 
-const char *dhcpcd_embedded_conf[] = {
+const char * const dhcpcd_embedded_conf[] = {
 "define 1 request ipaddress subnet_mask",
 "define 121 rfc3442 classless_static_routes",
 "define 249 rfc3442 ms_classless_static_routes",
--- a/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: 01-test,v 1.1.1.5 2014/03/01 11:00:43 roy Exp $
+# $NetBSD: 01-test,v 1.1.1.6 2014/03/14 11:27:41 roy Exp $
 
 # Just echo our DHCP options we have
 
@@ -6,4 +6,5 @@
 	set | grep "^\(interface\|pid\|reason\|skip_hooks\)=" | sort
 	set | grep "^if\(carrier\|flags\|mtu\|wireless\)=" | sort
 	set | grep "^\(new_\|old_\|ra_count=\|ra[0-9]*_\)" | sort
+	exit 0
 fi
--- a/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump	Fri Mar 14 11:27:36 2014 +0000
@@ -1,7 +1,8 @@
-# $NetBSD: 02-dump,v 1.1.1.2 2013/06/21 19:33:08 roy Exp $
+# $NetBSD: 02-dump,v 1.1.1.3 2014/03/14 11:27:41 roy Exp $
 
 # Just echo our DHCP options we have
 
 if [ "$reason" = "DUMP" ]; then
 	set | sed -ne 's/^new_//p' | sort
+	exit 0
 fi
--- a/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: 50-ntp.conf,v 1.1.1.11 2013/06/21 19:33:08 roy Exp $
+# $NetBSD: 50-ntp.conf,v 1.1.1.12 2014/03/14 11:27:41 roy Exp $
 
 # Sample dhcpcd hook script for ntp
 # Like our resolv.conf hook script, we store a database of ntp.conf files
@@ -8,7 +8,7 @@
 #   dhcpcd -e NTP_CONF=/usr/pkg/etc/ntpd.conf
 # or by adding this to /etc/dhcpcd.enter-hook
 #   NTP_CONF=/usr/pkg/etc/ntpd.conf
-# to use openntpd from pkgsrc instead of the system provided ntp.
+# to use OpenNTPD instead of the default NTP.
 
 if type invoke-rc.d >/dev/null 2>&1; then
 	# Debian has a seperate file for DHCP config to avoid stamping on
@@ -21,7 +21,16 @@
 : ${ntp_service:=ntpd}
 : ${ntp_restart_cmd:=service_condcommand $ntp_service restart}
 ntp_conf_dir="$state_dir/ntp.conf"
-ntp_conf=${NTP_CONF:-/etc/ntp.conf}
+
+# If we have installed OpenNTPD but not NTP then prefer it
+# XXX If both exist then update both?
+if [ -z "$NTP_CONF" -a -e /etc/ntpd.conf -a ! -e /etc/ntp.conf ]; then
+	: ${NTP_CONF:=/etc/ntpd.conf}
+else
+	: ${NTP_CONF:=/etc/ntp.conf}
+fi
+
+ntp_conf=${NTP_CONF}
 NL="
 "
 
--- a/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $NetBSD: dhcpcd-run-hooks.in,v 1.1.1.17 2014/02/25 13:14:30 roy Exp $
+# $NetBSD: dhcpcd-run-hooks.in,v 1.1.1.18 2014/03/14 11:27:37 roy Exp $
 
 # dhcpcd client configuration script 
 
@@ -184,7 +184,9 @@
 		[ -z "$label" -o ${#label} -gt 63 ] && return 1
 		case "$label" in
 		-*|_*|*-|*_)		return 1;;
-		*[![:alnum:]-_]*)	return 1;;
+		# some sh require - as the first or last character in the class
+		# when matching it
+		*[![:alnum:]_-]*)	return 1;;
 		esac
 		[ "$name" = "${name#*.}" ] && break
 		name="${name#*.}"
@@ -264,6 +266,8 @@
 		done
 		if [ -e /etc/arch-release ]; then
 			_service_status="[ -e /var/run/daemons/\$1 ]"
+		elif [ "$x" = "/etc/rc.d" -a -e /etc/rc.d/rc.subr ]; then
+			_service_status="$x/\$1 check 1>/dev/null 2>&1"
 		fi
 	fi
 
--- a/external/bsd/dhcpcd/dist/if-options.h	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/if-options.h	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if-options.h,v 1.1.1.20 2014/02/25 13:14:30 roy Exp $ */
+/* $NetBSD: if-options.h,v 1.1.1.21 2014/03/14 11:27:41 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -42,7 +42,7 @@
 
 /* Don't set any optional arguments here so we retain POSIX
  * compatibility with getopt */
-#define IF_OPTS "46bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:wxy:z:ABC:DEF:GHI:JKLO:Q:S:TUVW:X:Z:"
+#define IF_OPTS "46bc:de:f:gh:i:kl:m:no:pqr:s:t:u:v:wxy:z:ABC:DEF:GHI:JKLMO:Q:S:TUVW:X:Z:"
 
 #define DEFAULT_TIMEOUT		30
 #define DEFAULT_REBOOT		5
--- a/external/bsd/dhcpcd/dist/ipv4.c	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/ipv4.c	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.1.1.4 2014/02/25 13:14:29 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.1.1.5 2014/03/14 11:27:36 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -725,21 +725,29 @@
 
 	if (ifs == NULL)
 		ifs = ctx->ifaces;
-	if (ifs == NULL)
+	if (ifs == NULL) {
+		errno = ESRCH;
 		return;
-	if (addr->s_addr == INADDR_ANY)
+	}
+	if (addr->s_addr == INADDR_ANY) {
+		errno = EINVAL;
 		return;
+	}
 
 	TAILQ_FOREACH(ifp, ifs, next) {
 		if (strcmp(ifp->name, ifname) == 0)
 			break;
 	}
-	if (ifp == NULL)
+	if (ifp == NULL) {
+		errno = ESRCH;
 		return;
+	}
+	state = ipv4_getstate(ifp);
+	if (state == NULL) {
+		errno = ENOENT;
+		return;
+	}
 
-	state = ipv4_getstate(ifp);
-	if (state == NULL)
-		return;
 	ap = ipv4_findaddr(ifp, addr, net);
 	if (type == RTM_NEWADDR && ap == NULL) {
 		ap = malloc(sizeof(*ap));
--- a/external/bsd/dhcpcd/dist/ipv6.c	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/ipv6.c	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.1.1.8 2014/02/25 13:14:29 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.1.1.9 2014/03/14 11:27:36 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -41,9 +41,10 @@
    /* Match Linux defines to BSD */
 #  define IN6_IFF_TENTATIVE	(IFA_F_TENTATIVE | IFA_F_OPTIMISTIC)
 #  define IN6_IFF_DUPLICATED	IFA_F_DADFAILED
+#  define IN6_IFF_DETACHED	0
 #else
+#  include <net/if.h>
 #ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
-#  include <net/if.h>
 #  include <net/if_var.h>
 #endif
 #  include <netinet6/in6_var.h>
@@ -64,18 +65,19 @@
 #include "ipv6.h"
 #include "ipv6nd.h"
 
+#ifdef IPV6_POLLADDRFLAG
+#  warning kernel does not report IPv6 address flag changes
+#  warning polling tentative address flags periodically instead
+#endif
+
+#define IN6_IFF_NOTUSEABLE \
+	(IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED)
+
 /* Hackery at it's finest. */
 #ifndef s6_addr32
 #  define s6_addr32 __u6_addr.__u6_addr32
 #endif
 
-#define EUI64_GBIT	0x01
-#define EUI64_UBIT	0x02
-#define EUI64_TO_IFID(in6)	do {(in6)->s6_addr[8] ^= EUI64_UBIT; } \
-				    while (/*CONSTCOND*/ 0)
-#define EUI64_GROUP(in6)	((in6)->s6_addr[8] & EUI64_GBIT)
-
-
 struct ipv6_ctx *
 ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx)
 {
@@ -113,13 +115,24 @@
 	ctx->rcvhdr.msg_iov = ctx->rcviov;
 	ctx->rcvhdr.msg_iovlen = 1;
 	ctx->rcvhdr.msg_control = ctx->rcvbuf;
-	ctx->rcvhdr.msg_controllen = sizeof(ctx->rcvbuf);
+	// controllen is set at recieve
+	//ctx->rcvhdr.msg_controllen = sizeof(ctx->rcvbuf);
 	ctx->rcviov[0].iov_base = ctx->ansbuf;
 	ctx->rcviov[0].iov_len = sizeof(ctx->ansbuf);
 
 	ctx->nd_fd = -1;
 	ctx->dhcp_fd = -1;
 
+#ifdef IPV6_POLLADDRFLAG
+	if (!ctx->polladdr_warned) {
+		syslog(LOG_WARNING,
+		    "kernel does not report IPv6 address flag changes");
+		syslog(LOG_WARNING,
+		    "polling tentative address flags periodically instead");
+		ctx->polladdr_warned = 1;
+	}
+#endif
+
 	dhcpcd_ctx->ipv6 = ctx;
 	return ctx;
 }
@@ -160,91 +173,24 @@
 ipv6_makeaddr(struct in6_addr *addr, const struct interface *ifp,
     const struct in6_addr *prefix, int prefix_len)
 {
-	const struct ipv6_addr_l *ap;
-#if 0
-	static u_int8_t allzero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-	static u_int8_t allone[8] =
-	    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-#endif
+	const struct ipv6_addr *ap;
 
 	if (prefix_len < 0 || prefix_len > 64) {
 		errno = EINVAL;
 		return -1;
 	}
-
-	memcpy(addr, prefix, sizeof(*prefix));
-
-	/* Try and make the address from the first local-link address */
-	ap = ipv6_linklocal(ifp);
-	if (ap) {
-		addr->s6_addr32[2] = ap->addr.s6_addr32[2];
-		addr->s6_addr32[3] = ap->addr.s6_addr32[3];
-		return 0;
-	}
-
-	/* Because we delay a few functions until we get a local-link address
-	 * there is little point in the below code.
-	 * It exists in-case we need to create local-link addresses
-	 * ourselves, but then we would need to be able to send RFC
-	 * conformant DAD requests.
-	 * See ipv6ns.c for why we need the kernel to do this. */
-	errno = ENOENT;
-	return -1;
-
-#if 0
-	/* Make an EUI64 based off our hardware address */
-	switch (ifp->family) {
-	case ARPHRD_ETHER:
-		/* Check for a valid hardware address */
-		if (ifp->hwlen != 8 && ifp->hwlen != 6) {
-			errno = ENOTSUP;
-			return -1;
-		}
-		if (memcmp(ifp->hwaddr, allzero, ifp->hwlen) == 0 ||
-		    memcmp(ifp->hwaddr, allone, ifp->hwlen) == 0)
-		{
-			errno = EINVAL;
-			return -1;
-		}
-
-		/* make a EUI64 address */
-		if (ifp->hwlen == 8)
-			memcpy(&addr->s6_addr[8], ifp->hwaddr, 8);
-		else if (ifp->hwlen == 6) {
-			addr->s6_addr[8] = ifp->hwaddr[0];
-			addr->s6_addr[9] = ifp->hwaddr[1];
-			addr->s6_addr[10] = ifp->hwaddr[2];
-			addr->s6_addr[11] = 0xff;
-			addr->s6_addr[12] = 0xfe;
-			addr->s6_addr[13] = ifp->hwaddr[3];
-			addr->s6_addr[14] = ifp->hwaddr[4];
-			addr->s6_addr[15] = ifp->hwaddr[5];
-		}
-		break;
-	default:
-		errno = ENOTSUP;
+	if ((ap = ipv6_linklocal(ifp)) == NULL) {
+		/* We delay a few functions until we get a local-link address
+		 * so this should never be hit. */
+		errno = ENOENT;
 		return -1;
 	}
 
-	/* sanity check: g bit must not indicate "group" */
-	if (EUI64_GROUP(addr)) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	EUI64_TO_IFID(addr);
-
-	/* sanity check: ifid must not be all zero, avoid conflict with
-	 * subnet router anycast */
-	if ((addr->s6_addr[8] & ~(EUI64_GBIT | EUI64_UBIT)) == 0x00 &&
-		memcmp(&addr->s6_addr[9], allzero, 7) == 0)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-
+	/* Make the address from the first local-link address */
+	memcpy(addr, prefix, sizeof(*prefix));
+	addr->s6_addr32[2] = ap->addr.s6_addr32[2];
+	addr->s6_addr32[3] = ap->addr.s6_addr32[3];
 	return 0;
-#endif
 }
 
 int
@@ -421,6 +367,31 @@
 	return 0;
 }
 
+#ifdef IPV6_POLLADDRFLAG
+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)
 {
@@ -458,9 +429,55 @@
 		syslog(LOG_DEBUG,
 		    "%s: vltime %"PRIu32" seconds, pltime %"PRIu32" seconds",
 		    ap->iface->name, ap->prefix_vltime, ap->prefix_pltime);
+
+#ifdef IPV6_POLLADDRFLAG
+	eloop_timeout_delete(ap->iface->ctx->eloop,
+		ipv6_checkaddrflags, ap);
+	if (!(ap->flags & IPV6_AF_DADCOMPLETED)) {
+		struct timeval tv;
+
+		ms_to_tv(&tv, RETRANS_TIMER / 2);
+		eloop_timeout_add_tv(ap->iface->ctx->eloop,
+		    &tv, ipv6_checkaddrflags, ap);
+	}
+#endif
+
 	return 0;
 }
 
+ssize_t
+ipv6_addaddrs(struct ipv6_addrhead *addrs)
+{
+	struct ipv6_addr *ap, *apn;
+	ssize_t i;
+
+	i = 0;
+	TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
+		if (ap->prefix_vltime == 0) {
+			TAILQ_REMOVE(addrs, ap, next);
+			if (ap->flags & IPV6_AF_ADDED) {
+				syslog(LOG_INFO, "%s: deleting address %s",
+				    ap->iface->name, ap->saddr);
+				i++;
+				if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr) &&
+				    del_address6(ap) == -1 &&
+				    errno != EADDRNOTAVAIL && errno != ENXIO)
+					syslog(LOG_ERR, "del_address6 %m");
+			}
+			eloop_q_timeout_delete(ap->iface->ctx->eloop,
+			    0, NULL, ap);
+			free(ap);
+		} else if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr)) {
+			if (ap->flags & IPV6_AF_NEW)
+				i++;
+			ipv6_addaddr(ap);
+		}
+	}
+
+	return i;
+}
+
+
 void
 ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
     const struct interface *ifd)
@@ -471,9 +488,7 @@
 		if (ifd && ap->delegating_iface != ifd)
 			continue;
 		TAILQ_REMOVE(addrs, ap, next);
-		if (ap->dadcallback)
-			eloop_q_timeout_delete(ap->iface->ctx->eloop,
-			    0, NULL, ap->dadcallback);
+		eloop_q_timeout_delete(ap->iface->ctx->eloop, 0, NULL, ap);
 		/* Only drop the address if no other RAs have assigned it.
 		 * This is safe because the RA is removed from the list
 		 * before we are called. */
@@ -520,7 +535,7 @@
 {
 	struct interface *ifp;
 	struct ipv6_state *state;
-	struct ipv6_addr_l *ap;
+	struct ipv6_addr *ap;
 	struct ll_callback *cb;
 
 #if 0
@@ -531,16 +546,6 @@
 	    ifname, cmd, buf, flags);
 #endif
 
-	/* Safety, remove tentative addresses */
-	if (cmd == RTM_NEWADDR) {
-		if (flags & (IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED))
-			cmd = RTM_DELADDR;
-#ifdef IN6_IFF_DETACHED
-		if (flags & IN6_IFF_DETACHED)
-			cmd = RTM_DELADDR;
-#endif
-	}
-
 	if (ifs == NULL)
 		ifs = ctx->ifaces;
 	if (ifs == NULL) {
@@ -555,20 +560,17 @@
 		errno = ESRCH;
 		return;
 	}
-
 	state = ipv6_getstate(ifp);
-	if (state == NULL)
+	if (state == NULL) {
+		errno = ENOENT;
 		return;
+	}
 
 	if (!IN6_IS_ADDR_LINKLOCAL(addr)) {
 		ipv6nd_handleifa(ctx, cmd, ifname, addr, flags);
 		dhcp6_handleifa(ctx, cmd, ifname, addr, flags);
 	}
 
-	/* We don't care about duplicated addresses, so remove them */
-	if (flags & IN6_IFF_DUPLICATED)
-		cmd = RTM_DELADDR;
-
 	TAILQ_FOREACH(ap, &state->addrs, next) {
 		if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr))
 			break;
@@ -584,16 +586,30 @@
 	case RTM_NEWADDR:
 		if (ap == NULL) {
 			ap = calloc(1, sizeof(*ap));
+			ap->iface = ifp;
 			memcpy(ap->addr.s6_addr, addr->s6_addr,
 			    sizeof(ap->addr.s6_addr));
 			TAILQ_INSERT_TAIL(&state->addrs,
 			    ap, next);
+		}
+		ap->addr_flags = flags;
 
-			if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
+		if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
+#ifdef IPV6_POLLADDRFLAG
+			if (ap->addr_flags & IN6_IFF_TENTATIVE) {
+				struct timeval tv;
+
+				ms_to_tv(&tv, RETRANS_TIMER / 2);
+				eloop_timeout_add_tv(ap->iface->ctx->eloop,
+				    &tv, ipv6_checkaddrflags, ap);
+				break;
+			}
+#endif
+
+			if (!(ap->addr_flags & IN6_IFF_NOTUSEABLE)) {
 				/* Now run any callbacks.
 				 * Typically IPv6RS or DHCPv6 */
-				while ((cb =
-				    TAILQ_FIRST(&state->ll_callbacks)))
+				while ((cb = TAILQ_FIRST(&state->ll_callbacks)))
 				{
 					TAILQ_REMOVE(&state->ll_callbacks,
 					    cb, next);
@@ -606,33 +622,23 @@
 	}
 }
 
-const struct ipv6_addr_l *
-ipv6_linklocal(const struct interface *ifp)
+const struct ipv6_addr *
+ipv6_findaddr(const struct interface *ifp, const struct in6_addr *addr)
 {
 	const struct ipv6_state *state;
-	const struct ipv6_addr_l *ap;
+	const struct ipv6_addr *ap;
 
 	state = IPV6_CSTATE(ifp);
 	if (state) {
 		TAILQ_FOREACH(ap, &state->addrs, next) {
-			if (IN6_IS_ADDR_LINKLOCAL(&ap->addr))
-				return ap;
-		}
-	}
-	return NULL;
-}
-
-const struct ipv6_addr_l *
-ipv6_findaddr(const struct interface *ifp, const struct in6_addr *addr)
-{
-	const struct ipv6_state *state;
-	const struct ipv6_addr_l *ap;
-
-	state = IPV6_CSTATE(ifp);
-	if (state) {
-		TAILQ_FOREACH(ap, &state->addrs, next) {
-			if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr))
-				return ap;
+			if (addr == NULL) {
+				if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
+				    !(ap->addr_flags & IN6_IFF_NOTUSEABLE))
+					return ap;
+			} else {
+				if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr))
+					return ap;
+			}
 		}
 	}
 	return NULL;
@@ -681,7 +687,7 @@
 ipv6_free(struct interface *ifp)
 {
 	struct ipv6_state *state;
-	struct ipv6_addr_l *ap;
+	struct ipv6_addr *ap;
 
 	if (ifp) {
 		ipv6_free_ll_callbacks(ifp);
@@ -871,7 +877,6 @@
 	return r;
 }
 
-
 static struct rt6 *
 make_router(const struct ra *rap)
 {
@@ -941,14 +946,15 @@
 			continue;
 		if (rap->iface->options->options & DHCPCD_IPV6RA_OWN) {
 			TAILQ_FOREACH(addr, &rap->addrs, next) {
-				if ((addr->flags & IPV6_AF_ONLINK) == 0)
+				if (addr->prefix_vltime == 0 ||
+				    (addr->flags & IPV6_AF_ONLINK) == 0)
 					continue;
 				rt = make_prefix(rap->iface, rap, addr);
 				if (rt)
 					TAILQ_INSERT_TAIL(dnr, rt, next);
 			}
 		}
-		if (rap->iface->options->options &
+		if (rap->lifetime && rap->iface->options->options &
 		    (DHCPCD_IPV6RA_OWN | DHCPCD_IPV6RA_OWN_DEFAULT))
 		{
 			rt = make_router(rap);
--- a/external/bsd/dhcpcd/dist/ipv6.h	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/ipv6.h	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.1.1.7 2014/02/25 13:14:31 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.1.1.8 2014/03/14 11:27:41 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -31,6 +31,7 @@
 #define IPV6_H
 
 #include <sys/queue.h>
+#include <sys/uio.h>
 
 #include <netinet/in.h>
 
@@ -42,7 +43,6 @@
 #include "dhcpcd.h"
 
 #define ALLROUTERS "ff02::2"
-#define HOPLIMIT 255
 
 #define ROUNDUP8(a) (1 + (((a) - 1) | 7))
 
@@ -52,11 +52,6 @@
 
 /*
  * BSD kernels don't inform userland of DAD results.
- * Also, for RTM_NEWADDR messages the address flags could be
- * undefined leading to false positive duplicate address errors.
- * As such we listen for duplicate addresses on the wire and
- * wait the maxium possible length of time as dictated by the DAD transmission
- * counter and RFC timings.
  * See the discussion here:
  *    http://mail-index.netbsd.org/tech-net/2013/03/15/msg004019.html
  */
@@ -65,13 +60,13 @@
 #  include <sys/param.h>
 #endif
 #ifdef BSD
-#  define LISTEN_DAD
+#  define IPV6_POLLADDRFLAG
 #endif
 
 /* This was fixed in NetBSD */
 #ifdef __NetBSD_Prereq__
 #  if __NetBSD_Prereq__(6, 99, 20)
-#    undef LISTEN_DAD
+#    undef IPV6_POLLADDRFLAG
 #  endif
 #endif
 
@@ -83,6 +78,7 @@
 	uint32_t prefix_vltime;
 	uint32_t prefix_pltime;
 	struct in6_addr addr;
+	int addr_flags;
 	short flags;
 	char saddr[INET6_ADDRSTRLEN];
 	uint8_t iaid[4];
@@ -115,13 +111,6 @@
 };
 TAILQ_HEAD(rt6_head, rt6);
 
-struct ipv6_addr_l {
-	TAILQ_ENTRY(ipv6_addr_l) next;
-	struct in6_addr addr;
-};
-
-TAILQ_HEAD(ipv6_addr_l_head, ipv6_addr_l);
-
 struct ll_callback {
 	TAILQ_ENTRY(ll_callback) next;
 	void (*callback)(void *);
@@ -130,7 +119,7 @@
 TAILQ_HEAD(ll_callback_head, ll_callback);
 
 struct ipv6_state {
-	struct ipv6_addr_l_head addrs;
+	struct ipv6_addrhead addrs;
 	struct ll_callback_head ll_callbacks;
 };
 
@@ -142,11 +131,12 @@
 #define IP6BUFLEN	(CMSG_SPACE(sizeof(struct in6_pktinfo)) + \
 			CMSG_SPACE(sizeof(int)))
 
+#ifdef INET6
 struct ipv6_ctx {
 	struct sockaddr_in6 from;
 	struct msghdr sndhdr;
 	struct iovec sndiov[2];
-	unsigned char sndbuf[IP6BUFLEN];
+	unsigned char sndbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
 	struct msghdr rcvhdr;
 	struct iovec rcviov[2];
 	unsigned char rcvbuf[IP6BUFLEN];
@@ -155,17 +145,15 @@
 	const char *sfrom;
 
 	int nd_fd;
-#ifdef IPV6_SEND_DAD
-	int unspec_fd;
-#endif
-#ifdef LISTEN_DAD
-	uint8_t dad_warned;
+#ifdef IPV6_POLLADDRFLAG
+	uint8_t polladdr_warned;
 #endif
 	struct ra_head *ra_routers;
 	struct rt6_head *routes;
 
 	int dhcp_fd;
 };
+#endif
 
 #ifdef INET6
 struct ipv6_ctx *ipv6_init(struct dhcpcd_ctx *);
@@ -177,16 +165,18 @@
 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 *);
+ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs);
 void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
     const struct interface *);
 void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *,
     const char *, const struct in6_addr *, int);
 int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
     const struct in6_addr *, int);
-const struct ipv6_addr_l *ipv6_linklocal(const struct interface *);
-const struct ipv6_addr_l *ipv6_findaddr(const struct interface *,
+const struct ipv6_addr *ipv6_findaddr(const struct interface *,
     const struct in6_addr *);
+#define ipv6_linklocal(ifp) (ipv6_findaddr((ifp), NULL))
 int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *);
 void ipv6_free_ll_callbacks(struct interface *);
 void ipv6_free(struct interface *);
--- a/external/bsd/dhcpcd/dist/ipv6nd.h	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/ipv6nd.h	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6nd.h,v 1.1.1.2 2014/02/25 13:14:31 roy Exp $ */
+/* $NetBSD: ipv6nd.h,v 1.1.1.3 2014/03/14 11:27:41 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -96,17 +96,9 @@
     const char *, const struct in6_addr *, int);
 void ipv6nd_drop(struct interface *);
 
-void ipv6nd_probeaddr(void *);
-ssize_t ipv6nd_probeaddrs(struct ipv6_addrhead *);
 void ipv6nd_proberouter(void *);
 void ipv6nd_cancelproberouter(struct ra *);
 
-#ifdef LISTEN_DAD
-void ipv6nd_cancelprobeaddr(struct ipv6_addr *);
-#else
-#define ipv6nd_cancelprobeaddr(a)
-#endif
-
 #else
 #define ipv6nd_startrs(a) {}
 #define ipv6nd_addrexists(a, b) (0)
--- a/external/bsd/dhcpcd/dist/net.h	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/net.h	Fri Mar 14 11:27:36 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: net.h,v 1.1.1.15 2014/02/25 13:14:31 roy Exp $ */
+/* $NetBSD: net.h,v 1.1.1.16 2014/03/14 11:27:41 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -43,7 +43,7 @@
 
 /* Some systems have route metrics */
 #ifndef HAVE_ROUTE_METRIC
-# ifdef __linux__
+# if defined(__linux__) || defined(SIOCGIFPRIORITY)
 #  define HAVE_ROUTE_METRIC 1
 # endif
 # ifndef HAVE_ROUTE_METRIC
--- a/external/bsd/dhcpcd/dist/platform-bsd.c	Fri Mar 14 10:06:22 2014 +0000
+++ b/external/bsd/dhcpcd/dist/platform-bsd.c	Fri Mar 14 11:27:36 2014 +0000
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: platform-bsd.c,v 1.1.1.12 2014/02/25 13:14:29 roy Exp $");
+ __RCSID("$NetBSD: platform-bsd.c,v 1.1.1.13 2014/03/14 11:27:36 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -56,6 +56,12 @@
 #  define SYS_NMLN 256
 #endif
 
+#ifndef HW_MACHINE_ARCH
+#  ifdef HW_MODEL	/* OpenBSD */
+#    define HW_MACHINE_ARCH HW_MODEL
+#  endif
+#endif
+
 int
 hardware_platform(char *str, size_t len)
 {
@@ -111,7 +117,7 @@
 	s = socket(AF_INET6, SOCK_DGRAM, 0);
 	if (s == -1)
 		return -1;
-	strcpy(dummy, "lo0");
+	strlcpy(dummy, "lo0", sizeof(dummy));
 	if (ioctl(s, SIOCSRTRFLUSH_IN6, (caddr_t)&dummy) == -1)
 		syslog(LOG_ERR, "SIOSRTRFLUSH_IN6: %m");
 	if (ioctl(s, SIOCSPFXFLUSH_IN6, (caddr_t)&dummy) == -1)