Module Name:    src
Committed By:   roy
Date:           Fri Oct 17 23:42:25 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
        src/external/bsd/dhcpcd/dist/crypt: crypt.h hmac_md5.c
        src/external/bsd/dhcpcd/dist/dhcpcd-hooks: 01-test 02-dump 10-mtu
            10-wpa_supplicant 15-timezone 20-resolv.conf 29-lookup-hostname
            30-hostname 50-ntp.conf 50-ypbind

Log Message:
Sync


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 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.5 -r1.6 src/external/bsd/dhcpcd/dist/bpf-filter.h
cvs rdiff -u -r1.18 -r1.19 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.8 -r1.9 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
cvs rdiff -u -r1.32 -r1.33 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/dhcpcd.c \
    src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/dhcpcd.conf \
    src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/if-options.c \
    src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/script.c
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/dhcpcd/dist/crypt/crypt.h \
    src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-wpa_supplicant \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/15-timezone \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/29-lookup-hostname \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ypbind

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.2 src/external/bsd/dhcpcd/dist/arp.c:1.3
--- src/external/bsd/dhcpcd/dist/arp.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/arp.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: arp.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: arp.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -42,6 +42,7 @@
 #include <syslog.h>
 #include <unistd.h>
 
+#define ELOOP_QUEUE 2
 #include "config.h"
 #include "arp.h"
 #include "ipv4.h"
@@ -127,6 +128,7 @@ static void
 arp_packet(void *arg)
 {
 	struct interface *ifp = arg;
+	const struct interface *ifn;
 	uint8_t arp_buffer[ARP_LEN];
 	struct arphdr ar;
 	uint32_t reply_s;
@@ -173,8 +175,12 @@ arp_packet(void *arg)
 		if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
 			continue;
 		/* Ignore messages from ourself */
-		if (ar.ar_hln == ifp->hwlen &&
-		    memcmp(hw_s, ifp->hwaddr, ifp->hwlen) == 0)
+		TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
+			if (ar.ar_hln == ifn->hwlen &&
+			    memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
+				break;
+		}
+		if (ifn)
 			continue;
 		/* Copy out the IP addresses */
 		memcpy(&reply_s, hw_s + ar.ar_hln, ar.ar_pln);
Index: src/external/bsd/dhcpcd/dist/arp.h
diff -u src/external/bsd/dhcpcd/dist/arp.h:1.2 src/external/bsd/dhcpcd/dist/arp.h:1.3
--- src/external/bsd/dhcpcd/dist/arp.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/arp.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: arp.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: arp.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/auth.c
diff -u src/external/bsd/dhcpcd/dist/auth.c:1.2 src/external/bsd/dhcpcd/dist/auth.c:1.3
--- src/external/bsd/dhcpcd/dist/auth.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/auth.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: auth.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: auth.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/auth.h
diff -u src/external/bsd/dhcpcd/dist/auth.h:1.2 src/external/bsd/dhcpcd/dist/auth.h:1.3
--- src/external/bsd/dhcpcd/dist/auth.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/auth.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: auth.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: auth.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/common.c
diff -u src/external/bsd/dhcpcd/dist/common.c:1.2 src/external/bsd/dhcpcd/dist/common.c:1.3
--- src/external/bsd/dhcpcd/dist/common.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/common.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: common.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: common.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/common.h
diff -u src/external/bsd/dhcpcd/dist/common.h:1.2 src/external/bsd/dhcpcd/dist/common.h:1.3
--- src/external/bsd/dhcpcd/dist/common.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/common.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: common.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: common.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/config.h
diff -u src/external/bsd/dhcpcd/dist/config.h:1.2 src/external/bsd/dhcpcd/dist/config.h:1.3
--- src/external/bsd/dhcpcd/dist/config.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/config.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: config.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: config.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /* netbsd */
 #define SYSCONFDIR	"/etc"
Index: src/external/bsd/dhcpcd/dist/control.c
diff -u src/external/bsd/dhcpcd/dist/control.c:1.2 src/external/bsd/dhcpcd/dist/control.c:1.3
--- src/external/bsd/dhcpcd/dist/control.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/control.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: control.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: control.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/control.h
diff -u src/external/bsd/dhcpcd/dist/control.h:1.2 src/external/bsd/dhcpcd/dist/control.h:1.3
--- src/external/bsd/dhcpcd/dist/control.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/control.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: control.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: control.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.2 src/external/bsd/dhcpcd/dist/defs.h:1.3
--- src/external/bsd/dhcpcd/dist/defs.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/defs.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: defs.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
 #define CONFIG_H
 
 #define PACKAGE			"dhcpcd"
-#define VERSION			"6.5.0"
+#define VERSION			"6.5.1"
 
 #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.2 src/external/bsd/dhcpcd/dist/dev.h:1.3
--- src/external/bsd/dhcpcd/dist/dev.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dev.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dev.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: dev.h,v 1.3 2014/10/17 23:42:24 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.2 src/external/bsd/dhcpcd/dist/dhcp-common.c:1.3
--- src/external/bsd/dhcpcd/dist/dhcp-common.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcp-common.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp-common.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: dhcp-common.c,v 1.3 2014/10/17 23:42:24 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.2 src/external/bsd/dhcpcd/dist/dhcp-common.h:1.3
--- src/external/bsd/dhcpcd/dist/dhcp-common.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcp-common.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp-common.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: dhcp-common.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/dhcp.h
diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.2 src/external/bsd/dhcpcd/dist/dhcp.h:1.3
--- src/external/bsd/dhcpcd/dist/dhcp.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcp.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: dhcp.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -229,6 +229,7 @@ struct dhcp_state {
 	struct in_addr addr;
 	struct in_addr net;
 	struct in_addr dst;
+	uint8_t added;
 
 	char leasefile[sizeof(LEASEFILE) + IF_NAMESIZE];
 	time_t start_uptime;
@@ -273,9 +274,6 @@ ssize_t make_message(struct dhcp_message
     uint8_t);
 int valid_dhcp_packet(unsigned char *);
 
-ssize_t write_lease(const struct interface *, const struct dhcp_message *);
-struct dhcp_message *read_lease(struct interface *);
-
 void dhcp_handleifa(int, struct interface *,
     const struct in_addr *, const struct in_addr *, const struct in_addr *);
 
Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.2 src/external/bsd/dhcpcd/dist/dhcp6.c:1.3
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcp6.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -356,14 +356,48 @@ dhcp6_findselfsla(struct interface *ifp,
 	return NULL;
 }
 
+
+#ifndef ffs32
+static int
+ffs32(uint32_t n)
+{
+	int v;
+
+	if (!n)
+		return 0;
+
+	v = 1;
+	if ((n & 0x0000FFFFU) == 0) {
+		n >>= 16;
+		v += 16;
+	}
+	if ((n & 0x000000FFU) == 0) {
+		n >>= 8;
+		v += 8;
+	}
+	if ((n & 0x0000000FU) == 0) {
+		n >>= 4;
+		v += 4;
+	}
+	if ((n & 0x00000003U) == 0) {
+		n >>= 2;
+		v += 2;
+	}
+	if ((n & 0x00000001U) == 0)
+		v += 1;
+
+	return v;
+}
+#endif
+
 static int
 dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
-    const struct ipv6_addr *prefix, const struct if_sla *sla)
+    const struct ipv6_addr *prefix, const struct if_sla *sla, struct if_ia *ia)
 {
 	struct dhcp6_state *state;
 	struct if_sla asla;
-	char iabuf[INET6_ADDRSTRLEN];
-	const char *ia;
+	char sabuf[INET6_ADDRSTRLEN];
+	const char *sa;
 
 	state = D6_STATE(ifp);
 	if (state == NULL) {
@@ -380,18 +414,34 @@ dhcp6_delegateaddr(struct in6_addr *addr
 	}
 
 	if (sla == NULL || sla->sla_set == 0) {
-		struct interface *ifi;
-		unsigned int idx;
-		int bits;
-
 		asla.sla = ifp->index;
-		/* Work out our largest index delegating to. */
-		idx = 0;
-		TAILQ_FOREACH(ifi, ifp->ctx->ifaces, next) {
-			if (ifi != ifp && ifi->index > idx)
-				idx = ifi->index;
+		asla.prefix_len = 0;
+		sla = &asla;
+
+		if (ia->sla_max == 0) {
 		}
-		bits = ffs((int)idx);
+	} else if (sla->prefix_len == 0) {
+		asla.sla = sla->sla;
+		asla.prefix_len = 0;
+		sla = &asla;
+	}
+	if (sla->prefix_len == 0) {
+		uint32_t sla_max;
+		int bits;
+
+		if (ia->sla_max == 0) {
+			const struct interface *ifi;
+
+			sla_max = 0;
+			TAILQ_FOREACH(ifi, ifp->ctx->ifaces, next) {
+				if (ifi != ifp && ifi->index > sla_max)
+					sla_max = ifi->index;
+			}
+		} else
+			sla_max = ia->sla_max;
+
+		bits = ffs32(sla_max);
+
 		if (prefix->prefix_len + bits > UINT8_MAX)
 			asla.prefix_len = UINT8_MAX;
 		else {
@@ -405,16 +455,22 @@ dhcp6_delegateaddr(struct in6_addr *addr
 				asla.prefix_len = ROUNDUP8(asla.prefix_len);
 
 		}
-		sla = &asla;
+
+#define BIT(n) (1l << (n))
+#define BIT_MASK(len) (BIT(len) - 1)
+		if (ia->sla_max == 0)
+			/* Work out the real sla_max from our bits used */
+			ia->sla_max = (uint32_t)BIT_MASK(asla.prefix_len -
+			    prefix->prefix_len);
 	}
 
 	if (ipv6_userprefix(&prefix->prefix, prefix->prefix_len,
 		sla->sla, addr, sla->prefix_len) == -1)
 	{
-		ia = inet_ntop(AF_INET6, &prefix->prefix,
-		    iabuf, sizeof(iabuf));
+		sa = inet_ntop(AF_INET6, &prefix->prefix,
+		    sabuf, sizeof(sabuf));
 		syslog(LOG_ERR, "%s: invalid prefix %s/%d + %d/%d: %m",
-			ifp->name, ia, prefix->prefix_len,
+			ifp->name, sa, prefix->prefix_len,
 			sla->sla, sla->prefix_len);
 		return -1;
 	}
@@ -422,10 +478,10 @@ dhcp6_delegateaddr(struct in6_addr *addr
 	if (prefix->prefix_exclude_len &&
 	    IN6_ARE_ADDR_EQUAL(addr, &prefix->prefix_exclude))
 	{
-		ia = inet_ntop(AF_INET6, &prefix->prefix_exclude,
-		    iabuf, sizeof(iabuf));
+		sa = inet_ntop(AF_INET6, &prefix->prefix_exclude,
+		    sabuf, sizeof(sabuf));
 		syslog(LOG_ERR, "%s: cannot delegate excluded prefix %s/%d",
-		    ifp->name, ia, prefix->prefix_exclude_len);
+		    ifp->name, sa, prefix->prefix_exclude_len);
 		return -1;
 	}
 
@@ -1211,10 +1267,12 @@ dhcp6_dadcallback(void *arg)
 		if (state->state == DH6S_BOUND ||
 		    state->state == DH6S_DELEGATED)
 		{
+			struct ipv6_addr *ap2;
+
 			valid = (ap->delegating_iface == NULL);
-			TAILQ_FOREACH(ap, &state->addrs, next) {
-				if (ap->flags & IPV6_AF_ADDED &&
-				    !(ap->flags & IPV6_AF_DADCOMPLETED))
+			TAILQ_FOREACH(ap2, &state->addrs, next) {
+				if (ap2->flags & IPV6_AF_ADDED &&
+				    !(ap2->flags & IPV6_AF_DADCOMPLETED))
 				{
 					wascompleted = 1;
 					break;
@@ -1223,7 +1281,9 @@ dhcp6_dadcallback(void *arg)
 			if (!wascompleted) {
 				syslog(LOG_DEBUG, "%s: DHCPv6 DAD completed",
 				    ifp->name);
-				script_runreason(ifp, state->reason);
+				script_runreason(ifp,
+				    ap->delegating_iface ?
+				    "DELEGATED6" : state->reason);
 				if (valid)
 					dhcpcd_daemonise(ifp->ctx);
 			}
@@ -1598,12 +1658,13 @@ dhcp6_checkstatusok(const struct interfa
 }
 
 static struct ipv6_addr *
-dhcp6_findaddr(struct interface *ifp, const struct in6_addr *addr)
+dhcp6_iffindaddr(struct interface *ifp, const struct in6_addr *addr,
+    short flags)
 {
-	const struct dhcp6_state *state;
+	struct dhcp6_state *state;
 	struct ipv6_addr *ap;
 
-	state = D6_CSTATE(ifp);
+	state = D6_STATE(ifp);
 	if (state) {
 		TAILQ_FOREACH(ap, &state->addrs, next) {
 			if (addr == NULL) {
@@ -1611,23 +1672,28 @@ dhcp6_findaddr(struct interface *ifp, co
 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)) ==
 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED))
 					return ap;
-			} else if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr))
+			} else if (ap->prefix_vltime &&
+			    IN6_ARE_ADDR_EQUAL(&ap->addr, addr) &&
+			    (!flags || ap->flags & flags))
 				return ap;
 		}
 	}
 	return NULL;
 }
 
-int
-dhcp6_addrexists(struct dhcpcd_ctx *ctx, const struct ipv6_addr *addr)
+struct ipv6_addr *
+dhcp6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
+    short flags)
 {
 	struct interface *ifp;
+	struct ipv6_addr *ap;
 
 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-		if (dhcp6_findaddr(ifp, addr == NULL ? NULL : &addr->addr))
-			return 1;
+		ap = dhcp6_iffindaddr(ifp, addr, flags);
+		if (ap)
+			return ap;
 	}
-	return 0;
+	return NULL;
 }
 
 static int
@@ -1660,7 +1726,7 @@ dhcp6_findna(struct interface *ifp, uint
 			continue;
 		}
 		iap = (const struct dhcp6_ia_addr *)D6_COPTION_DATA(o);
-		a = dhcp6_findaddr(ifp, &iap->addr);
+		a = dhcp6_iffindaddr(ifp, &iap->addr, 0);
 		if (a == NULL) {
 			a = calloc(1, sizeof(*a));
 			if (a == NULL) {
@@ -2171,13 +2237,13 @@ dhcp6_startinit(struct interface *ifp)
 
 static struct ipv6_addr *
 dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
-    const struct if_sla *sla, struct interface *ifs)
+    const struct if_sla *sla, struct if_ia *ia, struct interface *ifs)
 {
 	struct dhcp6_state *state;
 	struct in6_addr addr;
 	struct ipv6_addr *a, *ap, *apn;
-	char iabuf[INET6_ADDRSTRLEN];
-	const char *ia;
+	char sabuf[INET6_ADDRSTRLEN];
+	const char *sa;
 	int pfxlen;
 
 	/* RFC6603 Section 4.2 */
@@ -2193,7 +2259,8 @@ dhcp6_ifdelegateaddr(struct interface *i
 		}
 		pfxlen = prefix->prefix_exclude_len;
 		memcpy(&addr, &prefix->prefix_exclude, sizeof(addr));
-	} else if ((pfxlen = dhcp6_delegateaddr(&addr, ifp, prefix, sla)) == -1)
+	} else if ((pfxlen = dhcp6_delegateaddr(&addr, ifp, prefix,
+	    sla, ia)) == -1)
 		return NULL;
 
 
@@ -2229,42 +2296,44 @@ dhcp6_ifdelegateaddr(struct interface *i
 		}
 	}
 
-	ia = inet_ntop(AF_INET6, &a->addr, iabuf, sizeof(iabuf));
-	snprintf(a->saddr, sizeof(a->saddr), "%s/%d", ia, a->prefix_len);
+	sa = inet_ntop(AF_INET6, &a->addr, sabuf, sizeof(sabuf));
+	snprintf(a->saddr, sizeof(a->saddr), "%s/%d", sa, a->prefix_len);
 	TAILQ_INSERT_TAIL(&state->addrs, a, next);
 	return a;
 }
 
 static void
-dhcp6_script_try_run(struct interface *ifp)
+dhcp6_script_try_run(struct interface *ifp, int delegated)
 {
 	struct dhcp6_state *state;
 	struct ipv6_addr *ap;
-	int completed, valid;
+	int completed;
 
 	state = D6_STATE(ifp);
 	if (!TAILQ_FIRST(&state->addrs))
 		return;
 
-	valid = 0;
 	completed = 1;
 	/* If all addresses have completed DAD run the script */
 	TAILQ_FOREACH(ap, &state->addrs, next) {
+		if (!(ap->flags & IPV6_AF_ADDED))
+			continue;
 		if (ap->flags & IPV6_AF_ONLINK) {
 			if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
-			    ipv6_findaddr(ap->iface, &ap->addr))
+			    ipv6_iffindaddr(ap->iface, &ap->addr))
 				ap->flags |= IPV6_AF_DADCOMPLETED;
-			if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
+			if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0 &&
+			    ((delegated && ap->delegating_iface) ||
+			    (!delegated && !ap->delegating_iface)))
+			{
 				completed = 0;
 				break;
 			}
 		}
-		if (ap->delegating_iface == NULL)
-			valid = 1;
 	}
 	if (completed) {
-		script_runreason(ifp, state->reason);
-		if (valid)
+		script_runreason(ifp, delegated ? "DELEGATED6" : state->reason);
+		if (!delegated)
 			dhcpcd_daemonise(ifp->ctx);
 	} else
 		syslog(LOG_DEBUG,
@@ -2331,7 +2400,7 @@ dhcp6_delegate_prefix(struct interface *
 				if (ia->sla_len == 0) {
 					/* no SLA configured, so lets
 					 * automate it */
-					if (ifd->carrier == LINK_DOWN) {
+					if (ifd->carrier != LINK_UP) {
 						syslog(LOG_DEBUG,
 						    "%s: has no carrier, cannot"
 						    " delegate addresses",
@@ -2340,7 +2409,7 @@ dhcp6_delegate_prefix(struct interface *
 						break;
 					}
 					if (dhcp6_ifdelegateaddr(ifd, ap,
-					    NULL, ifp))
+					    NULL, ia, ifp))
 						k++;
 				}
 				for (j = 0; j < ia->sla_len; j++) {
@@ -2350,7 +2419,7 @@ dhcp6_delegate_prefix(struct interface *
 						    IPV6_AF_DELEGATEDZERO;
 					if (strcmp(ifd->name, sla->ifname))
 						continue;
-					if (ifd->carrier == LINK_DOWN) {
+					if (ifd->carrier != LINK_UP) {
 						syslog(LOG_DEBUG,
 						    "%s: has no carrier, cannot"
 						    " delegate addresses",
@@ -2359,7 +2428,7 @@ dhcp6_delegate_prefix(struct interface *
 						break;
 					}
 					if (dhcp6_ifdelegateaddr(ifd, ap,
-					    sla, ifp))
+					    sla, ia, ifp))
 						k++;
 				}
 				if (carrier_warned ||abrt)
@@ -2371,7 +2440,7 @@ dhcp6_delegate_prefix(struct interface *
 		if (k && !carrier_warned) {
 			ifd_state = D6_STATE(ifd);
 			ipv6_addaddrs(&ifd_state->addrs);
-			dhcp6_script_try_run(ifd);
+			dhcp6_script_try_run(ifd, 1);
 		}
 	}
 }
@@ -2423,7 +2492,7 @@ dhcp6_find_delegates(struct interface *i
 						return 1;
 					}
 					if (dhcp6_ifdelegateaddr(ifp, ap,
-					    sla, ifd))
+					    sla, ia, ifd))
 					    k++;
 				}
 			}
@@ -2436,7 +2505,7 @@ dhcp6_find_delegates(struct interface *i
 		state->state = DH6S_DELEGATED;
 		ipv6_addaddrs(&state->addrs);
 		ipv6_buildroutes(ifp->ctx);
-		dhcp6_script_try_run(ifp);
+		dhcp6_script_try_run(ifp, 1);
 	}
 	return k;
 }
@@ -2907,7 +2976,7 @@ recv:
 			    "%s: will expire", ifp->name);
 		ipv6_buildroutes(ifp->ctx);
 		dhcp6_writelease(ifp);
-		dhcp6_script_try_run(ifp);
+		dhcp6_script_try_run(ifp, 0);
 	}
 
 	if (ifp->ctx->options & DHCPCD_TEST ||
@@ -3081,18 +3150,23 @@ dhcp6_start(struct interface *ifp, enum 
 
 	state = D6_STATE(ifp);
 	if (state) {
-		if (state->state == DH6S_DELEGATED) {
-			dhcp6_find_delegates(ifp);
-			return 0;
-		}
 		if (state->state == DH6S_INFORMED &&
 		    init_state == DH6S_INFORM)
 		{
 			dhcp6_startinform(ifp);
 			return 0;
 		}
+		if (init_state == DH6S_INIT &&
+		    ifp->options->options & DHCPCD_DHCP6 &&
+		    (state->state == DH6S_INFORM ||
+		    state->state == DH6S_INFORMED ||
+		    state->state == DH6S_DELEGATED))
+		{
+			/* Change from stateless to stateful */
+			goto gogogo;
+		}
 		/* We're already running DHCP6 */
-		/* XXX: What if the managed flag changes? */
+		/* XXX: What if the managed flag vanishes from all RA? */
 		return 0;
 	}
 
@@ -3109,16 +3183,13 @@ dhcp6_start(struct interface *ifp, enum 
 
 	state->sol_max_rt = SOL_MAX_RT;
 	state->inf_max_rt = INF_MAX_RT;
-
 	TAILQ_INIT(&state->addrs);
-	if (dhcp6_find_delegates(ifp))
-		return 0;
 
+gogogo:
 	state->state = init_state;
 	snprintf(state->leasefile, sizeof(state->leasefile),
 	    LEASEFILE6, ifp->name,
 	    ifp->options->options & DHCPCD_PFXDLGONLY ? ".pd" : "");
-
 	if (ipv6_linklocal(ifp) == NULL) {
 		syslog(LOG_DEBUG,
 		    "%s: delaying DHCPv6 soliciation for LL address",
@@ -3188,6 +3259,8 @@ dhcp6_freedrop(struct interface *ifp, in
 
 	ifpx = dhcp6_findpfxdlgif(ifp);
 	if (ifpx) {
+		if (options & DHCPCD_EXITING)
+			ifpx->options->options |= DHCPCD_EXITING;
 		dhcp6_freedrop(ifpx, dropdele ? 1 : drop, reason);
 		TAILQ_REMOVE(ifp->ctx->ifaces, ifpx, next);
 		if_free(ifpx);
@@ -3203,7 +3276,7 @@ dhcp6_freedrop(struct interface *ifp, in
 	if (state) {
 		dhcp_auth_reset(&state->auth);
 		if (options & DHCPCD_RELEASE) {
-			if (ifp->carrier != LINK_DOWN)
+			if (ifp->carrier == LINK_UP)
 				dhcp6_startrelease(ifp);
 			unlink(state->leasefile);
 		}
Index: src/external/bsd/dhcpcd/dist/dhcp6.h
diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.2 src/external/bsd/dhcpcd/dist/dhcp6.h:1.3
--- src/external/bsd/dhcpcd/dist/dhcp6.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcp6.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp6.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: dhcp6.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -233,7 +233,8 @@ struct dhcp6_state {
 #ifdef INET6
 void dhcp6_printoptions(const struct dhcpcd_ctx *,
     const struct dhcp_opt *, size_t);
-int dhcp6_addrexists(struct dhcpcd_ctx *, const struct ipv6_addr *);
+struct ipv6_addr *dhcp6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *,
+    short);
 size_t dhcp6_find_delegates(struct interface *);
 int dhcp6_start(struct interface *, enum DH6S);
 void dhcp6_reboot(struct interface *);
@@ -246,7 +247,7 @@ int dhcp6_dadcompleted(const struct inte
 void dhcp6_drop(struct interface *, const char *);
 int dhcp6_dump(struct interface *);
 #else
-#define dhcp6_addrexists(a, b) (0)
+#define dhcp6_findaddr(a, b, c) (0)
 #define dhcp6_find_delegates(a)
 #define dhcp6_start(a, b) (0)
 #define dhcp6_reboot(a)
Index: src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-# $NetBSD: dhcpcd-definitions.conf,v 1.2 2014/10/06 18:22:29 roy Exp $
+# $NetBSD: dhcpcd-definitions.conf,v 1.3 2014/10/17 23:42:24 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.2 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.3 2014/10/17 23:42:24 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.2 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd-embedded.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: dhcpcd-embedded.h,v 1.3 2014/10/17 23:42:24 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.2 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $NetBSD: dhcpcd-run-hooks.in,v 1.2 2014/10/06 18:22:29 roy Exp $
+# $NetBSD: dhcpcd-run-hooks.in,v 1.3 2014/10/17 23:42:24 roy Exp $
 
 # dhcpcd client configuration script 
 
@@ -54,7 +54,7 @@ list_interfaces()
 		[ -e "$x" ] || continue
 		for i in $interface_order; do
 			if [ $i = "${x##*/}" ]; then
-				unset x
+				x=
 				break
 			fi
 		done
@@ -163,7 +163,7 @@ copy_file()
 		ln -sf "$1" "$2"
 	else
 		comp_file "$1" "$2" && return 1
-		cat "$2" >"$1"
+		cat "$1" >"$2"
 	fi
 }
 
Index: src/external/bsd/dhcpcd/dist/dhcpcd.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.2 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: dhcpcd.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -54,6 +54,10 @@
 #define IF_DATA_DHCP6	4
 #define IF_DATA_MAX	5
 
+/* If the interface does not support carrier status (ie PPP),
+ * dhcpcd can poll it for the relevant flags periodically */
+#define IF_POLL_UP	100	/* milliseconds */
+
 struct interface {
 	struct dhcpcd_ctx *ctx;
 	TAILQ_ENTRY(interface) next;
@@ -61,6 +65,9 @@ struct interface {
 	unsigned int index;
 	unsigned int flags;
 	sa_family_t family;
+#ifdef __FreeBSD__
+	struct sockaddr_storage linkaddr;
+#endif
 	unsigned char hwaddr[HWADDR_LEN];
 	uint8_t hwlen;
 	unsigned int metric;
Index: src/external/bsd/dhcpcd/dist/duid.c
diff -u src/external/bsd/dhcpcd/dist/duid.c:1.2 src/external/bsd/dhcpcd/dist/duid.c:1.3
--- src/external/bsd/dhcpcd/dist/duid.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/duid.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: duid.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: duid.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/duid.h
diff -u src/external/bsd/dhcpcd/dist/duid.h:1.2 src/external/bsd/dhcpcd/dist/duid.h:1.3
--- src/external/bsd/dhcpcd/dist/duid.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/duid.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: duid.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: duid.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/eloop.c
diff -u src/external/bsd/dhcpcd/dist/eloop.c:1.2 src/external/bsd/dhcpcd/dist/eloop.c:1.3
--- src/external/bsd/dhcpcd/dist/eloop.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/eloop.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: eloop.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: eloop.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/eloop.h
diff -u src/external/bsd/dhcpcd/dist/eloop.h:1.2 src/external/bsd/dhcpcd/dist/eloop.h:1.3
--- src/external/bsd/dhcpcd/dist/eloop.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/eloop.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: eloop.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: eloop.h,v 1.3 2014/10/17 23:42:24 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.2 src/external/bsd/dhcpcd/dist/if-options.h:1.3
--- src/external/bsd/dhcpcd/dist/if-options.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/if-options.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: if-options.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: if-options.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -125,6 +125,7 @@ struct if_ia {
 	uint8_t iaid_set;
 	struct in6_addr addr;
 	uint8_t prefix_len;
+	uint32_t sla_max;
 	size_t sla_len;
 	struct if_sla *sla;
 #endif
Index: src/external/bsd/dhcpcd/dist/if.c
diff -u src/external/bsd/dhcpcd/dist/if.c:1.2 src/external/bsd/dhcpcd/dist/if.c:1.3
--- src/external/bsd/dhcpcd/dist/if.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/if.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: if.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -305,7 +305,7 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 		sdl_type = 0;
 		/* Don't allow loopback unless explicit */
 		if (ifp->flags & IFF_LOOPBACK) {
-			if (argc == 0 && ctx->ifac == 0) {
+			if ((argc == 0 || argc == -1) && ctx->ifac == 0) {
 				if_free(ifp);
 				continue;
 			}
@@ -329,11 +329,22 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 			}
 #endif
 
+#ifdef __FreeBSD__
+			memcpy(&ifp->linkaddr, sdl, sdl->sdl_len);
+#endif
 			ifp->index = sdl->sdl_index;
 			sdl_type = sdl->sdl_type;
 			switch(sdl->sdl_type) {
 #ifdef IFT_BRIDGE
-			case IFT_BRIDGE: /* FALLTHROUGH */
+			case IFT_BRIDGE:
+				/* Don't allow bridge unless explicit */
+				if ((argc == 0 || argc == -1)
+				    && ctx->ifac == 0)
+				{
+					if_free(ifp);
+					continue;
+				}
+				/* FALLTHOUGH */
 #endif
 #ifdef IFT_L2VLAN
 			case IFT_L2VLAN: /* FALLTHOUGH */
@@ -379,7 +390,7 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 		if (!(ifp->flags & IFF_POINTOPOINT) &&
 		    ifp->family != ARPHRD_ETHER)
 		{
-			if (argc == 0 && ctx->ifac == 0) {
+			if ((argc == 0 || argc == -1) && ctx->ifac == 0) {
 				if_free(ifp);
 				continue;
 			}
Index: src/external/bsd/dhcpcd/dist/if.h
diff -u src/external/bsd/dhcpcd/dist/if.h:1.2 src/external/bsd/dhcpcd/dist/if.h:1.3
--- src/external/bsd/dhcpcd/dist/if.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/if.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: if.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.2 src/external/bsd/dhcpcd/dist/ipv4.c:1.3
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv4.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -49,6 +49,7 @@
 #include <unistd.h>
 
 #include "config.h"
+#include "arp.h"
 #include "common.h"
 #include "dhcpcd.h"
 #include "dhcp.h"
@@ -117,7 +118,7 @@ ipv4_getnetmask(uint32_t addr)
 }
 
 struct ipv4_addr *
-ipv4_findaddr(struct interface *ifp,
+ipv4_iffindaddr(struct interface *ifp,
     const struct in_addr *addr, const struct in_addr *net)
 {
 	struct ipv4_state *state;
@@ -134,6 +135,20 @@ ipv4_findaddr(struct interface *ifp,
 	return NULL;
 }
 
+struct ipv4_addr *
+ipv4_findaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
+{
+	struct interface *ifp;
+	struct ipv4_addr *ap;
+
+	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+		ap = ipv4_iffindaddr(ifp, addr, NULL);
+		if (ap)
+			return ap;
+	}
+	return NULL;
+}
+
 int
 ipv4_addrexists(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
 {
@@ -149,7 +164,7 @@ ipv4_addrexists(struct dhcpcd_ctx *ctx, 
 			} else if (addr->s_addr == state->addr.s_addr)
 				return 1;
 		}
-		if (addr != NULL && ipv4_findaddr(ifp, addr, NULL))
+		if (addr != NULL && ipv4_iffindaddr(ifp, addr, NULL))
 			return 1;
 	}
 	return 0;
@@ -573,7 +588,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
 	TAILQ_INIT(nrs);
 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
 		state = D_CSTATE(ifp);
-		if (state == NULL || state->new == NULL)
+		if (state == NULL || state->new == NULL || !state->added)
 			continue;
 		dnr = get_routes(ifp);
 		dnr = massage_host_routes(dnr, ifp);
@@ -670,6 +685,7 @@ delete_address(struct interface *ifp)
 	    (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
 		return 0;
 	r = delete_address1(ifp, &state->addr, &state->net);
+	state->added = 0;
 	state->addr.s_addr = 0;
 	state->net.s_addr = 0;
 	return r;
@@ -693,11 +709,30 @@ ipv4_getstate(struct interface *ifp)
 	return state;
 }
 
+static int
+ipv4_addaddr(const struct interface *ifp, const struct dhcp_lease *lease)
+{
+	int r;
+
+	syslog(LOG_DEBUG, "%s: adding IP address %s/%d",
+	    ifp->name, inet_ntoa(lease->addr),
+	    inet_ntocidr(lease->net));
+	if (ifp->options->options & DHCPCD_NOALIAS)
+		r = if_setaddress(ifp,
+		    &lease->addr, &lease->net, &lease->brd);
+	else
+		r = if_addaddress(ifp,
+		    &lease->addr, &lease->net, &lease->brd);
+	if (r == -1 && errno != EEXIST)
+		syslog(LOG_ERR, "%s: if_addaddress: %m", __func__);
+	return r;
+}
+
 void
 ipv4_applyaddr(void *arg)
 {
-	struct interface *ifp = arg;
-	struct dhcp_state *state = D_STATE(ifp);
+	struct interface *ifp = arg, *ifn;
+	struct dhcp_state *state = D_STATE(ifp), *nstate;
 	struct dhcp_message *dhcp;
 	struct dhcp_lease *lease;
 	struct if_options *ifo = ifp->options;
@@ -716,40 +751,96 @@ ipv4_applyaddr(void *arg)
 	lease = &state->lease;
 
 	if (dhcp == NULL) {
-		ipv4_buildroutes(ifp->ctx);
 		if ((ifo->options & (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
 		{
-			if (state->addr.s_addr != 0)
+			if (state->added) {
+				struct in_addr addr;
+
+				addr = state->addr;
 				delete_address(ifp);
+				TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
+					if (ifn == ifp ||
+					    strcmp(ifn->name, ifp->name) == 0)
+						continue;
+					nstate = D_STATE(ifn);
+					if (nstate && !nstate->added &&
+					    nstate->addr.s_addr == addr.s_addr)
+					{
+						if (ifn->options->options &
+						    DHCPCD_ARP)
+						{
+							nstate->claims = 0;
+							nstate->probes = 0;
+							nstate->conflicts = 0;
+							arp_probe(ifn);
+						} else {
+							ipv4_addaddr(ifn,
+							    &nstate->lease);
+							nstate->added = 1;
+						}
+						break;
+					}
+				}
+			}
+			ipv4_buildroutes(ifp->ctx);
 			script_runreason(ifp, state->reason);
-		}
+		} else
+			ipv4_buildroutes(ifp->ctx);
 		return;
 	}
 
+	/* Ensure only one interface has the address */
+	TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
+		if (ifn == ifp || strcmp(ifn->name, ifp->name) == 0)
+			continue;
+		nstate = D_STATE(ifn);
+		if (nstate && nstate->added &&
+		    nstate->addr.s_addr == lease->addr.s_addr)
+		{
+			if (ifn->metric <= ifp->metric) {
+				syslog(LOG_INFO, "%s: preferring %s on %s",
+				    ifp->name,
+				    inet_ntoa(lease->addr),
+				    ifn->name);
+				state->addr.s_addr = lease->addr.s_addr;
+				state->net.s_addr = lease->net.s_addr;
+				goto routes;
+			}
+			syslog(LOG_INFO, "%s: preferring %s on %s",
+			    ifn->name,
+			    inet_ntoa(lease->addr),
+			    ifp->name);
+			delete_address1(ifn, &nstate->addr, &nstate->net);
+			nstate->added = 0;
+			break;
+		}
+	}
+
+	/* Does another interface already have the address from a prior boot? */
+	if (ifn == NULL) {
+		TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
+			if (ifn == ifp || strcmp(ifn->name, ifp->name) == 0)
+				continue;
+			ap = ipv4_iffindaddr(ifn, &lease->addr, NULL);
+			if (ap)
+				delete_address1(ifn, &ap->addr, &ap->net);
+		}
+	}
+
 	/* If the netmask is different, delete the addresss */
-	ap = ipv4_findaddr(ifp, &lease->addr, NULL);
+	ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
 	if (ap && ap->net.s_addr != lease->net.s_addr)
 		delete_address1(ifp, &ap->addr, &ap->net);
 
-	if (ipv4_findaddr(ifp, &lease->addr, &lease->net))
+	if (ipv4_iffindaddr(ifp, &lease->addr, &lease->net))
 		syslog(LOG_DEBUG, "%s: IP address %s/%d already exists",
 		    ifp->name, inet_ntoa(lease->addr),
 		    inet_ntocidr(lease->net));
 	else {
-		syslog(LOG_DEBUG, "%s: adding IP address %s/%d",
-		    ifp->name, inet_ntoa(lease->addr),
-		    inet_ntocidr(lease->net));
-		if (ifo->options & DHCPCD_NOALIAS)
-			r = if_setaddress(ifp,
-			    &lease->addr, &lease->net, &lease->brd);
-		else
-			r = if_addaddress(ifp,
-			    &lease->addr, &lease->net, &lease->brd);
-		if (r == -1 && errno != EEXIST) {
-			syslog(LOG_ERR, "%s: if_addaddress: %m", __func__);
+		r = ipv4_addaddr(ifp, lease);
+		if (r == -1 && errno != EEXIST)
 			return;
-		}
 		istate = ipv4_getstate(ifp);
 		ap = malloc(sizeof(*ap));
 		ap->addr = lease->addr;
@@ -763,6 +854,7 @@ ipv4_applyaddr(void *arg)
 	    state->addr.s_addr != 0)
 		delete_address(ifp);
 
+	state->added = 1;
 	state->addr.s_addr = lease->addr.s_addr;
 	state->net.s_addr = lease->net.s_addr;
 
@@ -777,11 +869,8 @@ ipv4_applyaddr(void *arg)
 		free(rt);
 	}
 
+routes:
 	ipv4_buildroutes(ifp->ctx);
-	if (!state->lease.frominfo &&
-	    !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))
-		if (write_lease(ifp, dhcp) == -1)
-			syslog(LOG_ERR, "%s: write_lease: %m", __func__);
 	script_runreason(ifp, state->reason);
 }
 
@@ -820,7 +909,7 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
 		return;
 	}
 
-	ap = ipv4_findaddr(ifp, addr, net);
+	ap = ipv4_iffindaddr(ifp, addr, net);
 	if (type == RTM_NEWADDR && ap == NULL) {
 		ap = malloc(sizeof(*ap));
 		if (ap == NULL) {
Index: src/external/bsd/dhcpcd/dist/ipv4.h
diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.2 src/external/bsd/dhcpcd/dist/ipv4.h:1.3
--- src/external/bsd/dhcpcd/dist/ipv4.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv4.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: ipv4.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -72,8 +72,9 @@ void ipv4_buildroutes(struct dhcpcd_ctx 
 void ipv4_applyaddr(void *);
 int ipv4_routedeleted(struct dhcpcd_ctx *, const struct rt *);
 
-struct ipv4_addr *ipv4_findaddr(struct interface *,
+struct ipv4_addr *ipv4_iffindaddr(struct interface *,
     const struct in_addr *, const struct in_addr *);
+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.2 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.3
--- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv4ll.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4ll.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: ipv4ll.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -35,6 +35,7 @@
 #include <syslog.h>
 #include <unistd.h>
 
+#define ELOOP_QUEUE 2
 #include "config.h"
 #include "arp.h"
 #include "common.h"
Index: src/external/bsd/dhcpcd/dist/ipv4ll.h
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.h:1.2 src/external/bsd/dhcpcd/dist/ipv4ll.h:1.3
--- src/external/bsd/dhcpcd/dist/ipv4ll.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv4ll.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4ll.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: ipv4ll.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.2 src/external/bsd/dhcpcd/dist/ipv6.c:1.3
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv6.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.2 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -152,16 +152,6 @@ ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx)
 	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;
 }
@@ -593,14 +583,55 @@ ipv6_checkaddrflags(void *arg)
 }
 #endif
 
+
+static void
+ipv6_deleteaddr(struct ipv6_addr *addr)
+{
+	struct ipv6_state *state;
+	struct ipv6_addr *ap;
+
+	syslog(LOG_INFO, "%s: deleting address %s",
+	    addr->iface->name, addr->saddr);
+	if (if_deladdress6(addr) == -1 &&
+	    errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV)
+		syslog(LOG_ERR, "if_deladdress6: :%m");
+
+	state = IPV6_STATE(addr->iface);
+	TAILQ_FOREACH(ap, &state->addrs, next) {
+		if (IN6_ARE_ADDR_EQUAL(&ap->addr, &addr->addr)) {
+			TAILQ_REMOVE(&state->addrs, ap, next);
+			free(ap);
+			break;
+		}
+	}
+}
+
 int
 ipv6_addaddr(struct ipv6_addr *ap)
 {
+	struct interface *ifp;
+	struct ipv6_state *state;
+	struct ipv6_addr *nap;
+
+	/* Ensure no other interface has this address */
+	TAILQ_FOREACH(ifp, ap->iface->ctx->ifaces, next) {
+		if (ifp == ap->iface || strcmp(ifp->name, ap->iface->name) == 0)
+			continue;
+		state = IPV6_STATE(ifp);
+		if (state == NULL)
+			continue;
+		TAILQ_FOREACH(nap, &state->addrs, next) {
+			if (IN6_ARE_ADDR_EQUAL(&nap->addr, &ap->addr)) {
+				ipv6_deleteaddr(nap);
+				break;
+			}
+		}
+	}
 
 	syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
 	    "%s: adding address %s", ap->iface->name, ap->saddr);
 	if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
-	    ipv6_findaddr(ap->iface, &ap->addr))
+	    ipv6_iffindaddr(ap->iface, &ap->addr))
 		ap->flags |= IPV6_AF_DADCOMPLETED;
 	if (if_addaddress6(ap) == -1) {
 		syslog(LOG_ERR, "if_addaddress6: %m");
@@ -646,23 +677,36 @@ ipv6_addaddr(struct ipv6_addr *ap)
 	return 0;
 }
 
+struct ipv6_addr *
+ipv6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr, short flags)
+{
+	struct ipv6_addr *dap, *nap;
+
+	dap = dhcp6_findaddr(ctx, addr, flags);
+	nap = ipv6nd_findaddr(ctx, addr, flags);
+	if (!dap && !nap)
+		return NULL;
+	if (dap && !nap)
+		return dap;
+	if (nap && !dap)
+		return nap;
+	if (nap->iface->metric < dap->iface->metric)
+		return nap;
+	return dap;
+}
+
 ssize_t
 ipv6_addaddrs(struct ipv6_addrhead *addrs)
 {
-	struct ipv6_addr *ap, *apn;
+	struct ipv6_addr *ap, *apn, *apf;
 	ssize_t i;
 
 	i = 0;
 	TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
 		if (ap->prefix_vltime == 0) {
 			if (ap->flags & IPV6_AF_ADDED) {
-				syslog(LOG_INFO, "%s: deleting address %s",
-				    ap->iface->name, ap->saddr);
+				ipv6_deleteaddr(ap);
 				i++;
-				if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr) &&
-				    if_deladdress6(ap) == -1 &&
-				    errno != EADDRNOTAVAIL && errno != ENXIO)
-					syslog(LOG_ERR, "if_deladdress6: %m");
 			}
 			eloop_q_timeout_delete(ap->iface->ctx->eloop,
 			    0, NULL, ap);
@@ -672,7 +716,34 @@ ipv6_addaddrs(struct ipv6_addrhead *addr
 				TAILQ_REMOVE(addrs, ap, next);
 				free(ap);
 			}
-		} else if (!IN6_IS_ADDR_UNSPECIFIED(&ap->addr)) {
+		} else if (!(ap->flags & IPV6_AF_STALE) &&
+		    !IN6_IS_ADDR_UNSPECIFIED(&ap->addr))
+		{
+			apf = ipv6_findaddr(ap->iface->ctx,
+			    &ap->addr, IPV6_AF_ADDED);
+			if (apf && apf->iface != ap->iface &&
+			    strcmp(apf->iface->name, ap->iface->name))
+			{
+				if (apf->iface->metric <= ap->iface->metric) {
+					syslog(LOG_INFO,
+					    "%s: preferring %s on %s",
+					    ap->iface->name,
+					    ap->saddr,
+					    apf->iface->name);
+					continue;
+				}
+				syslog(LOG_INFO,
+				    "%s: preferring %s on %s",
+				    apf->iface->name,
+				    ap->saddr,
+				    ap->iface->name);
+				if (if_deladdress6(apf) == -1 &&
+				    errno != EADDRNOTAVAIL && errno != ENXIO)
+					syslog(LOG_ERR, "if_deladdress6: %m");
+				apf->flags &=
+				    ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
+			} else if (apf)
+				apf->flags &= ~IPV6_AF_ADDED;
 			if (ap->flags & IPV6_AF_NEW)
 				i++;
 			ipv6_addaddr(ap);
@@ -682,33 +753,31 @@ ipv6_addaddrs(struct ipv6_addrhead *addr
 	return i;
 }
 
-
 void
 ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
     const struct interface *ifd)
 {
-	struct ipv6_addr *ap, *apn;
+	struct ipv6_addr *ap, *apn, *apf;
 
 	TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
 		if (ifd && ap->delegating_iface != ifd)
 			continue;
 		TAILQ_REMOVE(addrs, ap, next);
 		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. */
 		if (drop && ap->flags & IPV6_AF_ADDED &&
-		    !ipv6nd_addrexists(ap->iface->ctx, ap) &&
-		    !dhcp6_addrexists(ap->iface->ctx, ap) &&
 		    (ap->iface->options->options &
 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
 		{
-			syslog(LOG_INFO, "%s: deleting address %s",
-			    ap->iface->name, ap->saddr);
-			if (if_deladdress6(ap) == -1 &&
-			    errno != EADDRNOTAVAIL && errno != ENXIO)
-				syslog(LOG_ERR, "if_deladdress6: :%m");
+			/* Find the same address somewhere else */
+			apf = ipv6_findaddr(ap->iface->ctx, &ap->addr, 0);
+			if (apf == NULL ||
+			    (apf->iface != ap->iface &&
+			    strcmp(apf->iface->name, ap->iface->name)))
+				ipv6_deleteaddr(ap);
+			if (!(ap->iface->options->options &
+			    DHCPCD_EXITING) && apf)
+				ipv6_addaddr(apf);
 		}
 		free(ap);
 	}
@@ -787,6 +856,8 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 				ap = calloc(1, sizeof(*ap));
 				ap->iface = ifp;
 				ap->addr = *addr;
+				inet_ntop(AF_INET6, &addr->s6_addr,
+				    ap->saddr, sizeof(ap->saddr));
 				TAILQ_INSERT_TAIL(&state->addrs,
 				    ap, next);
 			}
@@ -825,7 +896,7 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 }
 
 const struct ipv6_addr *
-ipv6_findaddr(const struct interface *ifp, const struct in6_addr *addr)
+ipv6_iffindaddr(const struct interface *ifp, const struct in6_addr *addr)
 {
 	const struct ipv6_state *state;
 	const struct ipv6_addr *ap;
@@ -1069,10 +1140,11 @@ ipv6_handleifa_addrs(int cmd,
 		}
 		switch (cmd) {
 		case RTM_DELADDR:
-			syslog(LOG_INFO, "%s: deleted address %s",
-			    ap->iface->name, ap->saddr);
-			TAILQ_REMOVE(addrs, ap, next);
-			free(ap);
+			if (ap->flags & IPV6_AF_ADDED) {
+				syslog(LOG_INFO, "%s: deleted address %s",
+				    ap->iface->name, ap->saddr);
+				ap->flags &= ~IPV6_AF_ADDED;
+			}
 			break;
 		case RTM_NEWADDR:
 			/* Safety - ignore tentative announcements */
@@ -1144,6 +1216,9 @@ ipv6_routedeleted(struct dhcpcd_ctx *ctx
 {
 	struct rt6 *f;
 
+	if (ctx->ipv6 == NULL)
+		return 0;
+
 	f = find_route6(ctx->ipv6->routes, rt);
 	if (f == NULL)
 		return 0;
Index: src/external/bsd/dhcpcd/dist/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.2 src/external/bsd/dhcpcd/dist/ipv6.h:1.3
--- src/external/bsd/dhcpcd/dist/ipv6.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv6.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -161,9 +161,6 @@ struct ipv6_ctx {
 	const char *sfrom;
 
 	int nd_fd;
-#ifdef IPV6_POLLADDRFLAG
-	uint8_t polladdr_warned;
-#endif
 	struct ra_head *ra_routers;
 	struct rt6_head *routes;
 
@@ -193,9 +190,11 @@ void ipv6_handleifa(struct dhcpcd_ctx *c
     const char *, const struct in6_addr *, int);
 int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
     const struct in6_addr *, int);
-const struct ipv6_addr *ipv6_findaddr(const struct interface *,
+const struct ipv6_addr *ipv6_iffindaddr(const struct interface *,
     const struct in6_addr *);
-#define ipv6_linklocal(ifp) (ipv6_findaddr((ifp), NULL))
+struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *,
+    const struct in6_addr *, short);
+#define ipv6_linklocal(ifp) (ipv6_iffindaddr((ifp), NULL))
 int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *);
 void ipv6_free_ll_callbacks(struct interface *);
 int ipv6_start(struct interface *);
Index: src/external/bsd/dhcpcd/dist/ipv6nd.h
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.h:1.2 src/external/bsd/dhcpcd/dist/ipv6nd.h:1.3
--- src/external/bsd/dhcpcd/dist/ipv6nd.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6nd.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: ipv6nd.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -39,7 +39,7 @@
 
 struct ra_opt {
 	TAILQ_ENTRY(ra_opt) next;
-	uint8_t type;
+	uint16_t type;
 	struct timeval expire;
 	char *option;
 };
@@ -87,7 +87,8 @@ struct rs_state {
 #ifdef INET6
 void ipv6nd_startrs(struct interface *);
 ssize_t ipv6nd_env(char **, const char *, const struct interface *);
-int ipv6nd_addrexists(struct dhcpcd_ctx *, const struct ipv6_addr *);
+struct ipv6_addr *ipv6nd_findaddr(struct dhcpcd_ctx *,
+    const struct in6_addr *, short);
 void ipv6nd_freedrop_ra(struct ra *, int);
 #define ipv6nd_free_ra(ra) ipv6nd_freedrop_ra((ra),  0)
 #define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra),  1)
@@ -105,7 +106,7 @@ void ipv6nd_neighbour(struct dhcpcd_ctx 
 #endif
 #else
 #define ipv6nd_startrs(a) {}
-#define ipv6nd_addrexists(a, b) (0)
+#define ipv6nd_findaddr(a, b, c) (0)
 #define ipv6nd_free(a)
 #define ipv6nd_hasra(a) (0)
 #define ipv6nd_dadcompleted(a) (0)
Index: src/external/bsd/dhcpcd/dist/script.h
diff -u src/external/bsd/dhcpcd/dist/script.h:1.2 src/external/bsd/dhcpcd/dist/script.h:1.3
--- src/external/bsd/dhcpcd/dist/script.h:1.2	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/script.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: script.h,v 1.2 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: script.h,v 1.3 2014/10/17 23:42:24 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.5 src/external/bsd/dhcpcd/dist/bpf-filter.h:1.6
--- src/external/bsd/dhcpcd/dist/bpf-filter.h:1.5	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/bpf-filter.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf-filter.h,v 1.5 2014/10/06 18:22:29 roy Exp $ */
+/* $NetBSD: bpf-filter.h,v 1.6 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon

Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.18 src/external/bsd/dhcpcd/dist/dhcp.c:1.19
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.18	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcp.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.18 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.19 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -1046,7 +1046,7 @@ toobig:
 	return -1;
 }
 
-ssize_t
+static ssize_t
 write_lease(const struct interface *ifp, const struct dhcp_message *dhcp)
 {
 	int fd;
@@ -1091,7 +1091,7 @@ write_lease(const struct interface *ifp,
 	return bytes;
 }
 
-struct dhcp_message *
+static struct dhcp_message *
 read_lease(struct interface *ifp)
 {
 	int fd;
@@ -1604,7 +1604,7 @@ send_message(struct interface *iface, ui
 	if (dhcp_open(iface) == -1)
 		return;
 
-	if (state->addr.s_addr != INADDR_ANY &&
+	if (state->added && state->addr.s_addr != INADDR_ANY &&
 	    state->new != NULL &&
 	    (state->new->cookie == htonl(MAGIC_COOKIE) ||
 	    iface->options->options & DHCPCD_INFORM))
@@ -1843,29 +1843,31 @@ dhcp_rebind(void *arg)
 void
 dhcp_bind(void *arg)
 {
-	struct interface *iface = arg;
-	struct dhcp_state *state = D_STATE(iface);
-	struct if_options *ifo = iface->options;
+	struct interface *ifp = arg;
+	struct dhcp_state *state = D_STATE(ifp);
+	struct if_options *ifo = ifp->options;
 	struct dhcp_lease *lease = &state->lease;
 	struct timeval tv;
 	uint8_t ipv4ll = 0;
 
+	if (state->state == DHS_BOUND)
+		goto applyaddr;
 	state->reason = NULL;
 	state->xid = 0;
 	free(state->old);
 	state->old = state->new;
 	state->new = state->offer;
 	state->offer = NULL;
-	get_lease(iface->ctx, lease, state->new);
+	get_lease(ifp->ctx, lease, state->new);
 	if (ifo->options & DHCPCD_STATIC) {
 		syslog(LOG_INFO, "%s: using static address %s/%d",
-		    iface->name, inet_ntoa(lease->addr),
+		    ifp->name, inet_ntoa(lease->addr),
 		    inet_ntocidr(lease->net));
 		lease->leasetime = ~0U;
 		state->reason = "STATIC";
 	} else if (state->new->cookie != htonl(MAGIC_COOKIE)) {
 		syslog(LOG_INFO, "%s: using IPv4LL address %s",
-		    iface->name, inet_ntoa(lease->addr));
+		    ifp->name, inet_ntoa(lease->addr));
 		lease->leasetime = ~0U;
 		state->reason = "IPV4LL";
 		ipv4ll = 1;
@@ -1874,8 +1876,8 @@ dhcp_bind(void *arg)
 			lease->addr.s_addr = ifo->req_addr.s_addr;
 		else
 			lease->addr.s_addr = state->addr.s_addr;
-		syslog(LOG_INFO, "%s: received approval for %s", iface->name,
-		    inet_ntoa(lease->addr));
+		syslog(LOG_INFO, "%s: received approval for %s",
+		    ifp->name, inet_ntoa(lease->addr));
 		lease->leasetime = ~0U;
 		state->reason = "INFORM";
 	} else {
@@ -1888,12 +1890,12 @@ dhcp_bind(void *arg)
 			    lease->rebindtime =
 			    lease->leasetime;
 			syslog(LOG_INFO, "%s: leased %s for infinity",
-			    iface->name, inet_ntoa(lease->addr));
+			    ifp->name, inet_ntoa(lease->addr));
 		} else {
 			if (lease->leasetime < DHCP_MIN_LEASE) {
 				syslog(LOG_WARNING,
 				    "%s: minimum lease is %d seconds",
-				    iface->name, DHCP_MIN_LEASE);
+				    ifp->name, DHCP_MIN_LEASE);
 				lease->leasetime = DHCP_MIN_LEASE;
 			}
 			if (lease->rebindtime == 0)
@@ -1905,7 +1907,7 @@ dhcp_bind(void *arg)
 				syslog(LOG_WARNING,
 				    "%s: rebind time greater than lease "
 				    "time, forcing to %"PRIu32" seconds",
-				    iface->name, lease->rebindtime);
+				    ifp->name, lease->rebindtime);
 			}
 			if (lease->renewaltime == 0)
 				lease->renewaltime =
@@ -1916,18 +1918,18 @@ dhcp_bind(void *arg)
 				syslog(LOG_WARNING,
 				    "%s: renewal time greater than rebind "
 				    "time, forcing to %"PRIu32" seconds",
-				    iface->name, lease->renewaltime);
+				    ifp->name, lease->renewaltime);
 			}
 			syslog(lease->addr.s_addr == state->addr.s_addr ?
 			    LOG_DEBUG : LOG_INFO,
-			    "%s: leased %s for %"PRIu32" seconds", iface->name,
+			    "%s: leased %s for %"PRIu32" seconds", ifp->name,
 			    inet_ntoa(lease->addr), lease->leasetime);
 		}
 	}
-	if (iface->ctx->options & DHCPCD_TEST) {
+	if (ifp->ctx->options & DHCPCD_TEST) {
 		state->reason = "TEST";
-		script_runreason(iface, state->reason);
-		eloop_exit(iface->ctx->eloop, EXIT_SUCCESS);
+		script_runreason(ifp, state->reason);
+		eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
 		return;
 	}
 	if (state->reason == NULL) {
@@ -1945,25 +1947,32 @@ dhcp_bind(void *arg)
 	if (lease->leasetime == ~0U)
 		lease->renewaltime = lease->rebindtime = lease->leasetime;
 	else {
-		eloop_timeout_add_sec(iface->ctx->eloop,
-		    (time_t)lease->renewaltime, dhcp_renew, iface);
-		eloop_timeout_add_sec(iface->ctx->eloop,
-		    (time_t)lease->rebindtime, dhcp_rebind, iface);
-		eloop_timeout_add_sec(iface->ctx->eloop,
-		    (time_t)lease->leasetime, dhcp_expire, iface);
+		eloop_timeout_add_sec(ifp->ctx->eloop,
+		    (time_t)lease->renewaltime, dhcp_renew, ifp);
+		eloop_timeout_add_sec(ifp->ctx->eloop,
+		    (time_t)lease->rebindtime, dhcp_rebind, ifp);
+		eloop_timeout_add_sec(ifp->ctx->eloop,
+		    (time_t)lease->leasetime, dhcp_expire, ifp);
 		syslog(LOG_DEBUG,
 		    "%s: renew in %"PRIu32" seconds, rebind in %"PRIu32
 		    " seconds",
-		    iface->name, lease->renewaltime, lease->rebindtime);
+		    ifp->name, lease->renewaltime, lease->rebindtime);
 	}
-	ipv4_applyaddr(iface);
-	if (dhcpcd_daemonise(iface->ctx) == 0) {
+	state->state = DHS_BOUND;
+	if (!state->lease.frominfo &&
+	    !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))
+		if (write_lease(ifp, state->new) == -1)
+			syslog(LOG_ERR, "%s: write_lease: %m", __func__);
+
+applyaddr:
+	ipv4_applyaddr(ifp);
+	if (dhcpcd_daemonise(ifp->ctx) == 0) {
 		if (!ipv4ll)
-			arp_close(iface);
-		state->state = DHS_BOUND;
+			arp_close(ifp);
 		if (ifo->options & DHCPCD_ARP) {
 		        state->claims = 0;
-			arp_announce(iface);
+			if (state->added)
+				arp_announce(ifp);
 		}
 	}
 }
@@ -2039,7 +2048,7 @@ dhcp_inform(struct interface *ifp)
 	} else {
 		if (ifo->req_addr.s_addr == INADDR_ANY) {
 			state = D_STATE(ifp);
-			ap = ipv4_findaddr(ifp, NULL, NULL);
+			ap = ipv4_iffindaddr(ifp, NULL, NULL);
 			if (ap == NULL) {
 				syslog(LOG_INFO,
 					"%s: waiting for 3rd party to "
@@ -2113,7 +2122,8 @@ dhcp_reboot(struct interface *ifp)
 	} else if (state->offer->cookie == 0) {
 		if (ifo->options & DHCPCD_IPV4LL) {
 			state->claims = 0;
-			arp_announce(ifp);
+			if (state->added)
+				arp_announce(ifp);
 		} else
 			dhcp_discover(ifp);
 		return;
@@ -2152,13 +2162,16 @@ dhcp_drop(struct interface *ifp, const c
 	struct timespec ts;
 #endif
 
+	/* 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)
 		return;
 	dhcp_auth_reset(&state->auth);
 	dhcp_close(ifp);
 	arp_close(ifp);
-	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 	if (ifp->options->options & DHCPCD_RELEASE) {
 		unlink(state->leasefile);
 		if (ifp->carrier != LINK_DOWN &&
@@ -2566,7 +2579,7 @@ dhcp_handledhcp(struct interface *iface,
 		/* If the interface already has the address configured
 		 * then we can't ARP for duplicate detection. */
 		addr.s_addr = state->offer->yiaddr;
-		if (!ipv4_findaddr(iface, &addr, NULL)) {
+		if (!ipv4_iffindaddr(iface, &addr, NULL)) {
 			state->claims = 0;
 			state->probes = 0;
 			state->conflicts = 0;

Index: src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.8 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.9
--- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in:1.8	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd-run-hooks.8.in,v 1.8 2014/10/06 18:22:29 roy Exp $
+.\"     $NetBSD: dhcpcd-run-hooks.8.in,v 1.9 2014/10/17 23:42:24 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.32 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.33
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.32	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.8.in,v 1.32 2014/10/06 18:22:29 roy Exp $
+.\"     $NetBSD: dhcpcd.8.in,v 1.33 2014/10/17 23:42:24 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.12 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.13
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.12	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.12 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.13 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -207,7 +207,7 @@ handle_exit_timeout(void *arg)
 		return;
 	}
 	ctx->options &= ~DHCPCD_TIMEOUT_IPV4LL;
-	timeout = (PROBE_NUM * PROBE_MAX) + (PROBE_WAIT * 2);
+	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);
 }
@@ -234,14 +234,14 @@ dhcpcd_ipwaited(struct dhcpcd_ctx *ctx)
 	    !ipv4_addrexists(ctx, NULL))
 		return 0;
 	if (ctx->options & DHCPCD_WAITIP6 &&
-	    !ipv6nd_addrexists(ctx, NULL) &&
-	    !dhcp6_addrexists(ctx, NULL))
+	    !ipv6nd_findaddr(ctx, NULL, 0) &&
+	    !dhcp6_findaddr(ctx, NULL, 0))
 		return 0;
 	if (ctx->options & DHCPCD_WAITIP &&
 	    !(ctx->options & (DHCPCD_WAITIP4 | DHCPCD_WAITIP6)) &&
 	    !ipv4_addrexists(ctx, NULL) &&
-	    !ipv6nd_addrexists(ctx, NULL) &&
-	    !dhcp6_addrexists(ctx, NULL))
+	    !ipv6nd_findaddr(ctx, NULL, 0) &&
+	    !dhcp6_findaddr(ctx, NULL, 0))
 		return 0;
 	return 1;
 }
@@ -643,10 +643,8 @@ dhcpcd_startinterface(void *arg)
 	struct if_options *ifo = ifp->options;
 	size_t i;
 	char buf[DUID_LEN * 3];
-
-	pre_start(ifp);
-	if (if_up(ifp) == -1)
-		syslog(LOG_ERR, "%s: if_up: %m", ifp->name);
+	int carrier;
+	struct timeval tv;
 
 	if (ifo->options & DHCPCD_LINK) {
 		switch (ifp->carrier) {
@@ -657,18 +655,15 @@ dhcpcd_startinterface(void *arg)
 			return;
 		case LINK_UNKNOWN:
 			/* No media state available.
-			 * Any change on state such as IFF_UP and IFF_RUNNING
-			 * should be reported to us via the route socket
-			 * as we've done the best we can to bring the interface
-			 * up at this point. */
-			ifp->carrier = if_carrier(ifp);
-			if (ifp->carrier == LINK_UNKNOWN) {
-				syslog(LOG_INFO, "%s: unknown carrier",
-				    ifp->name);
-				return;
-			}
-			dhcpcd_handlecarrier(ifp->ctx, ifp->carrier,
-			    ifp->flags, ifp->name);
+			 * Loop until both IFF_UP and IFF_RUNNING are set */
+			if ((carrier = if_carrier(ifp)) == LINK_UNKNOWN) {
+				tv.tv_sec = 0;
+				tv.tv_usec = IF_POLL_UP * 1000;
+				eloop_timeout_add_tv(ifp->ctx->eloop,
+				    &tv, dhcpcd_startinterface, ifp);
+			} else
+				dhcpcd_handlecarrier(ifp->ctx, carrier,
+				    ifp->flags, ifp->name);
 			return;
 		}
 	}
@@ -712,6 +707,9 @@ dhcpcd_startinterface(void *arg)
 		    !(ifo->options & (DHCPCD_INFORM | DHCPCD_PFXDLGONLY)))
 			ipv6nd_startrs(ifp);
 
+		if (ifo->options & DHCPCD_DHCP6)
+			dhcp6_find_delegates(ifp);
+
 		if (!(ifo->options & DHCPCD_IPV6RS) ||
 		    ifo->options & DHCPCD_IA_FORCED)
 		{
@@ -720,7 +718,6 @@ dhcpcd_startinterface(void *arg)
 			if (ifo->options & DHCPCD_IA_FORCED)
 				nolease = dhcp6_start(ifp, DH6S_INIT);
 			else {
-				dhcp6_find_delegates(ifp);
 				nolease = 0;
 				/* Enabling the below doesn't really make
 				 * sense as there is currently no standard
@@ -749,6 +746,33 @@ dhcpcd_startinterface(void *arg)
 }
 
 static void
+dhcpcd_prestartinterface(void *arg)
+{
+	struct interface *ifp = arg;
+
+	pre_start(ifp);
+	if (if_up(ifp) == -1)
+		syslog(LOG_ERR, "%s: if_up: %m", ifp->name);
+
+	if (ifp->options->options & DHCPCD_LINK &&
+	    ifp->carrier == LINK_UNKNOWN)
+	{
+		int carrier;
+
+		if ((carrier = if_carrier(ifp)) != LINK_UNKNOWN) {
+			dhcpcd_handlecarrier(ifp->ctx, carrier,
+			    ifp->flags, ifp->name);
+			return;
+		}
+		syslog(LOG_INFO,
+		    "%s: unknown carrier, waiting for interface flags",
+		    ifp->name);
+	}
+
+	dhcpcd_startinterface(ifp);
+}
+
+static void
 handle_link(void *arg)
 {
 	struct dhcpcd_ctx *ctx;
@@ -806,8 +830,7 @@ run_preinit(struct interface *ifp)
 
 	script_runreason(ifp, "PREINIT");
 
-	if (ifp->carrier != LINK_UNKNOWN &&
-	    ifp->options->options & DHCPCD_LINK)
+	if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN)
 		script_runreason(ifp,
 		    ifp->carrier == LINK_UP ? "CARRIER" : "NOCARRIER");
 }
@@ -867,7 +890,7 @@ dhcpcd_handleinterface(void *arg, int ac
 			iff = ifp;
 		}
 		if (action > 0)
-			dhcpcd_startinterface(iff);
+			dhcpcd_prestartinterface(iff);
 	}
 
 	/* Free our discovered list */
@@ -918,7 +941,7 @@ if_reboot(struct interface *ifp, int arg
 	configure_interface(ifp, argc, argv);
 	dhcp_reboot_newopts(ifp, oldopts);
 	dhcp6_reboot(ifp);
-	dhcpcd_startinterface(ifp);
+	dhcpcd_prestartinterface(ifp);
 }
 
 static void
@@ -944,7 +967,7 @@ reconf_reboot(struct dhcpcd_ctx *ctx, in
 			TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next);
 			dhcpcd_initstate1(ifp, argc, argv);
 			run_preinit(ifp);
-			dhcpcd_startinterface(ifp);
+			dhcpcd_prestartinterface(ifp);
 		}
 	}
 	free(ifs);
@@ -1613,11 +1636,6 @@ main(int argc, char **argv)
 	}
 #endif
 
-#ifdef __FreeBSD__
-	syslog(LOG_WARNING, "FreeBSD errors that are worked around:");
-	syslog(LOG_WARNING, "IPv4 subnet routes cannot be deleted");
-#endif
-
 	/* When running dhcpcd against a single interface, we need to retain
 	 * the old behaviour of waiting for an IP address */
 	if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND))
@@ -1699,7 +1717,8 @@ main(int argc, char **argv)
 
 	ipv4_sortinterfaces(&ctx);
 	TAILQ_FOREACH(ifp, ctx.ifaces, next) {
-		eloop_timeout_add_sec(ctx.eloop, 0, dhcpcd_startinterface, ifp);
+		eloop_timeout_add_sec(ctx.eloop, 0,
+		    dhcpcd_prestartinterface, ifp);
 	}
 
 	i = eloop_start(&ctx);
Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.12 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.13
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.12	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.conf.5.in,v 1.12 2014/10/06 18:22:29 roy Exp $
+.\"     $NetBSD: dhcpcd.conf.5.in,v 1.13 2014/10/17 23:42:24 roy Exp $
 .\" Copyright (c) 2006-2014 Roy Marples
 .\" All rights reserved
 .\"
@@ -295,22 +295,27 @@ You can specify multiple
 per
 .Ic ia_pd ,
 space separated.
-IPv6RS should be disabled globally when requesting a Prefix Delegation like so:
+IPv6RS should be disabled globally when requesting a Prefix Delegation.
 .Pp
-.D1 # Global settings, disable IPv4 and IPv6RS
-.D1 noipv4
-.D1 noipv6rs
-.D1 # Don't touch eth3 at all
-.D1 denyinterfaces eth3 
-.Pp
-.D1 interface eth0
-.D1 ia_pd 1 eth1/1 eth2/2
-.Pp
-.D1 # Enable automatic address configuration for eth1
-.D1 # eth1 still gets a delegated prefix
-.D1 interface eth1
-.D1 ipv4
-.D1 ipv6rs
+In the following example eth0 is the externally facing interface to be
+configured for both IPv4 and IPv6.
+The DHCPv4 server will provide us with an IPv4 address and a default route.
+The DHCPv6 server is going to provide us with an IPv6 address, a default
+route and a /64 subnet to be delegated to the internal interface.
+The eth1 interface will be automatically configured
+for IPv6 using the first address (::1) from the delegated prefix.
+.Xr rtadvd 8
+can be used with an empty configuration file on eth1 to provide automatic
+IPv6 address configuration for the internal network.
+.Bd -literal -indent
+noipv6rs            # disable routing solicitation
+denyinterfaces eth2 # Don't touch eth2 at all
+interface eth0
+    ipv6rs	    # enable routing solicitation get the
+		    # default IPv6 route
+    ia_na 1	    # request an IPv6 address
+    ia_pd 2 eth1/0  # get a /64 and assign it to eth1
+.Ed
 .It Ic ia_pd_mix
 To be RFC compliant,
 .Nm dhcpcd

Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.11 src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.12
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.11	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-# $NetBSD: dhcpcd.conf,v 1.11 2014/10/06 18:22:29 roy Exp $
+# $NetBSD: dhcpcd.conf,v 1.12 2014/10/17 23:42:24 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.11 src/external/bsd/dhcpcd/dist/if-bsd.c:1.12
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.11	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/if-bsd.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.11 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.12 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -147,6 +147,19 @@ if_openlinksocket(void)
 #endif
 }
 
+static void
+if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp)
+{
+
+#ifdef __FreeBSD__
+	memcpy(sdl, &ifp->linkaddr, sizeof(*sdl));
+	sdl->sdl_nlen = sdl->sdl_alen = sdl->sdl_slen = 0;
+#else
+	sdl->sdl_len = sizeof(*sdl);
+	link_addr(ifp->name, sdl);
+#endif
+}
+
 static int
 if_getssid1(const char *ifname, uint8_t *ssid)
 {
@@ -494,6 +507,10 @@ if_route(const struct rt *rt, int action
 	} else
 		rtm.hdr.rtm_type = RTM_DELETE;
 	rtm.hdr.rtm_flags = RTF_UP;
+#ifdef RTF_PINNED
+	if (rtm.hdr.rtm_type != RTM_ADD)
+		rtm.hdr.rtm_flags |= RTF_PINNED;
+#endif
 #ifdef SIOCGIFPRIORITY
 	rtm.hdr.rtm_priority = rt->metric;
 #endif
@@ -523,10 +540,7 @@ if_route(const struct rt *rt, int action
 		    rt->gate.s_addr != htonl(INADDR_LOOPBACK)) ||
 		    !(rtm.hdr.rtm_flags & RTF_STATIC))
 		{
-			/* Make us a link layer socket for the host gateway */
-			memset(&su, 0, sizeof(su));
-			su.sdl.sdl_len = sizeof(struct sockaddr_dl);
-			link_addr(rt->iface->name, &su.sdl);
+			if_linkaddr(&su.sdl, rt->iface);
 			ADDSU;
 		} else
 			ADDADDR(&rt->gate);
@@ -536,10 +550,7 @@ if_route(const struct rt *rt, int action
 		ADDADDR(&rt->net);
 
 	if (rtm.hdr.rtm_addrs & RTA_IFP) {
-		/* Make us a link layer socket for the host gateway */
-		memset(&su, 0, sizeof(su));
-		su.sdl.sdl_len = sizeof(struct sockaddr_dl);
-		link_addr(rt->iface->name, &su.sdl);
+		if_linkaddr(&su.sdl, rt->iface);
 		ADDSU;
 	}
 
@@ -671,6 +682,10 @@ if_route6(const struct rt6 *rt, int acti
 	else
 		rtm.hdr.rtm_type = RTM_DELETE;
 	rtm.hdr.rtm_flags = RTF_UP | (int)rt->flags;
+#ifdef RTF_PINNED
+	if (rtm.hdr.rtm_type != RTM_ADD)
+		rtm.hdr.rtm_flags |= RTF_PINNED;
+#endif
 	rtm.hdr.rtm_addrs = RTA_DST | RTA_NETMASK;
 #ifdef SIOCGIFPRIORITY
 	rtm.hdr.rtm_priority = rt->metric;
@@ -693,10 +708,8 @@ if_route6(const struct rt6 *rt, int acti
 	lla = NULL;
 	if (rtm.hdr.rtm_addrs & RTA_GATEWAY) {
 		if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
-			lla = ipv6_linklocal(rt->iface);
-			if (lla == NULL) /* unlikely */
-				return -1;
-			ADDADDRS(&lla->addr, rt->iface->index);
+			if_linkaddr(&su.sdl, rt->iface);
+			ADDSU;
 		} else {
 			ADDADDRS(&rt->gate, rt->iface->index);
 		}
@@ -706,10 +719,7 @@ if_route6(const struct rt6 *rt, int acti
 		ADDADDR(&rt->net);
 
 	if (rtm.hdr.rtm_addrs & RTA_IFP) {
-		/* Make us a link layer socket for the host gateway */
-		memset(&su, 0, sizeof(su));
-		su.sdl.sdl_len = sizeof(struct sockaddr_dl);
-		link_addr(rt->iface->name, &su.sdl);
+		if_linkaddr(&su.sdl, rt->iface);
 		ADDSU;
 	}
 
@@ -1043,11 +1053,17 @@ if_nd6reachable(const char *ifname, stru
 	memset(&nbi, 0, sizeof(nbi));
 	strlcpy(nbi.ifname, ifname, sizeof(nbi.ifname));
 	nbi.addr = *addr;
-	if (ioctl(s, SIOCGNBRINFO_IN6, &nbi) == -1)
+	if (ioctl(s, SIOCGNBRINFO_IN6, &nbi) == -1) {
+#ifdef __FreeBSD__
+		/* FreeBSD doesn't support reachable routers? */
+		if (errno == EINVAL)
+			errno = ENOTSUP;
+#endif
 		flags = -1;
-	else {
+	} else {
 		flags = 0;
 		switch(nbi.state) {
+		case ND6_LLINFO_NOSTATE:	/* just added */
 		case ND6_LLINFO_REACHABLE:
 		case ND6_LLINFO_STALE:
 		case ND6_LLINFO_DELAY:

Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.13 src/external/bsd/dhcpcd/dist/if-options.c:1.14
--- src/external/bsd/dhcpcd/dist/if-options.c:1.13	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/if-options.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.13 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.14 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -1316,6 +1316,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 						ia->prefix_len = (uint8_t)i;
 				}
 			}
+			ia->sla_max = 0;
 			ia->sla_len = 0;
 			ia->sla = NULL;
 		}
@@ -1375,27 +1376,34 @@ parse_option(struct dhcpcd_ctx *ctx, con
 						goto err_sla;
 					sla->prefix_len = (uint8_t)i;
 				} else
-					sla->prefix_len = 64;
+					sla->prefix_len = 0;
 			} else {
 				sla->sla_set = 0;
-				/* Sanity - check there are no more
-				 * unspecified SLA's */
-				for (sl = 0; sl < ia->sla_len - 1; sl++) {
-					slap = &ia->sla[sl];
-					if (slap->sla_set == 0 &&
-					    strcmp(slap->ifname, sla->ifname)
-					    == 0)
-					{
-						syslog(LOG_WARNING,
-						    "%s: cannot specify the "
-						    "same interface twice with "
-						    "an automatic SLA",
-						    sla->ifname);
-						ia->sla_len--;
-						break;
-					}
+				sla->prefix_len = 0;
+			}
+			/* Sanity check */
+			for (sl = 0; sl < ia->sla_len - 1; sl++) {
+				slap = &ia->sla[sl];
+				if (slap->sla_set && sla->sla_set == 0) {
+					syslog(LOG_WARNING,
+					    "%s: cannot mix automatic "
+					    "and fixed SLA",
+					    sla->ifname);
+					goto err_sla;
+				}
+				if (sla->sla_set == 0 &&
+				    strcmp(slap->ifname, sla->ifname) == 0)
+				{
+					syslog(LOG_WARNING,
+					    "%s: cannot specify the "
+					    "same interface twice with "
+					    "an automatic SLA",
+					    sla->ifname);
+					goto err_sla;
 				}
 			}
+			if (sla->sla_set && sla->sla > ia->sla_max)
+				ia->sla_max = sla->sla;
 		}
 		break;
 err_sla:
Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.13 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.14
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.13	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.13 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.14 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -82,6 +82,9 @@ struct nd_opt_dnssl {		/* DNSSL option R
 } __packed;
 #endif
 
+/* Impossible options, so we can easily add extras */
+#define _ND_OPT_PREFIX_ADDR	255 + 1
+
 /* Minimal IPv6 MTU */
 #ifndef IPV6_MMTU
 #define IPV6_MMTU 1280
@@ -371,8 +374,12 @@ ipv6nd_checkreachablerouters(void *arg)
 	TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
 		flags = if_nd6reachable(rap->iface->name, &rap->from);
 		if (flags == -1) {
-			/* An error occured, so it's unreachable */
-			flags = 0;
+			if (errno == ENOTSUP)
+				/* Unsupported? We have to assume reachable */
+				flags = IPV6ND_REACHABLE;
+			else
+				/* An error occured, so it's unreachable */
+				flags = 0;
 		}
 		ipv6nd_reachable(rap, flags);
 	}
@@ -394,14 +401,15 @@ ipv6nd_free_opts(struct ra *rap)
 	}
 }
 
-int
-ipv6nd_addrexists(struct dhcpcd_ctx *ctx, const struct ipv6_addr *addr)
+struct ipv6_addr *
+ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
+    short flags)
 {
 	struct ra *rap;
 	struct ipv6_addr *ap;
 
 	if (ctx->ipv6 == NULL)
-		return 0;
+		return NULL;
 
 	TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
 		TAILQ_FOREACH(ap, &rap->addrs, next) {
@@ -409,12 +417,14 @@ ipv6nd_addrexists(struct dhcpcd_ctx *ctx
 				if ((ap->flags &
 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)) ==
 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED))
-					return 1;
-			} else if (IN6_ARE_ADDR_EQUAL(&ap->addr, &addr->addr))
-				return 1;
+					return ap;
+			} else if (ap->prefix_vltime &&
+			    IN6_ARE_ADDR_EQUAL(&ap->addr, addr) &&
+			    (!flags || ap->flags & flags))
+				return ap;
 		}
 	}
-	return 0;
+	return NULL;
 }
 
 void ipv6nd_freedrop_ra(struct ra *rap, int drop)
@@ -528,7 +538,7 @@ ipv6nd_scriptrun(struct ra *rap)
 		{
 			hasaddress = 1;
 			if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
-			    ipv6_findaddr(ap->iface, &ap->addr))
+			    ipv6_iffindaddr(ap->iface, &ap->addr))
 				ap->flags |= IPV6_AF_DADCOMPLETED;
 			if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
 				syslog(LOG_DEBUG,
@@ -700,7 +710,7 @@ static void
 ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
     struct icmp6_hdr *icp, size_t len)
 {
-	size_t olen, l, m, n;
+	size_t olen, l, n;
 	ssize_t r;
 	struct nd_router_advert *nd_ra;
 	struct nd_opt_prefix_info *pi;
@@ -716,7 +726,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 	struct nd_opt_hdr *ndo;
 	struct ra_opt *rao;
 	struct ipv6_addr *ap;
-	char *opt, *tmp;
+	char *opt, *opt2, *tmp;
 	struct timeval expire;
 	uint8_t new_rap, new_data;
 
@@ -820,6 +830,10 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 	if (rap->lifetime)
 		rap->expired = 0;
 
+	TAILQ_FOREACH(ap, &rap->addrs, next) {
+		ap->flags |= IPV6_AF_STALE;
+	}
+
 	len -= sizeof(struct nd_router_advert);
 	p = ((uint8_t *)icp) + sizeof(struct nd_router_advert);
 	lifetime = ~0U;
@@ -840,7 +854,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 			break;
 		}
 
-		opt = NULL;
+		opt = opt2 = NULL;
 		switch (ndo->nd_opt_type) {
 		case ND_OPT_PREFIX_INFORMATION:
 			pi = (struct nd_opt_prefix_info *)(void *)ndo;
@@ -916,7 +930,8 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 				}
 				ap->dadcallback = ipv6nd_dadcallback;
 				TAILQ_INSERT_TAIL(&rap->addrs, ap, next);
-			}
+			} else
+				ap->flags &= ~IPV6_AF_STALE;
 			if (pi->nd_opt_pi_flags_reserved &
 			    ND_OPT_PI_FLAG_ONLINK)
 				ap->flags |= IPV6_AF_ONLINK;
@@ -925,20 +940,16 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 			ap->prefix_pltime =
 			    ntohl(pi->nd_opt_pi_preferred_time);
 			ap->nsprobes = 0;
-			if (opt) {
-				l = strlen(opt) + 1;
-				m = strlen(ap->saddr) + 1;
-				tmp = realloc(opt, l + m);
-				if (tmp) {
-					opt = tmp;
-					opt[l - 1] = ' ';
-					strlcpy(opt + l, ap->saddr, m);
-				} else {
-					syslog(LOG_ERR, "%s: %m", __func__);
-					continue;
+			cbp = inet_ntop(AF_INET6, &ap->prefix, buf, sizeof(buf));
+			if (cbp) {
+				l = strlen(cbp);
+				opt = malloc(l + 5);
+				if (opt) {
+					snprintf(opt, l + 5, "%s/%d", cbp,
+					    ap->prefix_len);
+					opt2 = strdup(ap->saddr);
 				}
-			} else
-				opt = strdup(ap->saddr);
+			}
 			lifetime = ap->prefix_vltime;
 			break;
 
@@ -1039,8 +1050,10 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 			continue;
 		}
 
+		n = ndo->nd_opt_type;
+extra_opt:
 		TAILQ_FOREACH(rao, &rap->options, next) {
-			if (rao->type == ndo->nd_opt_type &&
+			if (rao->type == n &&
 			    strcmp(rao->option, opt) == 0)
 				break;
 		}
@@ -1051,6 +1064,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 				free(rao);
 			}
 			free(opt);
+			free(opt2);
 			continue;
 		}
 
@@ -1060,7 +1074,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 				syslog(LOG_ERR, "%s: %m", __func__);
 				continue;
 			}
-			rao->type = ndo->nd_opt_type;
+			rao->type = (uint16_t)n;
 			rao->option = opt;
 			TAILQ_INSERT_TAIL(&rap->options, rao, next);
 		} else
@@ -1072,6 +1086,12 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 			expire.tv_usec = 0;
 			timeradd(&rap->received, &expire, &rao->expire);
 		}
+		if (rao && rao->type == ND_OPT_PREFIX_INFORMATION && opt2) {
+			n = _ND_OPT_PREFIX_ADDR;
+			opt = opt2;
+			opt2 = NULL;
+			goto extra_opt;
+		}
 	}
 
 	if (new_rap)
@@ -1089,6 +1109,8 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, rap); /* reachable timer */
 
 handle_flag:
+	if (!(ifp->options->options & DHCPCD_DHCP6))
+		goto nodhcp6;
 	if (rap->flags & ND_RA_FLAG_MANAGED) {
 		if (new_data && dhcp6_start(ifp, DH6S_INIT) == -1)
 			syslog(LOG_ERR, "dhcp6_start: %s: %m", ifp->name);
@@ -1099,6 +1121,7 @@ handle_flag:
 		if (new_data)
 			syslog(LOG_DEBUG, "%s: No DHCPv6 instruction in RA",
 			    ifp->name);
+nodhcp6:
 		if (ifp->ctx->options & DHCPCD_TEST) {
 			eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
 			return;
@@ -1110,7 +1133,8 @@ handle_flag:
 
 #ifndef HAVE_RTM_GETNEIGH
 	/* Start our reachability tests now */
-	ipv6nd_checkreachablerouters(ifp->ctx);
+	eloop_timeout_add_sec(ifp->ctx->eloop, ND6REACHABLE_TIMER,
+	    ipv6nd_checkreachablerouters, ifp->ctx);
 #endif
 }
 
@@ -1151,13 +1175,13 @@ ipv6nd_env(char **env, const char *prefi
 	const struct ra_opt *rao;
 	char buffer[32];
 	const char *optn;
-	char **pref, **mtu, **rdnss, **dnssl, ***var, *new;
+	char **pref, **addr, **mtu, **rdnss, **dnssl, ***var, *new;
 
 	i = l = 0;
 	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
-		i++;
 		if (rap->iface != ifp)
 			continue;
+		i++;
 		if (env) {
 			snprintf(buffer, sizeof(buffer),
 			    "ra%zu_from", i);
@@ -1165,16 +1189,20 @@ ipv6nd_env(char **env, const char *prefi
 		}
 		l++;
 
-		pref = mtu = rdnss = dnssl = NULL;
+		pref = addr = mtu = rdnss = dnssl = NULL;
 		TAILQ_FOREACH(rao, &rap->options, next) {
 			if (rao->option == NULL)
 				continue;
 			var = NULL;
 			switch(rao->type) {
 			case ND_OPT_PREFIX_INFORMATION:
-				optn = "prefix"; /* really address */
+				optn = "prefix";
 				var = &pref;
 				break;
+			case _ND_OPT_PREFIX_ADDR:
+				optn = "addr";
+				var = &addr;
+				break;
 			case ND_OPT_MTU:
 				optn = "mtu";
 				var = &mtu;

Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.10 src/external/bsd/dhcpcd/dist/script.c:1.11
--- src/external/bsd/dhcpcd/dist/script.c:1.10	Mon Oct  6 18:22:29 2014
+++ src/external/bsd/dhcpcd/dist/script.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.10 2014/10/06 18:22:29 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.11 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon

Index: src/external/bsd/dhcpcd/dist/crypt/crypt.h
diff -u src/external/bsd/dhcpcd/dist/crypt/crypt.h:1.2 src/external/bsd/dhcpcd/dist/crypt/crypt.h:1.3
--- src/external/bsd/dhcpcd/dist/crypt/crypt.h:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/crypt/crypt.h	Fri Oct 17 23:42:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: crypt.h,v 1.2 2014/10/06 18:22:30 roy Exp $ */
+/* $NetBSD: crypt.h,v 1.3 2014/10/17 23:42:24 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
Index: src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c
diff -u src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c:1.2 src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c:1.3
--- src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/crypt/hmac_md5.c	Fri Oct 17 23:42:24 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: hmac_md5.c,v 1.2 2014/10/06 18:22:30 roy Exp $");
+ __RCSID("$NetBSD: hmac_md5.c,v 1.3 2014/10/17 23:42:24 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon

Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/01-test	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 01-test,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 01-test,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Just echo our DHCP options we have
 
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/02-dump	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 02-dump,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 02-dump,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Just echo our DHCP options we have
 
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 10-mtu,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 10-mtu,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Configure the MTU for the interface
 
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-wpa_supplicant
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-wpa_supplicant:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-wpa_supplicant:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-wpa_supplicant:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-wpa_supplicant	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 10-wpa_supplicant,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 10-wpa_supplicant,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Start, reconfigure and stop wpa_supplicant per wireless interface.
 # This is needed because wpa_supplicant lacks hotplugging of any kind
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/15-timezone
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/15-timezone:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/15-timezone:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/15-timezone:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/15-timezone	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 15-timezone,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 15-timezone,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Configure timezone
 
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 20-resolv.conf,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 20-resolv.conf,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Generate /etc/resolv.conf
 # Support resolvconf(8) if available
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/29-lookup-hostname
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/29-lookup-hostname:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/29-lookup-hostname:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/29-lookup-hostname:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/29-lookup-hostname	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 29-lookup-hostname,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 29-lookup-hostname,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Lookup the hostname in DNS if not set
 
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 30-hostname,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 30-hostname,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Set the hostname from DHCP data if required
 
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 50-ntp.conf,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 50-ntp.conf,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Sample dhcpcd hook script for ntp
 # Like our resolv.conf hook script, we store a database of ntp.conf files
Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ypbind
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ypbind:1.2 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ypbind:1.3
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ypbind:1.2	Mon Oct  6 18:22:30 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ypbind	Fri Oct 17 23:42:25 2014
@@ -1,4 +1,4 @@
-# $NetBSD: 50-ypbind,v 1.2 2014/10/06 18:22:30 roy Exp $
+# $NetBSD: 50-ypbind,v 1.3 2014/10/17 23:42:25 roy Exp $
 
 # Sample dhcpcd hook for ypbind
 # This script is only suitable for the BSD versions.

Reply via email to