Module Name:    src
Committed By:   roy
Date:           Fri Aug 21 10:39:01 UTC 2015

Modified Files:
        src/external/bsd/dhcpcd/dist: control.c defs.h dhcp.c dhcp.h dhcp6.c
            dhcpcd-run-hooks.in dhcpcd.8.in dhcpcd.c dhcpcd.conf
            dhcpcd.conf.5.in dhcpcd.h if-bsd.c if-options.c if-options.h if.c
            if.h ipv4.c ipv4.h ipv4ll.c ipv4ll.h ipv6.c ipv6nd.c script.c
        src/external/bsd/dhcpcd/dist/dhcpcd-hooks: 20-resolv.conf 30-hostname
Removed Files:
        src/external/bsd/dhcpcd/dist/dhcpcd-hooks: 10-mtu

Log Message:
Sync


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/control.c \
    src/external/bsd/dhcpcd/dist/ipv4ll.h
cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/defs.h
cvs rdiff -u -r1.32 -r1.33 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/dhcp.h \
    src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in
cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/dhcp6.c \
    src/external/bsd/dhcpcd/dist/if.c
cvs rdiff -u -r1.43 -r1.44 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/dhcpcd.c
cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/dhcpcd.conf \
    src/external/bsd/dhcpcd/dist/ipv4.c
cvs rdiff -u -r1.22 -r1.23 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in \
    src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/dhcpcd.h \
    src/external/bsd/dhcpcd/dist/if-options.h \
    src/external/bsd/dhcpcd/dist/ipv4.h
cvs rdiff -u -r1.25 -r1.26 src/external/bsd/dhcpcd/dist/if-options.c \
    src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/if.h \
    src/external/bsd/dhcpcd/dist/ipv4ll.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/ipv6.c
cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/script.c
cvs rdiff -u -r1.6 -r0 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/10-mtu
cvs rdiff -u -r1.7 -r1.8 \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf
cvs rdiff -u -r1.6 -r1.7 \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname

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/control.c
diff -u src/external/bsd/dhcpcd/dist/control.c:1.9 src/external/bsd/dhcpcd/dist/control.c:1.10
--- src/external/bsd/dhcpcd/dist/control.c:1.9	Sat May 16 23:31:32 2015
+++ src/external/bsd/dhcpcd/dist/control.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: control.c,v 1.9 2015/05/16 23:31:32 roy Exp $");
+ __RCSID("$NetBSD: control.c,v 1.10 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -46,6 +46,7 @@
 #include "dhcpcd.h"
 #include "control.h"
 #include "eloop.h"
+#include "if.h"
 
 #ifndef SUN_LEN
 #define SUN_LEN(su) \
@@ -210,28 +211,8 @@ make_sock(struct sockaddr_un *sa, const 
 {
 	int fd;
 
-#ifdef SOCK_CLOEXEC
-	if ((fd = socket(AF_UNIX,
-	    SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) == -1)
+	if ((fd = xsocket(AF_UNIX, SOCK_STREAM, 0, O_NONBLOCK|O_CLOEXEC)) == -1)
 		return -1;
-#else
-	int flags;
-
-	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
-		return -1;
-	if ((flags = fcntl(fd, F_GETFD, 0)) == -1 ||
-	    fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
-	{
-		close(fd);
-	        return -1;
-	}
-	if ((flags = fcntl(fd, F_GETFL, 0)) == -1 ||
-	    fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
-	{
-		close(fd);
-	        return -1;
-	}
-#endif
 	memset(sa, 0, sizeof(*sa));
 	sa->sun_family = AF_UNIX;
 	if (unpriv)
Index: src/external/bsd/dhcpcd/dist/ipv4ll.h
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.h:1.9 src/external/bsd/dhcpcd/dist/ipv4ll.h:1.10
--- src/external/bsd/dhcpcd/dist/ipv4ll.h:1.9	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/ipv4ll.h	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4ll.h,v 1.9 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: ipv4ll.h,v 1.10 2015/08/21 10:39:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -32,6 +32,9 @@
 
 #include "arp.h"
 
+extern const struct in_addr inaddr_llmask;
+extern const struct in_addr inaddr_llbcast;
+
 #define LINKLOCAL_ADDR	0xa9fe0000
 #define LINKLOCAL_MASK	IN_CLASSB_NET
 #define LINKLOCAL_BRDC	(LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
@@ -58,6 +61,7 @@ struct ipv4ll_state {
 	IN_LINKLOCAL(ntohl(IPV4LL_CSTATE((ifp))->addr.s_addr)))
 
 struct rt* ipv4ll_subnet_route(const struct interface *);
+struct rt* ipv4ll_default_route(const struct interface *);
 ssize_t ipv4ll_env(char **, const char *, const struct interface *);
 void ipv4ll_start(void *);
 void ipv4ll_claimed(void *);

Index: src/external/bsd/dhcpcd/dist/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.19 src/external/bsd/dhcpcd/dist/defs.h:1.20
--- src/external/bsd/dhcpcd/dist/defs.h:1.19	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/defs.h	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.19 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: defs.h,v 1.20 2015/08/21 10:39:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
 #define CONFIG_H
 
 #define PACKAGE			"dhcpcd"
-#define VERSION			"6.9.1"
+#define VERSION			"6.9.2"
 
 #ifndef CONFIG
 # define CONFIG			SYSCONFDIR "/" PACKAGE ".conf"

Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.32 src/external/bsd/dhcpcd/dist/dhcp.c:1.33
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.32	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcp.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.32 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.33 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -279,6 +279,23 @@ get_option_uint32(struct dhcpcd_ctx *ctx
 }
 
 static int
+get_option_uint16(struct dhcpcd_ctx *ctx,
+    uint16_t *i, const struct dhcp_message *dhcp, uint8_t option)
+{
+	const uint8_t *p;
+	size_t len;
+	uint16_t d;
+
+	p = get_option(ctx, dhcp, option, &len);
+	if (!p || len < (ssize_t)sizeof(d))
+		return -1;
+	memcpy(&d, p, sizeof(d));
+	if (i)
+		*i = ntohs(d);
+	return 0;
+}
+
+static int
 get_option_uint8(struct dhcpcd_ctx *ctx,
     uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
 {
@@ -586,7 +603,7 @@ route_netmask(uint32_t ip_in)
 /* We need to obey routing options.
  * If we have a CSR then we only use that.
  * Otherwise we add static routes and then routers. */
-struct rt_head *
+static struct rt_head *
 get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
 {
 	struct if_options *ifo = ifp->options;
@@ -692,6 +709,40 @@ get_option_routes(struct interface *ifp,
 	return routes;
 }
 
+uint16_t
+dhcp_get_mtu(const struct interface *ifp)
+{
+	const struct dhcp_message *dhcp;
+	uint16_t mtu;
+
+	if ((dhcp = D_CSTATE(ifp)->new) == NULL ||
+	    has_option_mask(ifp->options->nomask, DHO_MTU) ||
+	    get_option_uint16(ifp->ctx, &mtu, dhcp, DHO_MTU) == -1)
+		return 0;
+	return mtu;
+}
+
+/* Grab our routers from the DHCP message and apply any MTU value
+ * the message contains */
+struct rt_head *
+dhcp_get_routes(struct interface *ifp)
+{
+	struct rt_head *routes;
+	uint16_t mtu;
+	const struct dhcp_message *dhcp;
+
+	dhcp = D_CSTATE(ifp)->new;
+	routes = get_option_routes(ifp, dhcp);
+	if ((mtu = dhcp_get_mtu(ifp)) != 0) {
+		struct rt *rt;
+
+		TAILQ_FOREACH(rt, routes, next) {
+			rt->mtu = mtu;
+		}
+	}
+	return routes;
+}
+
 #define PUTADDR(_type, _val)						      \
 	{								      \
 		*p++ = _type;						      \
@@ -852,21 +903,27 @@ make_message(struct dhcp_message **messa
 		if (!(ifo->options & DHCPCD_BOOTP)) {
 			int mtu;
 
-			*p++ = DHO_MAXMESSAGESIZE;
-			*p++ = 2;
-			mtu = if_getmtu(ifp->name);
-			if (mtu < MTU_MIN) {
-				if (if_setmtu(ifp->name, MTU_MIN) == 0)
-					sz = MTU_MIN;
+			if ((mtu = if_getmtu(ifp)) == -1)
+				logger(ifp->ctx, LOG_ERR,
+				    "%s: if_getmtu: %m", ifp->name);
+			else if (mtu < MTU_MIN) {
+				if (if_setmtu(ifp, MTU_MIN) == -1)
+					logger(ifp->ctx, LOG_ERR,
+					    "%s: if_setmtu: %m", ifp->name);
+				mtu = MTU_MIN;
 			} else if (mtu > MTU_MAX) {
 				/* Even though our MTU could be greater than
 				 * MTU_MAX (1500) dhcpcd does not presently
 				 * handle DHCP packets any bigger. */
 				mtu = MTU_MAX;
 			}
-			sz = htons((uint16_t)mtu);
-			memcpy(p, &sz, 2);
-			p += 2;
+			if (mtu != -1) {
+				*p++ = DHO_MAXMESSAGESIZE;
+				*p++ = 2;
+				sz = htons((uint16_t)mtu);
+				memcpy(p, &sz, 2);
+				p += 2;
+			}
 		}
 
 		if (ifo->userclass[0]) {
@@ -1184,6 +1241,13 @@ read_lease(struct interface *ifp)
 		else
 			logger(ifp->ctx, LOG_DEBUG,
 			    "%s: accepted reconfigure key", ifp->name);
+	} else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) ==
+	    DHCPCD_AUTH_SENDREQUIRE)
+	{
+		logger(ifp->ctx, LOG_ERR,
+		    "%s: authentication now required", ifp->name);
+		free(dhcp);
+		return NULL;
 	}
 
 	return dhcp;
@@ -1483,19 +1547,8 @@ dhcp_openudp(struct interface *ifp)
 	char *p;
 #endif
 
-#ifdef SOCK_CLOEXEC
-	if ((s = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP)) == -1)
-		return -1;
-#else
-	if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+	if ((s = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP, O_CLOEXEC)) == -1)
 		return -1;
-	if ((n = fcntl(s, F_GETFD, 0)) == -1 ||
-	    fcntl(s, F_SETFD, n | FD_CLOEXEC) == -1)
-	{
-		close(s);
-	        return -1;
-	}
-#endif
 
 	n = 1;
 	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
@@ -2325,6 +2378,8 @@ dhcp_drop(struct interface *ifp, const c
 	dhcp_auth_reset(&state->auth);
 	dhcp_close(ifp);
 
+	free(state->offer);
+	state->offer = NULL;
 	free(state->old);
 	state->old = state->new;
 	state->new = NULL;
@@ -2481,12 +2536,15 @@ dhcp_handledhcp(struct interface *ifp, s
 		else
 			logger(ifp->ctx, LOG_DEBUG,
 			    "%s: accepted reconfigure key", ifp->name);
-	} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
-		log_dhcp1(LOG_ERR, "no authentication", ifp, dhcp, from, 0);
-		return;
-	} else if (ifo->auth.options & DHCPCD_AUTH_SEND)
+	} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
+		if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
+			log_dhcp1(LOG_ERR, "no authentication",
+			    ifp, dhcp, from, 0);
+			return;
+		}
 		log_dhcp1(LOG_WARNING, "no authentication",
 		    ifp, dhcp, from, 0);
+	}
 
 	/* RFC 3203 */
 	if (type == DHCP_FORCERENEW) {
@@ -2500,7 +2558,8 @@ dhcp_handledhcp(struct interface *ifp, s
 		if (auth == NULL) {
 			log_dhcp(LOG_ERR, "unauthenticated Force Renew",
 			    ifp, dhcp, from);
-			return;
+			if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
+				return;
 		}
 		if (state->state != DHS_BOUND && state->state != DHS_INFORM) {
 			log_dhcp(LOG_DEBUG, "not bound, ignoring Force Renew",
@@ -3203,7 +3262,7 @@ dhcp_start1(void *arg)
 	}
 	/* We don't want to read the old lease if we NAK an old test */
 	nolease = state->offer && ifp->ctx->options & DHCPCD_TEST;
-	if (!nolease) {
+	if (!nolease && ifo->options & DHCPCD_DHCP) {
 		state->offer = read_lease(ifp);
 		/* Check the saved lease matches the type we want */
 		if (state->offer) {
@@ -3294,13 +3353,8 @@ dhcp_start1(void *arg)
 	}
 
 	if (!(ifo->options & DHCPCD_DHCP)) {
-		if (ifo->options & DHCPCD_IPV4LL) {
-			if (state->offer && state->offer->cookie != 0) {
-				free(state->offer);
-				state->offer = NULL;
-			}
+		if (ifo->options & DHCPCD_IPV4LL)
 			ipv4ll_start(ifp);
-		}
 		return;
 	}
 
@@ -3338,6 +3392,13 @@ dhcp_start(struct interface *ifp)
 }
 
 void
+dhcp_abort(struct interface *ifp)
+{
+
+	eloop_timeout_delete(ifp->ctx->eloop, dhcp_start1, ifp);
+}
+
+void
 dhcp_handleifa(int cmd, struct interface *ifp,
 	const struct in_addr *addr,
 	const struct in_addr *net,

Index: src/external/bsd/dhcpcd/dist/dhcp.h
diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.10 src/external/bsd/dhcpcd/dist/dhcp.h:1.11
--- src/external/bsd/dhcpcd/dist/dhcp.h:1.10	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcp.h	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: dhcp.h,v 1.11 2015/08/21 10:39:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -247,8 +247,8 @@ int get_option_addr(struct dhcpcd_ctx *,
     const struct dhcp_message *, uint8_t);
 #define IS_BOOTP(i, m) ((m) != NULL &&						    \
 	    get_option_uint8((i)->ctx, NULL, (m), DHO_MESSAGETYPE) == -1)
-struct rt_head *get_option_routes(struct interface *,
-    const struct dhcp_message *);
+uint16_t dhcp_get_mtu(const struct interface *);
+struct rt_head *dhcp_get_routes(struct interface *);
 ssize_t dhcp_env(char **, const char *, const struct dhcp_message *,
     const struct interface *);
 
@@ -266,7 +266,7 @@ void dhcp_handleifa(int, struct interfac
 
 void dhcp_drop(struct interface *, const char *);
 void dhcp_start(struct interface *);
-void dhcp_stop(struct interface *);
+void dhcp_abort(struct interface *);
 void dhcp_discover(void *);
 void dhcp_inform(struct interface *);
 void dhcp_bind(struct interface *);
@@ -277,6 +277,7 @@ int dhcp_dump(struct interface *);
 #else
 #define dhcp_drop(a, b) {}
 #define dhcp_start(a) {}
+#define dhcp_abort(a) {}
 #define dhcp_reboot(a, b) (b = b)
 #define dhcp_reboot_newopts(a, b) (b = b)
 #define dhcp_close(a) {}
Index: src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.10 src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.11
--- src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in:1.10	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.in	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $NetBSD: dhcpcd-run-hooks.in,v 1.10 2015/07/09 10:15:34 roy Exp $
+# $NetBSD: dhcpcd-run-hooks.in,v 1.11 2015/08/21 10:39:00 roy Exp $
 
 # dhcpcd client configuration script 
 
@@ -120,8 +120,7 @@ remove_markers()
 comp_file()
 {
 
-	[ -e "$1" ] || return 1
-	[ -e "$2" ] || return 1
+	[ -e "$1" -a -e "$2" ] || return 1
 
 	if type cmp >/dev/null 2>&1; then
 		cmp -s "$1" "$2"

Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.14 src/external/bsd/dhcpcd/dist/dhcp6.c:1.15
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.14	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcp6.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.15 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -43,6 +43,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #define ELOOP_QUEUE 4
 #include "config.h"
@@ -2247,7 +2248,9 @@ auth:
 		else
 			logger(ifp->ctx, LOG_DEBUG,
 			    "%s: accepted reconfigure key", ifp->name);
-	} else if (ifp->options->auth.options & DHCPCD_AUTH_REQUIRE) {
+	} else if ((ifp->options->auth.options & DHCPCD_AUTH_SENDREQUIRE) ==
+	    DHCPCD_AUTH_SENDREQUIRE)
+	{
 		logger(ifp->ctx, LOG_ERR,
 		    "%s: authentication now required", ifp->name);
 		goto ex;
@@ -2753,13 +2756,16 @@ dhcp6_handledata(void *arg)
 		else
 			logger(ifp->ctx, LOG_DEBUG,
 			    "%s: accepted reconfigure key", ifp->name);
-	} else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
-		logger(ifp->ctx, LOG_ERR,
-		    "%s: no authentication from %s", ifp->name, ctx->sfrom);
-		return;
-	} else if (ifo->auth.options & DHCPCD_AUTH_SEND)
+	} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
+		if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
+			logger(ifp->ctx, LOG_ERR,
+			    "%s: no authentication from %s",
+			    ifp->name, ctx->sfrom);
+			return;
+		}
 		logger(ifp->ctx, LOG_WARNING,
 		    "%s: no authentication from %s", ifp->name, ctx->sfrom);
+	}
 
 	op = dhcp6_get_op(r->type);
 	switch(r->type) {
@@ -2863,7 +2869,8 @@ dhcp6_handledata(void *arg)
 			logger(ifp->ctx, LOG_ERR,
 			    "%s: unauthenticated %s from %s",
 			    ifp->name, op, ctx->sfrom);
-			return;
+			if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
+				return;
 		}
 		logger(ifp->ctx, LOG_INFO, "%s: %s from %s",
 		    ifp->name, op, ctx->sfrom);
@@ -3073,30 +3080,10 @@ dhcp6_open(struct dhcpcd_ctx *dctx)
 #endif
 
 	ctx = dctx->ipv6;
-#ifdef SOCK_CLOEXEC
-	ctx->dhcp_fd = socket(PF_INET6,
-	    SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
-	    IPPROTO_UDP);
+	ctx->dhcp_fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP,
+	    O_NONBLOCK|O_CLOEXEC);
 	if (ctx->dhcp_fd == -1)
 		return -1;
-#else
-	if ((ctx->dhcp_fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1)
-		return -1;
-	if ((n = fcntl(ctx->dhcp_fd, F_GETFD, 0)) == -1 ||
-	    fcntl(ctx->dhcp_fd, F_SETFD, n | FD_CLOEXEC) == -1)
-	{
-		close(ctx->dhcp_fd);
-		ctx->dhcp_fd = -1;
-	        return -1;
-	}
-	if ((n = fcntl(ctx->dhcp_fd, F_GETFL, 0)) == -1 ||
-	    fcntl(ctx->dhcp_fd, F_SETFL, n | O_NONBLOCK) == -1)
-	{
-		close(ctx->dhcp_fd);
-		ctx->dhcp_fd = -1;
-	        return -1;
-	}
-#endif
 
 	n = 1;
 	if (setsockopt(ctx->dhcp_fd, SOL_SOCKET, SO_REUSEADDR,
@@ -3143,8 +3130,8 @@ dhcp6_start1(void *arg)
 	const struct dhcp_compat *dhc;
 
 	state = D6_STATE(ifp);
-	/* Match any DHCPv4 opton to DHCPv6 options if given for easy
-	 * configuration */
+	/* If no DHCPv6 options are configured,
+	   match configured DHCPv4 options to DHCPv6 equivalents. */
 	for (i = 0; i < sizeof(ifo->requestmask6); i++) {
 		if (ifo->requestmask6[i] != '\0')
 			break;
@@ -3160,7 +3147,7 @@ dhcp6_start1(void *arg)
 			add_option_mask(ifo->requestmask6, D6_OPTION_FQDN);
 	}
 
-	/* Rapid commit won't wor with Prefix Delegation Exclusion */
+	/* Rapid commit won't work with Prefix Delegation Exclusion */
 	if (dhcp6_findselfsla(ifp, NULL))
 		del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT);
 
Index: src/external/bsd/dhcpcd/dist/if.c
diff -u src/external/bsd/dhcpcd/dist/if.c:1.14 src/external/bsd/dhcpcd/dist/if.c:1.15
--- src/external/bsd/dhcpcd/dist/if.c:1.14	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/if.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: if.c,v 1.15 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -61,6 +61,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include "config.h"
 #include "common.h"
@@ -73,11 +74,6 @@
 #include "ipv4ll.h"
 #include "ipv6nd.h"
 
-#ifdef __QNX__
-/* QNX carries defines for, but does not actually support PF_LINK */
-#undef IFLR_ACTIVE
-#endif
-
 void
 if_free(struct interface *ifp)
 {
@@ -95,28 +91,50 @@ if_free(struct interface *ifp)
 }
 
 int
-if_carrier(struct interface *iface)
+if_opensockets(struct dhcpcd_ctx *ctx)
+{
+
+	if ((ctx->link_fd = if_openlinksocket()) == -1)
+		return -1;
+
+	ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC);
+	if (ctx->pf_inet_fd == -1)
+		return -1;
+
+#if defined(INET6) && defined(BSD)
+	ctx->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, O_CLOEXEC);
+	if (ctx->pf_inet6_fd == -1)
+		return -1;
+#endif
+
+#ifdef IFLR_ACTIVE
+	ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, O_CLOEXEC);
+	if (ctx->pf_link_fd == -1)
+		return -1;
+#endif
+
+	return 0;
+}
+
+int
+if_carrier(struct interface *ifp)
 {
-	int s, r;
+	int r;
 	struct ifreq ifr;
 #ifdef SIOCGIFMEDIA
 	struct ifmediareq ifmr;
 #endif
 
-	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-		return LINK_UNKNOWN;
 	memset(&ifr, 0, sizeof(ifr));
-	strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
-	if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
-		close(s);
+	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+	if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1)
 		return LINK_UNKNOWN;
-	}
-	iface->flags = (unsigned int)ifr.ifr_flags;
+	ifp->flags = (unsigned int)ifr.ifr_flags;
 
 #ifdef SIOCGIFMEDIA
 	memset(&ifmr, 0, sizeof(ifmr));
-	strlcpy(ifmr.ifm_name, iface->name, sizeof(ifmr.ifm_name));
-	if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 &&
+	strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
+	if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) != -1 &&
 	    ifmr.ifm_status & IFM_AVALID)
 		r = (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN;
 	else
@@ -124,7 +142,6 @@ if_carrier(struct interface *iface)
 #else
 	r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN;
 #endif
-	close(s);
 	return r;
 }
 
@@ -132,24 +149,21 @@ int
 if_setflag(struct interface *ifp, short flag)
 {
 	struct ifreq ifr;
-	int s, r;
+	int r;
 
-	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-		return -1;
 	memset(&ifr, 0, sizeof(ifr));
 	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
 	r = -1;
-	if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
+	if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == 0) {
 		if (flag == 0 || (ifr.ifr_flags & flag) == flag)
 			r = 0;
 		else {
 			ifr.ifr_flags |= flag;
-			if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0)
+			if (ioctl(ifp->ctx->pf_inet_fd, SIOCSIFFLAGS, &ifr) ==0)
 				r = 0;
 		}
 		ifp->flags = (unsigned int)ifr.ifr_flags;
 	}
-	close(s);
 	return r;
 }
 
@@ -241,24 +255,12 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 	const struct sockaddr_dl *sdl;
 #ifdef SIOCGIFPRIORITY
 	struct ifreq ifr;
-	int s_inet;
 #endif
 #ifdef IFLR_ACTIVE
 	struct if_laddrreq iflr;
-	int s_link;
 #endif
 
-#ifdef SIOCGIFPRIORITY
-	if ((s_inet = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-		return NULL;
-#endif
 #ifdef IFLR_ACTIVE
-	if ((s_link = socket(PF_LINK, SOCK_DGRAM, 0)) == -1) {
-#ifdef SIOCGIFPRIORITY
-		close(s_inet);
-#endif
-		return NULL;
-	}
 	memset(&iflr, 0, sizeof(iflr));
 #endif
 #elif AF_PACKET
@@ -343,7 +345,7 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 				continue;
 		}
 
-		if (if_vimaster(p) == 1) {
+		if (if_vimaster(ctx, p) == 1) {
 			logger(ctx, argc ? LOG_ERR : LOG_DEBUG,
 			    "%s: is a Virtual Interface Master, skipping", p);
 			continue;
@@ -376,7 +378,7 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 			    MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr)));
 			iflr.flags = IFLR_PREFIX;
 			iflr.prefixlen = (unsigned int)sdl->sdl_alen * NBBY;
-			if (ioctl(s_link, SIOCGLIFADDR, &iflr) == -1 ||
+			if (ioctl(ctx->pf_link_fd, SIOCGLIFADDR, &iflr) == -1 ||
 			    !(iflr.flags & IFLR_ACTIVE))
 			{
 				if_free(ifp);
@@ -497,27 +499,30 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 			}
 		}
 
-		/* Handle any platform init for the interface */
-		if (if_init(ifp) == -1) {
-			logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p);
-			if_free(ifp);
-			continue;
-		}
+		if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) {
+			/* Handle any platform init for the interface */
+			if (if_init(ifp) == -1) {
+				logger(ifp->ctx, LOG_ERR, "%s: if_init: %m", p);
+				if_free(ifp);
+				continue;
+			}
 
-		/* Ensure that the MTU is big enough for DHCP */
-		if (if_getmtu(ifp->name) < MTU_MIN &&
-		    if_setmtu(ifp->name, MTU_MIN) == -1)
-		{
-			logger(ifp->ctx, LOG_ERR, "%s: set_mtu: %m", p);
-			if_free(ifp);
-			continue;
+			/* Ensure that the MTU is big enough for DHCP */
+			if (if_getmtu(ifp) < MTU_MIN &&
+			    if_setmtu(ifp, MTU_MIN) == -1)
+			{
+				logger(ifp->ctx, LOG_ERR,
+				    "%s: if_setmtu: %m", p);
+				if_free(ifp);
+				continue;
+			}
 		}
 
 #ifdef SIOCGIFPRIORITY
 		/* Respect the interface priority */
 		memset(&ifr, 0, sizeof(ifr));
 		strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
-		if (ioctl(s_inet, SIOCGIFPRIORITY, &ifr) == 0)
+		if (ioctl(ctx->pf_inet_fd, SIOCGIFPRIORITY, &ifr) == 0)
 			ifp->metric = ifr.ifr_metric;
 #else
 		/* We reserve the 100 range for virtual interfaces, if and when
@@ -535,13 +540,6 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 	if_learnaddrs1(ctx, ifs, ifaddrs);
 	freeifaddrs(ifaddrs);
 
-#ifdef SIOCGIFPRIORITY
-	close(s_inet);
-#endif
-#ifdef IFLR_ACTIVE
-	close(s_link);
-#endif
-
 	return ifs;
 }
 
@@ -581,18 +579,15 @@ if_findindex(struct if_head *ifaces, uns
 }
 
 int
-if_domtu(const char *ifname, short int mtu)
+if_domtu(const struct interface *ifp, short int mtu)
 {
-	int s, r;
+	int r;
 	struct ifreq ifr;
 
-	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-		return -1;
 	memset(&ifr, 0, sizeof(ifr));
-	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
 	ifr.ifr_mtu = mtu;
-	r = ioctl(s, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
-	close(s);
+	r = ioctl(ifp->ctx->pf_inet_fd, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
 	if (r == -1)
 		return -1;
 	return ifr.ifr_mtu;
@@ -667,3 +662,31 @@ if_sortinterfaces(struct dhcpcd_ctx *ctx
 	}
 	TAILQ_CONCAT(ctx->ifaces, &sorted, next);
 }
+
+int
+xsocket(int domain, int type, int protocol, int flags)
+{
+#ifdef SOCK_CLOEXEC
+	if (flags & O_CLOEXEC)
+		type |= SOCK_CLOEXEC;
+	if (flags & O_NONBLOCK)
+		type |= SOCK_NONBLOCK;
+
+	return socket(domain, type, protocol);
+#else
+	int s, xflags;
+
+	if ((s = socket(domain, type, protocol)) == -1)
+		return -1;
+	if ((flags & O_CLOEXEC) && (xflags = fcntl(s, F_GETFD, 0)) == -1 ||
+	    fcntl(s, F_SETFD, xlags | FD_CLOEXEC) == -1)
+		goto out;
+	if ((flags & O_NONBLOCK) && (xflags = fcntl(s, F_GETFL, 0)) == -1 ||
+	    fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1)
+		goto out;
+	return s;
+out:
+	close(s);
+	return -1;
+#endif
+}

Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.43 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.44
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.43	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.8.in,v 1.43 2015/07/09 10:15:34 roy Exp $
+.\"     $NetBSD: dhcpcd.8.in,v 1.44 2015/08/21 10:39:00 roy Exp $
 .\" Copyright (c) 2006-2015 Roy Marples
 .\" All rights reserved
 .\"
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd July 3, 2015
+.Dd August 21, 2015
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -204,7 +204,7 @@ This script runs each script found in
 in a lexical order.
 The default installation supplies the scripts
 .Pa 01-test ,
-.Pa 10-mtu ,
+.Pa 02-dump ,
 .Pa 10-wpa_supplicant ,
 .Pa 15-timezone ,
 .Pa 20-resolv.conf
@@ -552,8 +552,8 @@ Matches full name, or prefixed with 2 nu
 .Pp
 So to stop
 .Nm
-from touching your DNS or MTU settings you would do:-
-.D1 dhcpcd -C resolv.conf -C mtu eth0
+from touching your DNS settings you would do:-
+.D1 dhcpcd -C resolv.conf eth0
 .It Fl G , Fl Fl nogateway
 Don't set any default routes.
 .It Fl H , Fl Fl xidhwaddr

Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.26 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.27
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.26	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.26 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.27 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -575,10 +575,6 @@ configure_interface1(struct interface *i
 		}
 	}
 #endif
-
-	/* If we are not sending an authentication option, don't require it */
-	if (!(ifo->auth.options & DHCPCD_AUTH_SEND))
-		ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE;
 }
 
 int
@@ -703,6 +699,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
 			script_runreason(ifp, "NOCARRIER");
 #ifdef NOCARRIER_PRESERVE_IP
 			arp_close(ifp);
+			dhcp_abort(ifp);
 			if_sortinterfaces(ctx);
 			ipv4_preferanother(ifp);
 			ipv6nd_expire(ifp, 0);
@@ -907,7 +904,9 @@ dhcpcd_prestartinterface(void *arg)
 	struct interface *ifp = arg;
 
 	pre_start(ifp);
-	if (if_up(ifp) == -1)
+	if ((!(ifp->ctx->options & DHCPCD_MASTER) ||
+	    ifp->options->options & DHCPCD_IF_UP) &&
+	    if_up(ifp) == -1)
 		logger(ifp->ctx, LOG_ERR, "%s: if_up: %m", ifp->name);
 
 	if (ifp->options->options & DHCPCD_LINK &&
@@ -1395,6 +1394,14 @@ main(int argc, char **argv)
 	ifo = NULL;
 	ctx.cffile = CONFIG;
 	ctx.pid_fd = ctx.control_fd = ctx.control_unpriv_fd = ctx.link_fd = -1;
+	ctx.pf_inet_fd = -1;
+#if defined(INET6) && defined(BSD)
+	ctx.pf_inet6_fd = -1;
+#endif
+#ifdef IFLR_ACTIVE
+	ctx.pf_link_fd = -1;
+#endif
+
 	TAILQ_INIT(&ctx.control_fds);
 #ifdef PLUGIN_DEV
 	ctx.dev_fd = -1;
@@ -1760,17 +1767,12 @@ main(int argc, char **argv)
 	if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND))
 		ctx.options |= DHCPCD_WAITIP;
 
-	/* RTM_NEWADDR goes through the link socket as well which we
-	 * need for IPv6 DAD, so we check for DHCPCD_LINK in
-	 * dhcpcd_handlecarrier instead.
-	 * We also need to open this before checking for interfaces below
-	 * so that we pickup any new addresses during the discover phase. */
-	ctx.link_fd = if_openlinksocket();
-	if (ctx.link_fd == -1)
-		logger(&ctx, LOG_ERR, "open_link_socket: %m");
-	else
-		eloop_event_add(ctx.eloop, ctx.link_fd,
-		    handle_link, &ctx, NULL, NULL);
+	/* Open our persistent sockets. */
+	if (if_opensockets(&ctx) == -1) {
+		logger(&ctx, LOG_ERR, "if_opensockets: %m");
+		goto exit_failure;
+	}
+	eloop_event_add(ctx.eloop, ctx.link_fd, handle_link, &ctx, NULL, NULL);
 
 	/* Start any dev listening plugin which may want to
 	 * change the interface name provided by the kernel */
@@ -1875,6 +1877,17 @@ exit1:
 		eloop_event_delete(ctx.eloop, ctx.link_fd);
 		close(ctx.link_fd);
 	}
+	if (ctx.pf_inet_fd != -1)
+		close(ctx.pf_inet_fd);
+#if defined(INET6) && defined(BSD)
+	if (ctx.pf_inet6_fd != -1)
+		close(ctx.pf_inet6_fd);
+#endif
+#ifdef IFLR_ACTIVE
+	if (ctx.pf_link_fd != -1)
+		close(ctx.pf_link_fd);
+#endif
+
 
 	free_options(ifo);
 	free_globals(&ctx);

Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.16 src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.17
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf:1.16	Thu Mar 26 10:26:37 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-# $NetBSD: dhcpcd.conf,v 1.16 2015/03/26 10:26:37 roy Exp $
+# $NetBSD: dhcpcd.conf,v 1.17 2015/08/21 10:39:00 roy Exp $
 
 # A sample configuration for dhcpcd.
 # See dhcpcd.conf(5) for details.
@@ -30,9 +30,8 @@ option domain_name_servers, domain_name,
 option classless_static_routes
 # Most distributions have NTP support.
 option ntp_servers
-# Respect the network MTU.
-# Some interface drivers reset when changing the MTU so disabled by default.
-#option interface_mtu
+# Respect the network MTU. This is applied to DHCP routes.
+option interface_mtu
 
 # A ServerID is required by RFC2131.
 require dhcp_server_identifier
Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.16 src/external/bsd/dhcpcd/dist/ipv4.c:1.17
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.16	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/ipv4.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.16 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.17 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -296,6 +296,11 @@ desc_route(const char *cmd, const struct
 	else if (rt->net.s_addr == htonl(INADDR_BROADCAST))
 		logger(ctx, LOG_INFO, "%s: %s host route to %s via %s",
 		    ifname, cmd, addr, inet_ntoa(rt->gate));
+	else if (rt->dest.s_addr == htonl(INADDR_ANY) &&
+	    rt->net.s_addr == htonl(INADDR_ANY) &&
+	    rt->gate.s_addr == htonl(INADDR_ANY))
+		logger(ctx, LOG_INFO, "%s: %s default route",
+		    ifname, cmd);
 	else if (rt->gate.s_addr == htonl(INADDR_ANY))
 		logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
 		    ifname, cmd, addr, inet_ntocidr(rt->net));
@@ -383,6 +388,7 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, in
 static int
 nc_route(struct rt *ort, struct rt *nrt)
 {
+	int change;
 
 	/* Don't set default routes if not asked to */
 	if (nrt->dest.s_addr == 0 &&
@@ -392,6 +398,7 @@ nc_route(struct rt *ort, struct rt *nrt)
 
 	desc_route(ort == NULL ? "adding" : "changing", nrt);
 
+	change = 0;
 	if (ort == NULL) {
 		ort = ipv4_findrt(nrt->iface->ctx, nrt, 0);
 		if (ort &&
@@ -401,8 +408,12 @@ nc_route(struct rt *ort, struct rt *nrt)
 		    ort->metric == nrt->metric &&
 #endif
 		    ort->gate.s_addr == nrt->gate.s_addr)))
-			return 0;
-	} else if (ort->flags & STATE_FAKE && !(nrt->flags & STATE_FAKE) &&
+		{
+			if (ort->mtu == nrt->mtu)
+				return 0;
+			change = 1;
+		}
+	} else if (ort->state & STATE_FAKE && !(nrt->state & STATE_FAKE) &&
 	    ort->iface == nrt->iface &&
 #ifdef HAVE_ROUTE_METRIC
 	    ort->metric == nrt->metric &&
@@ -410,12 +421,32 @@ nc_route(struct rt *ort, struct rt *nrt)
 	    ort->dest.s_addr == nrt->dest.s_addr &&
 	    ort->net.s_addr ==  nrt->net.s_addr &&
 	    ort->gate.s_addr == nrt->gate.s_addr)
-		return 0;
+	{
+		if (ort->mtu == nrt->mtu)
+			return 0;
+		change = 1;
+	}
+
+#ifdef RTF_CLONING
+	/* BSD can set routes to be cloning routes.
+	 * Cloned routes inherit the parent flags.
+	 * As such, we need to delete and re-add the route to flush children
+	 * to correct the flags. */
+	if (change && ort != NULL && ort->flags & RTF_CLONING)
+		change = 0;
+#endif
+
+	if (change) {
+		if (if_route(RTM_CHANGE, nrt) == 0)
+			return 0;
+		if (errno != ESRCH)
+			logger(nrt->iface->ctx, LOG_ERR, "if_route (CHG): %m");
+	}
 
 #ifdef HAVE_ROUTE_METRIC
 	/* With route metrics, we can safely add the new route before
 	 * deleting the old route. */
-	if (if_route(RTM_ADD, nrt)  == 0) {
+	if (if_route(RTM_ADD, nrt) == 0) {
 		if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
 			logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
 		return 0;
@@ -472,7 +503,7 @@ add_subnet_route(struct rt_head *rt, con
 		return rt;
 #endif
 
-	if ((r = malloc(sizeof(*r))) == NULL) {
+	if ((r = calloc(1, sizeof(*r))) == NULL) {
 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
 		ipv4_freeroutes(rt);
 		return NULL;
@@ -480,6 +511,7 @@ add_subnet_route(struct rt_head *rt, con
 	r->dest.s_addr = s->addr.s_addr & s->net.s_addr;
 	r->net.s_addr = s->net.s_addr;
 	r->gate.s_addr = INADDR_ANY;
+	r->mtu = dhcp_get_mtu(ifp);
 	r->src = s->addr;
 
 	TAILQ_INSERT_HEAD(rt, r, next);
@@ -500,8 +532,7 @@ add_loopback_route(struct rt_head *rt, c
 	if (s->addr.s_addr == INADDR_ANY)
 		return rt;
 
-	r = malloc(sizeof(*r));
-	if (r == NULL) {
+	if ((r = calloc(1, sizeof(*r))) == NULL) {
 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
 		ipv4_freeroutes(rt);
 		return NULL;
@@ -509,6 +540,7 @@ add_loopback_route(struct rt_head *rt, c
 	r->dest = s->addr;
 	r->net.s_addr = INADDR_BROADCAST;
 	r->gate.s_addr = htonl(INADDR_LOOPBACK);
+	r->mtu = dhcp_get_mtu(ifp);
 	r->src = s->addr;
 	TAILQ_INSERT_HEAD(rt, r, next);
 	return rt;
@@ -529,8 +561,7 @@ get_routes(struct interface *ifp)
 		TAILQ_FOREACH(rt, ifp->options->routes, next) {
 			if (rt->gate.s_addr == 0)
 				break;
-			r = malloc(sizeof(*r));
-			if (r == NULL) {
+			if ((r = calloc(1, sizeof(*r))) == NULL) {
 				logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
 				ipv4_freeroutes(nrt);
 				return NULL;
@@ -539,7 +570,7 @@ get_routes(struct interface *ifp)
 			TAILQ_INSERT_TAIL(nrt, r, next);
 		}
 	} else
-		nrt = get_option_routes(ifp, D_STATE(ifp)->new);
+		nrt = dhcp_get_routes(ifp);
 
 	/* Copy our address as the source address */
 	if (nrt) {
@@ -564,8 +595,7 @@ add_destination_route(struct rt_head *rt
 	    (state = D_CSTATE(ifp)) == NULL)
 		return rt;
 
-	r = malloc(sizeof(*r));
-	if (r == NULL) {
+	if ((r = calloc(1, sizeof(*r))) == NULL) {
 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
 		ipv4_freeroutes(rt);
 		return NULL;
@@ -573,6 +603,8 @@ add_destination_route(struct rt_head *rt
 	r->dest.s_addr = INADDR_ANY;
 	r->net.s_addr = INADDR_ANY;
 	r->gate.s_addr = state->dst.s_addr;
+	r->mtu = dhcp_get_mtu(ifp);
+	r->src = state->addr;
 	TAILQ_INSERT_HEAD(rt, r, next);
 	return rt;
 }
@@ -637,8 +669,7 @@ add_router_host_route(struct rt_head *rt
 			    "%s: router %s requires a host route",
 			    ifp->name, inet_ntoa(rtp->gate));
 		}
-		rtn = malloc(sizeof(*rtn));
-		if (rtn == NULL) {
+		if ((rtn = calloc(1, sizeof(*rtn))) == NULL) {
 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
 			ipv4_freeroutes(rt);
 			return NULL;
@@ -646,18 +677,72 @@ add_router_host_route(struct rt_head *rt
 		rtn->dest.s_addr = rtp->gate.s_addr;
 		rtn->net.s_addr = htonl(INADDR_BROADCAST);
 		rtn->gate.s_addr = htonl(INADDR_ANY);
+		rtn->mtu = dhcp_get_mtu(ifp);
+		rtn->src = state->addr;
 		TAILQ_INSERT_BEFORE(rtp, rtn, next);
 	}
 	return rt;
 }
 
+static int
+ipv4_doroute(struct rt *rt, struct rt_head *nrs)
+{
+	const struct dhcp_state *state;
+	struct rt *or;
+
+	state = D_CSTATE(rt->iface);
+	rt->state = state->added & STATE_FAKE;
+#ifdef HAVE_ROUTE_METRIC
+	rt->metric = rt->iface->metric;
+#endif
+	/* Is this route already in our table? */
+	if ((find_route(nrs, rt, NULL)) != NULL)
+		return 0;
+	/* Do we already manage it? */
+	if ((or = find_route(rt->iface->ctx->ipv4_routes, rt, NULL))) {
+		if (state->added & STATE_FAKE)
+			return 0;
+		if (or->state & STATE_FAKE ||
+		    or->iface != rt->iface ||
+#ifdef HAVE_ROUTE_METRIC
+		    rt->metric != or->metric ||
+#endif
+		    rt->src.s_addr != or->src.s_addr ||
+		    rt->gate.s_addr != or->gate.s_addr ||
+		    rt->mtu != or->mtu)
+		{
+			if (c_route(or, rt) != 0)
+				return 0;
+		}
+		TAILQ_REMOVE(rt->iface->ctx->ipv4_routes, or, next);
+		free(or);
+	} else {
+		if (state->added & STATE_FAKE) {
+			if ((or = ipv4_findrt(rt->iface->ctx, rt, 1)) == NULL)
+				return 0;
+			rt->iface = or->iface;
+			rt->gate.s_addr = or->gate.s_addr;
+#ifdef HAVE_ROUTE_METRIC
+			rt->metric = or->metric;
+#endif
+			rt->mtu = or->mtu;
+			rt->flags = or->flags;
+		} else {
+			if (n_route(rt) != 0)
+				return 0;
+		}
+	}
+	return 1;
+}
+
 void
 ipv4_buildroutes(struct dhcpcd_ctx *ctx)
 {
 	struct rt_head *nrs, *dnr;
-	struct rt *or, *rt, *rtn;
+	struct rt *rt, *rtn;
 	struct interface *ifp;
 	const struct dhcp_state *state;
+	int has_default;
 
 	/* We need to have the interfaces in the correct order to ensure
 	 * our routes are managed correctly. */
@@ -669,6 +754,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
 	}
 	TAILQ_INIT(nrs);
 
+	has_default = 0;
 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
 		state = D_CSTATE(ifp);
 		if (state != NULL && state->new != NULL && state->added) {
@@ -700,48 +786,29 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
 			continue;
 		TAILQ_FOREACH_SAFE(rt, dnr, next, rtn) {
 			rt->iface = ifp;
-#ifdef HAVE_ROUTE_METRIC
-			rt->metric = ifp->metric;
-#endif
-			rt->flags = state->added & STATE_FAKE;
-			/* Is this route already in our table? */
-			if ((find_route(nrs, rt, NULL)) != NULL)
-				continue;
-			/* Do we already manage it? */
-			if ((or = find_route(ctx->ipv4_routes, rt, NULL))) {
-				if (state->added & STATE_FAKE)
-					continue;
-				if (or->flags & STATE_FAKE ||
-				    or->iface != ifp ||
-#ifdef HAVE_ROUTE_METRIC
-				    rt->metric != or->metric ||
-#endif
-				    rt->src.s_addr != or->src.s_addr ||
-				    rt->gate.s_addr != or->gate.s_addr)
-				{
-					if (c_route(or, rt) != 0)
-						continue;
-				}
-				TAILQ_REMOVE(ctx->ipv4_routes, or, next);
-				free(or);
-			} else {
-				if (state->added & STATE_FAKE) {
-					or = ipv4_findrt(ctx, rt, 1);
-					if (or == NULL ||
-					    or->gate.s_addr != rt->gate.s_addr)
-						continue;
-				} else {
-					if (n_route(rt) != 0)
-						continue;
-				}
+			if (ipv4_doroute(rt, nrs) == 1) {
+				TAILQ_REMOVE(dnr, rt, next);
+				TAILQ_INSERT_TAIL(nrs, rt, next);
+				if (rt->dest.s_addr == INADDR_ANY)
+					has_default = 1;
 			}
-			rt->flags |= STATE_ADDED;
-			TAILQ_REMOVE(dnr, rt, next);
-			TAILQ_INSERT_TAIL(nrs, rt, next);
 		}
 		ipv4_freeroutes(dnr);
 	}
 
+	/* If we don't manage a default route, grab one without a
+	 * gateway for any IPv4LL enabled interfaces. */
+	if (!has_default) {
+		TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+			if ((rt = ipv4ll_default_route(ifp)) != NULL) {
+				if (ipv4_doroute(rt, nrs) == 1)
+					TAILQ_INSERT_TAIL(nrs, rt, next);
+				else
+					free(rt);
+			}
+		}
+	}
+
 	/* Remove old routes we used to manage */
 	if (ctx->ipv4_routes) {
 		TAILQ_FOREACH(rt, ctx->ipv4_routes, next) {

Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.22 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.23
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.22	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.conf.5.in,v 1.22 2015/07/09 10:15:34 roy Exp $
+.\"     $NetBSD: dhcpcd.conf.5.in,v 1.23 2015/08/21 10:39:00 roy Exp $
 .\" Copyright (c) 2006-2015 Roy Marples
 .\" All rights reserved
 .\"
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd July 9, 2015
+.Dd August 1, 2015
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -408,6 +408,7 @@ Don't send any ARP requests.
 This also disables IPv4LL.
 .It Ic noauthrequired
 Don't require authentication even though we requested it.
+Also allows FORCERENEW and RECONFIGURE messages without authentication.
 .It Ic nodelay
 Don't delay for an initial randomised time when starting protocols.
 .It Ic nodev
@@ -431,8 +432,8 @@ Matches full name, or prefixed with 2 nu
 .Pp
 So to stop
 .Nm dhcpcd
-from touching your DNS or MTU settings you would do:-
-.D1 nohook resolv.conf, mtu
+from touching your DNS settings or starting wpa_supplicant you would do:-
+.D1 nohook resolv.conf, wpa_supplicant
 .It Ic noipv4
 Don't attempt to configure an IPv4 address.
 .It Ic noipv4ll
@@ -448,6 +449,14 @@ Disable solicitation and receipt of IPv6
 .It Ic nolink
 Don't receive link messages about carrier status.
 You should only set this for buggy interface drivers.
+.It Ic noup
+Don't bring the interface up when in master mode.
+If
+.Nm
+cannot determine the carrier state,
+.Nm
+will enter a tight polling loop until the interface is marked up and running
+or a valid carrier state is reported.
 .It Ic option Ar option
 Requests the
 .Ar option
@@ -464,7 +473,8 @@ lines.
 Prepend dhcp6_ to
 .Ar option
 to request a DHCPv6 option.
-DHCPv4 options are mapped to DHCPv6 where applicable.
+If no DHCPv6 options are configured,
+then DHCPv4 options are mapped to equivalent DHCPv6 options.
 .Pp
 Prepend nd_ to
 .Ar option
Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.22 src/external/bsd/dhcpcd/dist/if-bsd.c:1.23
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.22	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/if-bsd.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.22 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.23 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -84,6 +84,7 @@
 #include "if.h"
 #include "if-options.h"
 #include "ipv4.h"
+#include "ipv4ll.h"
 #include "ipv6.h"
 #include "ipv6nd.h"
 
@@ -127,27 +128,7 @@ int
 if_openlinksocket(void)
 {
 
-#ifdef SOCK_CLOEXEC
-	return socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
-#else
-	int s, flags;
-
-	if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
-		return -1;
-	if ((flags = fcntl(s, F_GETFD, 0)) == -1 ||
-	    fcntl(s, F_SETFD, flags | FD_CLOEXEC) == -1)
-	{
-		close(s);
-	        return -1;
-	}
-	if ((flags = fcntl(s, F_GETFL, 0)) == -1 ||
-	    fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
-	{
-		close(s);
-	        return -1;
-	}
-	return s;
-#endif
+	return xsocket(PF_ROUTE, SOCK_RAW, 0, O_NONBLOCK|O_CLOEXEC);
 }
 
 #if defined(INET) || defined(INET6)
@@ -164,9 +145,9 @@ if_linkaddr(struct sockaddr_dl *sdl, con
 #endif
 
 static int
-if_getssid1(const char *ifname, uint8_t *ssid)
+if_getssid1(int s, const char *ifname, uint8_t *ssid)
 {
-	int s, retval = -1;
+	int retval = -1;
 #if defined(SIOCG80211NWID)
 	struct ifreq ifr;
 	struct ieee80211_nwid nwid;
@@ -175,9 +156,6 @@ if_getssid1(const char *ifname, uint8_t 
 	char nwid[IEEE80211_NWID_LEN + 1];
 #endif
 
-	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-		return -1;
-
 #if defined(SIOCG80211NWID) /* NetBSD */
 	memset(&ifr, 0, sizeof(ifr));
 	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
@@ -216,7 +194,6 @@ if_getssid1(const char *ifname, uint8_t 
 	}
 #endif
 
-	close(s);
 	return retval;
 }
 
@@ -225,7 +202,7 @@ if_getssid(struct interface *ifp)
 {
 	int r;
 
-	r = if_getssid1(ifp->name, ifp->ssid);
+	r = if_getssid1(ifp->ctx->pf_inet_fd, ifp->name, ifp->ssid);
 	if (r != -1)
 		ifp->ssid_len = (unsigned int)r;
 	return r;
@@ -239,23 +216,20 @@ if_getssid(struct interface *ifp)
  * returning the SSID gives an error.
  */
 int
-if_vimaster(const char *ifname)
+if_vimaster(const struct dhcpcd_ctx *ctx, const char *ifname)
 {
-	int s, r;
+	int r;
 	struct ifmediareq ifmr;
 
-	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-		return -1;
 	memset(&ifmr, 0, sizeof(ifmr));
 	strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
-	r = ioctl(s, SIOCGIFMEDIA, &ifmr);
-	close(s);
+	r = ioctl(ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr);
 	if (r == -1)
 		return -1;
 	if (ifmr.ifm_status & IFM_AVALID &&
 	    IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211)
 	{
-		if (if_getssid1(ifname, NULL) == -1)
+		if (if_getssid1(ctx->pf_inet_fd, ifname, NULL) == -1)
 			return 1;
 	}
 	return 0;
@@ -450,12 +424,9 @@ if_address(const struct interface *ifp, 
     const struct in_addr *netmask, const struct in_addr *broadcast,
     int action)
 {
-	int s, r;
+	int r;
 	struct in_aliasreq ifra;
 
-	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
-		return -1;
-
 	memset(&ifra, 0, sizeof(ifra));
 	strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name));
 
@@ -470,9 +441,8 @@ if_address(const struct interface *ifp, 
 		ADDADDR(&ifra.ifra_broadaddr, broadcast);
 #undef ADDADDR
 
-	r = ioctl(s,
+	r = ioctl(ifp->ctx->pf_inet_fd,
 	    action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
-	close(s);
 	return r;
 }
 
@@ -503,6 +473,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct
 
 	get_addrs(rtm->rtm_addrs, cp, rti_info);
 	memset(rt, 0, sizeof(*rt));
+	rt->flags = (unsigned int)rtm->rtm_flags;
 	COPYOUT(rt->dest, rti_info[RTAX_DST]);
 	if (rtm->rtm_addrs & RTA_NETMASK)
 		COPYOUT(rt->net, rti_info[RTAX_NETMASK]);
@@ -511,6 +482,9 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct
 	COPYOUT(rt->gate, rti_info[RTAX_GATEWAY]);
 	COPYOUT(rt->src, rti_info[RTAX_IFA]);
 
+	if (rtm->rtm_inits & RTV_MTU)
+		rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu;
+
 	if (rtm->rtm_index)
 		rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
 	else if (rtm->rtm_addrs & RTA_IFP) {
@@ -519,6 +493,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct
 		sdl = (struct sockaddr_dl *)(void *)rti_info[RTAX_IFP];
 		rt->iface = if_findsdl(ctx, sdl);
 	}
+
 	/* If we don't have an interface and it's a host route, it maybe
 	 * to a local ip via the loopback interface. */
 	if (rt->iface == NULL &&
@@ -537,6 +512,7 @@ int
 if_route(unsigned char cmd, const struct rt *rt)
 {
 	const struct dhcp_state *state;
+	const struct ipv4ll_state *istate;
 	union sockunion {
 		struct sockaddr sa;
 		struct sockaddr_in sin;
@@ -549,10 +525,6 @@ if_route(unsigned char cmd, const struct
 	} rtm;
 	char *bp = rtm.buffer;
 	size_t l;
-	int s, retval;
-
-	if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
-		return -1;
 
 #define ADDSU {								      \
 		l = RT_ROUNDUP(su.sa.sa_len);				      \
@@ -563,14 +535,18 @@ if_route(unsigned char cmd, const struct
 		memset(&su, 0, sizeof(su));				      \
 		su.sin.sin_family = AF_INET;				      \
 		su.sin.sin_len = sizeof(su.sin);			      \
-		(&su.sin)->sin_addr = *addr;				      \
+		(&su.sin)->sin_addr = *(addr);				      \
 		ADDSU;							      \
 	}
 
-	if (cmd != RTM_DELETE)
+	if (cmd != RTM_DELETE) {
 		state = D_CSTATE(rt->iface);
-	else	/* appease GCC */
+		istate = IPV4LL_CSTATE(rt->iface);
+	} else {
+		/* appease GCC */
 		state = NULL;
+		istate = NULL;
+	}
 	memset(&rtm, 0, sizeof(rtm));
 	rtm.hdr.rtm_version = RTM_VERSION;
 	rtm.hdr.rtm_seq = 1;
@@ -587,9 +563,14 @@ if_route(unsigned char cmd, const struct
 	if (cmd != RTM_DELETE) {
 		rtm.hdr.rtm_addrs |= RTA_IFA | RTA_IFP;
 		/* None interface subnet routes are static. */
-		if (rt->gate.s_addr != INADDR_ANY ||
+		if ((rt->gate.s_addr != INADDR_ANY ||
 		    rt->net.s_addr != state->net.s_addr ||
-		    rt->dest.s_addr != (state->addr.s_addr & state->net.s_addr))
+		    rt->dest.s_addr !=
+		    (state->addr.s_addr & state->net.s_addr)) &&
+		    (istate == NULL ||
+		    rt->dest.s_addr !=
+		    (istate->addr.s_addr & inaddr_llmask.s_addr) ||
+		    rt->net.s_addr != inaddr_llmask.s_addr))
 			rtm.hdr.rtm_flags |= RTF_STATIC;
 		else {
 #ifdef RTF_CLONING
@@ -660,16 +641,20 @@ if_route(unsigned char cmd, const struct
 		}
 
 		if (rtm.hdr.rtm_addrs & RTA_IFA)
-			ADDADDR(&state->addr);
+			ADDADDR(istate == NULL ? &state->addr : &istate->addr);
+
+		if (rt->mtu) {
+			rtm.hdr.rtm_inits |= RTV_MTU;
+			rtm.hdr.rtm_rmx.rmx_mtu = rt->mtu;
+		}
 	}
 
 #undef ADDADDR
 #undef ADDSU
 
 	rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm);
-	retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
-	close(s);
-	return retval;
+	return write(rt->iface->ctx->link_fd,
+	    &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
 }
 
 int
@@ -713,23 +698,17 @@ if_initrt(struct interface *ifp)
 int
 if_addrflags(const struct in_addr *addr, const struct interface *ifp)
 {
-	int s, flags;
 	struct ifreq ifr;
 	struct sockaddr_in *sin;
 
-	s = socket(PF_INET, SOCK_DGRAM, 0);
-	flags = -1;
-	if (s != -1) {
-		memset(&ifr, 0, sizeof(ifr));
-		strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
-		sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr;
-		sin->sin_family = AF_INET;
-		sin->sin_addr = *addr;
-		if (ioctl(s, SIOCGIFAFLAG_IN, &ifr) != -1)
-			flags = ifr.ifr_addrflags;
-		close(s);
-	}
-	return flags;
+	memset(&ifr, 0, sizeof(ifr));
+	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+	sin = (struct sockaddr_in *)(void *)&ifr.ifr_addr;
+	sin->sin_family = AF_INET;
+	sin->sin_addr = *addr;
+	if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1)
+		return -1;
+	return ifr.ifr_addrflags;
 }
 #else
 int
@@ -775,17 +754,13 @@ ifa_scope(struct sockaddr_in6 *sin, unsi
 #endif
 
 int
-if_address6(const struct ipv6_addr *a, int action)
+if_address6(const struct ipv6_addr *ia, int action)
 {
-	int s, r;
 	struct in6_aliasreq ifa;
 	struct in6_addr mask;
 
-	if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
-		return -1;
-
 	memset(&ifa, 0, sizeof(ifa));
-	strlcpy(ifa.ifra_name, a->iface->name, sizeof(ifa.ifra_name));
+	strlcpy(ifa.ifra_name, ia->iface->name, sizeof(ifa.ifra_name));
 	/*
 	 * We should not set IN6_IFF_TENTATIVE as the kernel should be
 	 * able to work out if it's a new address or not.
@@ -795,31 +770,30 @@ if_address6(const struct ipv6_addr *a, i
 	 * either.
 	 */
 #if 0
-	if (a->autoconf)
+	if (ia->autoconf)
 		ifa.ifra_flags |= IN6_IFF_AUTOCONF;
 #endif
 #ifdef IPV6_MANGETEMPADDR
-	if (a->flags & IPV6_AF_TEMPORARY)
+	if (ia->flags & IPV6_AF_TEMPORARY)
 		ifa.ifra_flags |= IN6_IFF_TEMPORARY;
 #endif
 
 #define ADDADDR(v, addr) {						      \
 		(v)->sin6_family = AF_INET6;				      \
 		(v)->sin6_len = sizeof(*v);				      \
-		(v)->sin6_addr = *addr;					      \
+		(v)->sin6_addr = *(addr);				      \
 	}
 
-	ADDADDR(&ifa.ifra_addr, &a->addr);
-	ifa_scope(&ifa.ifra_addr, a->iface->index);
-	ipv6_mask(&mask, a->prefix_len);
+	ADDADDR(&ifa.ifra_addr, &ia->addr);
+	ifa_scope(&ifa.ifra_addr, ia->iface->index);
+	ipv6_mask(&mask, ia->prefix_len);
 	ADDADDR(&ifa.ifra_prefixmask, &mask);
-	ifa.ifra_lifetime.ia6t_vltime = a->prefix_vltime;
-	ifa.ifra_lifetime.ia6t_pltime = a->prefix_pltime;
+	ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime;
+	ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime;
 #undef ADDADDR
 
-	r = ioctl(s, action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
-	close(s);
-	return r;
+	return ioctl(ia->iface->ctx->pf_inet6_fd,
+	    action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
 }
 
 
@@ -900,6 +874,9 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struc
 		ipv6_mask(&rt->net, 128);
 	COPYOUT6(rt->gate, rti_info[RTAX_GATEWAY]);
 
+	if (rtm->rtm_inits & RTV_MTU)
+		rt->mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu;
+
 	if (rtm->rtm_index)
 		rt->iface = if_findindex(ctx->ifaces, rtm->rtm_index);
 	else if (rtm->rtm_addrs & RTA_IFP) {
@@ -937,10 +914,6 @@ if_route6(unsigned char cmd, const struc
 	} rtm;
 	char *bp = rtm.buffer;
 	size_t l;
-	int s, retval;
-
-	if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
-		return -1;
 
 #define ADDSU {								      \
 		l = RT_ROUNDUP(su.sa.sa_len);				      \
@@ -1025,9 +998,8 @@ if_route6(unsigned char cmd, const struc
 #undef ADDSU
 
 	rtm.hdr.rtm_msglen = (unsigned short)(bp - (char *)&rtm);
-	retval = write(s, &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
-	close(s);
-	return retval;
+	return write(rt->iface->ctx->link_fd,
+	    &rtm, rtm.hdr.rtm_msglen) == -1 ? -1 : 0;
 }
 
 int
@@ -1070,67 +1042,56 @@ if_initrt6(struct interface *ifp)
 int
 if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
 {
-	int s, flags;
+	int flags;
 	struct in6_ifreq ifr6;
 
-	s = socket(PF_INET6, SOCK_DGRAM, 0);
-	flags = -1;
-	if (s != -1) {
-		memset(&ifr6, 0, sizeof(ifr6));
-		strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name));
-		ifr6.ifr_addr.sin6_family = AF_INET6;
-		ifr6.ifr_addr.sin6_addr = *addr;
-		ifa_scope(&ifr6.ifr_addr, ifp->index);
-		if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) != -1)
-			flags = ifr6.ifr_ifru.ifru_flags6;
-		close(s);
-	}
+	memset(&ifr6, 0, sizeof(ifr6));
+	strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name));
+	ifr6.ifr_addr.sin6_family = AF_INET6;
+	ifr6.ifr_addr.sin6_addr = *addr;
+	ifa_scope(&ifr6.ifr_addr, ifp->index);
+	if (ioctl(ifp->ctx->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
+		flags = ifr6.ifr_ifru.ifru_flags6;
+	else
+		flags = -1;
 	return flags;
 }
 
 int
 if_getlifetime6(struct ipv6_addr *ia)
 {
-	int s, r;
+	int r;
 	struct in6_ifreq ifr6;
+	time_t t;
+	struct in6_addrlifetime *lifetime;
 
-	s = socket(PF_INET6, SOCK_DGRAM, 0);
 	r = -1;
-	if (s != -1) {
-		memset(&ifr6, 0, sizeof(ifr6));
-		strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
-		ifr6.ifr_addr.sin6_family = AF_INET6;
-		ifr6.ifr_addr.sin6_addr = ia->addr;
-		ifa_scope(&ifr6.ifr_addr, ia->iface->index);
-		if (ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) != -1) {
-			time_t t;
-			struct in6_addrlifetime *lifetime;
-
-			t = time(NULL);
-			lifetime = &ifr6.ifr_ifru.ifru_lifetime;
-
-			if (lifetime->ia6t_preferred)
-				ia->prefix_pltime =
-				    (uint32_t)(lifetime->ia6t_preferred -
-				    MIN(t, lifetime->ia6t_preferred));
-			else
-				ia->prefix_pltime = ND6_INFINITE_LIFETIME;
-			if (lifetime->ia6t_expire) {
-				ia->prefix_vltime =
-				    (uint32_t)(lifetime->ia6t_expire -
-				    MIN(t, lifetime->ia6t_expire));
-				/* Calculate the created time */
-				clock_gettime(CLOCK_MONOTONIC, &ia->created);
-				ia->created.tv_sec -=
-				    lifetime->ia6t_vltime - ia->prefix_vltime;
-			} else
-				ia->prefix_vltime = ND6_INFINITE_LIFETIME;
+	memset(&ifr6, 0, sizeof(ifr6));
+	strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
+	ifr6.ifr_addr.sin6_family = AF_INET6;
+	ifr6.ifr_addr.sin6_addr = ia->addr;
+	ifa_scope(&ifr6.ifr_addr, ia->iface->index);
+	if (ioctl(ia->iface->ctx->pf_inet6_fd,
+	    SIOCGIFALIFETIME_IN6, &ifr6) == -1)
+		return -1;
 
-			r = 0;
-		}
-		close(s);
-	}
-	return r;
+	t = time(NULL);
+	lifetime = &ifr6.ifr_ifru.ifru_lifetime;
+
+	if (lifetime->ia6t_preferred)
+		ia->prefix_pltime = (uint32_t)(lifetime->ia6t_preferred -
+		    MIN(t, lifetime->ia6t_preferred));
+	else
+		ia->prefix_pltime = ND6_INFINITE_LIFETIME;
+	if (lifetime->ia6t_expire) {
+		ia->prefix_vltime = (uint32_t)(lifetime->ia6t_expire -
+		    MIN(t, lifetime->ia6t_expire));
+		/* Calculate the created time */
+		clock_gettime(CLOCK_MONOTONIC, &ia->created);
+		ia->created.tv_sec -= lifetime->ia6t_vltime - ia->prefix_vltime;
+	} else
+		ia->prefix_vltime = ND6_INFINITE_LIFETIME;
+	return 0;
 }
 #endif
 
@@ -1670,12 +1631,7 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 int
 if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own)
 {
-	int s, r;
 
-	if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
-		return -1;
-	r = _if_checkipv6(s, ctx, ifp, own);
-	close(s);
-	return r;
+	return _if_checkipv6(ctx->pf_inet6_fd, ctx, ifp, own);
 }
 #endif

Index: src/external/bsd/dhcpcd/dist/dhcpcd.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.12 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.13
--- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.12	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.h	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: dhcpcd.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -64,6 +64,11 @@
  * dhcpcd can poll it for the relevant flags periodically */
 #define IF_POLL_UP	100	/* milliseconds */
 
+#ifdef __QNX__
+/* QNX carries defines for, but does not actually support PF_LINK */
+#undef IFLR_ACTIVE
+#endif
+
 struct interface {
 	struct dhcpcd_ctx *ctx;
 	TAILQ_ENTRY(interface) next;
@@ -107,9 +112,17 @@ struct dhcpcd_ctx {
 	char **ifcv;	/* configured interfaces */
 	unsigned char *duid;
 	size_t duid_len;
-	int link_fd;
 	struct if_head *ifaces;
 
+	int pf_inet_fd;
+#if defined(INET6) && defined(BSD)
+	int pf_inet6_fd;
+#endif
+#ifdef IFLR_ACTIVE
+	int pf_link_fd;
+#endif
+	int link_fd;
+
 #ifdef USE_SIGNALS
 	sigset_t sigset;
 #endif
@@ -125,6 +138,8 @@ struct dhcpcd_ctx {
 	struct dhcp_opt *vivso;
 	size_t vivso_len;
 
+	char *randomstate; /* original state */
+
 #ifdef INET
 	struct dhcp_opt *dhcp_opts;
 	size_t dhcp_opts_len;
Index: src/external/bsd/dhcpcd/dist/if-options.h
diff -u src/external/bsd/dhcpcd/dist/if-options.h:1.12 src/external/bsd/dhcpcd/dist/if-options.h:1.13
--- src/external/bsd/dhcpcd/dist/if-options.h:1.12	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/if-options.h	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if-options.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: if-options.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -106,7 +106,7 @@
 #define DHCPCD_IAID			(1ULL << 48)
 #define DHCPCD_DHCP			(1ULL << 49)
 #define DHCPCD_DHCP6			(1ULL << 50)
-// unassigned				(1ULL << 51)
+#define DHCPCD_IF_UP			(1ULL << 51)
 // unassigned				(1ULL << 52)
 // unassinged				(1ULL << 53)
 #define DHCPCD_IPV6RA_AUTOCONF		(1ULL << 54)
Index: src/external/bsd/dhcpcd/dist/ipv4.h
diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.12 src/external/bsd/dhcpcd/dist/ipv4.h:1.13
--- src/external/bsd/dhcpcd/dist/ipv4.h:1.12	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/ipv4.h	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4.h,v 1.12 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: ipv4.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -63,8 +63,10 @@ struct rt {
 #ifdef HAVE_ROUTE_METRIC
 	unsigned int metric;
 #endif
+	unsigned int mtu;
 	struct in_addr src;
 	unsigned int flags;
+	unsigned int state;
 };
 TAILQ_HEAD(rt_head, rt);
 

Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.25 src/external/bsd/dhcpcd/dist/if-options.c:1.26
--- src/external/bsd/dhcpcd/dist/if-options.c:1.25	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/if-options.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.25 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.26 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -97,7 +97,7 @@
 #define O_CONTROLGRP		O_BASE + 34
 #define O_SLAAC			O_BASE + 35
 #define O_GATEWAY		O_BASE + 36
-// unassigned			O_BASE + 37
+#define O_NOUP			O_BASE + 37
 #define O_IPV6RA_AUTOCONF	O_BASE + 38
 #define O_IPV6RA_NOAUTOCONF	O_BASE + 39
 #define O_REJECT		O_BASE + 40
@@ -199,6 +199,7 @@ const struct option cf_options[] = {
 	{"reject",          required_argument, NULL, O_REJECT},
 	{"bootp",           no_argument,       NULL, O_BOOTP},
 	{"nodelay",         no_argument,       NULL, O_NODELAY},
+	{"noup",            no_argument,       NULL, O_NOUP},
 	{NULL,              0,                 NULL, '\0'}
 };
 
@@ -2006,6 +2007,9 @@ err_sla:
 	case O_GATEWAY:
 		ifo->options |= DHCPCD_GATEWAY;
 		break;
+	case O_NOUP:
+		ifo->options &= ~DHCPCD_IF_UP;
+		break;
 	case O_SLAAC:
 		if (strcmp(arg, "private") == 0 ||
 		    strcmp(arg, "stableprivate") == 0 ||
@@ -2120,6 +2124,7 @@ read_config(struct dhcpcd_ctx *ctx,
 		return NULL;
 	}
 	ifo->options |= DHCPCD_DAEMONISE | DHCPCD_LINK | DHCPCD_INITIAL_DELAY;
+	ifo->options |= DHCPCD_IF_UP;
 #ifdef PLUGIN_DEV
 	ifo->options |= DHCPCD_DEV;
 #endif
Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.25 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.26
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.25	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.25 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.26 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -192,29 +192,10 @@ ipv6nd_open(struct dhcpcd_ctx *dctx)
 	ctx = dctx->ipv6;
 	if (ctx->nd_fd != -1)
 		return ctx->nd_fd;
-#ifdef SOCK_CLOEXEC
-	ctx->nd_fd = socket(PF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
-	    IPPROTO_ICMPV6);
+	ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
+	    O_NONBLOCK|O_CLOEXEC);
 	if (ctx->nd_fd == -1)
 		return -1;
-#else
-	if ((ctx->nd_fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1)
-		return -1;
-	if ((on = fcntl(ctx->nd_fd, F_GETFD, 0)) == -1 ||
-	    fcntl(ctx->nd_fd, F_SETFD, on | FD_CLOEXEC) == -1)
-	{
-		close(ctx->nd_fd);
-		ctx->nd_fd = -1;
-	        return -1;
-	}
-	if ((on = fcntl(ctx->nd_fd, F_GETFL, 0)) == -1 ||
-	    fcntl(ctx->nd_fd, F_SETFL, on | O_NONBLOCK) == -1)
-	{
-		close(ctx->nd_fd);
-		ctx->nd_fd = -1;
-	        return -1;
-	}
-#endif
 
 	/* RFC4861 4.1 */
 	on = 255;
@@ -735,14 +716,19 @@ try_script:
 }
 
 static int
-ipv6nd_ra_has_public_addr(const struct ra *rap)
+ipv6nd_has_public_addr(const struct interface *ifp)
 {
+	const struct ra *rap;
 	const struct ipv6_addr *ia;
 
-	TAILQ_FOREACH(ia, &rap->addrs, next) {
-		if (ia->flags & IPV6_AF_AUTOCONF &&
-		    ipv6_publicaddr(ia))
-			return 1;
+	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
+		if (rap->iface == ifp) {
+			TAILQ_FOREACH(ia, &rap->addrs, next) {
+				if (ia->flags & IPV6_AF_AUTOCONF &&
+				    ipv6_publicaddr(ia))
+					return 1;
+			}
+		}
 	}
 	return 0;
 }
@@ -1109,7 +1095,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
 	if (new_rap)
 		add_router(ifp->ctx->ipv6, rap);
 
-	if (!ipv6nd_ra_has_public_addr(rap) &&
+	if (!ipv6nd_has_public_addr(rap->iface) &&
 	    !(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) &&
 	    (!(rap->flags & ND_RA_FLAG_MANAGED) ||
 	    !dhcp6_has_public_addr(rap->iface)))

Index: src/external/bsd/dhcpcd/dist/if.h
diff -u src/external/bsd/dhcpcd/dist/if.h:1.11 src/external/bsd/dhcpcd/dist/if.h:1.12
--- src/external/bsd/dhcpcd/dist/if.h:1.11	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/if.h	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.11 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: if.h,v 1.12 2015/08/21 10:39:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -95,16 +95,17 @@ struct interface *if_find(struct if_head
 struct interface *if_findindex(struct if_head *, unsigned int);
 void if_sortinterfaces(struct dhcpcd_ctx *);
 void if_free(struct interface *);
-int if_domtu(const char *, short int);
-#define if_getmtu(iface) if_domtu(iface, 0)
-#define if_setmtu(iface, mtu) if_domtu(iface, mtu)
+int if_domtu(const struct interface *, short int);
+#define if_getmtu(ifp) if_domtu((ifp), 0)
+#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
 int if_carrier(struct interface *);
 
 /* The below functions are provided by if-KERNEL.c */
 int if_conf(struct interface *);
 int if_init(struct interface *);
 int if_getssid(struct interface *);
-int if_vimaster(const char *);
+int if_vimaster(const struct dhcpcd_ctx *ctx, const char *);
+int if_opensockets(struct dhcpcd_ctx *);
 int if_openlinksocket(void);
 int if_managelink(struct dhcpcd_ctx *);
 
@@ -163,4 +164,5 @@ int if_initrt6(struct interface *);
 #endif
 
 int if_machinearch(char *, size_t);
+int xsocket(int, int, int, int);
 #endif
Index: src/external/bsd/dhcpcd/dist/ipv4ll.c
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.11 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.12
--- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.11	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/ipv4ll.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4ll.c,v 1.11 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: ipv4ll.c,v 1.12 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -48,13 +48,17 @@
 #include "ipv4ll.h"
 #include "script.h"
 
-static const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
-static const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) };
+const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
+const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) };
 
 static in_addr_t
 ipv4ll_pick_addr(const struct arp_state *astate)
 {
 	struct in_addr addr;
+	struct ipv4ll_state *istate;
+
+	istate = IPV4LL_STATE(astate->iface);
+	setstate(istate->randomstate);
 
 	do {
 		/* RFC 3927 Section 2.1 states that the first 256 and
@@ -69,6 +73,9 @@ ipv4ll_pick_addr(const struct arp_state 
 		/* Ensure we don't have the address on another interface */
 	} while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL);
 
+	/* Restore the original random state */
+	setstate(astate->iface->ctx->randomstate);
+
 	return addr.s_addr;
 }
 
@@ -83,7 +90,7 @@ ipv4ll_subnet_route(const struct interfa
 	    state->addr.s_addr == INADDR_ANY)
 		return NULL;
 
-	if ((rt = malloc(sizeof(*rt))) == NULL) {
+	if ((rt = calloc(1, sizeof(*rt))) == NULL) {
 		logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__);
 		return NULL;
 	}
@@ -95,6 +102,29 @@ ipv4ll_subnet_route(const struct interfa
 	return rt;
 }
 
+struct rt *
+ipv4ll_default_route(const struct interface *ifp)
+{
+	const struct ipv4ll_state *state;
+	struct rt *rt;
+
+	assert(ifp != NULL);
+	if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
+	    state->addr.s_addr == INADDR_ANY)
+		return NULL;
+
+	if ((rt = calloc(1, sizeof(*rt))) == NULL) {
+		logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__);
+		return NULL;
+	}
+	rt->iface = ifp;
+	rt->dest.s_addr = INADDR_ANY;
+	rt->net.s_addr = INADDR_ANY;
+	rt->gate.s_addr = INADDR_ANY;
+	rt->src = state->addr;
+	return rt;
+}
+
 ssize_t
 ipv4ll_env(char **env, const char *prefix, const struct interface *ifp)
 {
@@ -162,6 +192,7 @@ ipv4ll_probed(struct arp_state *astate)
 #endif
 	state->addr = astate->addr;
 	timespecclear(&state->defend);
+	if_initrt(ifp);
 	ipv4_buildroutes(ifp->ctx);
 	arp_announce(astate);
 	script_runreason(ifp, "IPV4LL");
@@ -295,6 +326,7 @@ ipv4ll_start(void *arg)
 	 * the same address without persistent storage. */
 	if (state->conflicts == 0) {
 		unsigned int seed;
+		char *orig;
 
 		if (sizeof(seed) > ifp->hwlen) {
 			seed = 0;
@@ -302,7 +334,15 @@ ipv4ll_start(void *arg)
 		} else
 			memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed),
 			    sizeof(seed));
-		initstate(seed, state->randomstate, sizeof(state->randomstate));
+		orig = initstate(seed,
+		    state->randomstate, sizeof(state->randomstate));
+
+		/* Save the original state. */
+		if (ifp->ctx->randomstate == NULL)
+			ifp->ctx->randomstate = orig;
+
+		/* Set back the original state until we need the seeded one. */
+		setstate(ifp->ctx->randomstate);
 	}
 
 	if ((astate = arp_new(ifp, NULL)) == NULL)
@@ -338,7 +378,6 @@ ipv4ll_start(void *arg)
 		return;
 	}
 
-	setstate(state->randomstate);
 	logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address",
 	    ifp->name);
 	astate->addr.s_addr = ipv4ll_pick_addr(astate);
@@ -353,9 +392,11 @@ void
 ipv4ll_freedrop(struct interface *ifp, int drop)
 {
 	struct ipv4ll_state *state;
+	int dropped;
 
 	assert(ifp != NULL);
 	state = IPV4LL_STATE(ifp);
+	dropped = 0;
 
 	/* Free ARP state first because ipv4_deladdr might also ... */
 	if (state && state->arp) {
@@ -370,6 +411,7 @@ ipv4ll_freedrop(struct interface *ifp, i
 		if (state && state->addr.s_addr != INADDR_ANY) {
 			ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
 			state->addr.s_addr = INADDR_ANY;
+			dropped = 1;
 		}
 
 		/* Free any other link local addresses that might exist. */
@@ -377,18 +419,22 @@ ipv4ll_freedrop(struct interface *ifp, i
 			struct ipv4_addr *ia, *ian;
 
 			TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
-				if (IN_LINKLOCAL(ntohl(ia->addr.s_addr)))
+				if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
 					ipv4_deladdr(ifp, &ia->addr,
 					    &ia->net, 0);
+					dropped = 1;
+				}
 			}
 		}
-		script_runreason(ifp, "IPV4LL");
 	}
 
 	if (state) {
 		free(state);
 		ifp->if_data[IF_DATA_IPV4LL] = NULL;
 
-		ipv4_buildroutes(ifp->ctx);
+		if (dropped) {
+			ipv4_buildroutes(ifp->ctx);
+			script_runreason(ifp, "IPV4LL");
+		}
 	}
 }

Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.13 src/external/bsd/dhcpcd/dist/ipv6.c:1.14
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.13	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/ipv6.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.13 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.14 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -647,7 +647,13 @@ ipv6_addaddr(struct ipv6_addr *ap, const
 		ap->flags |= IPV6_AF_DADCOMPLETED;
 
 	logger(ap->iface->ctx, ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
-	    "%s: adding address %s", ap->iface->name, ap->saddr);
+	    "%s: adding %saddress %s", ap->iface->name,
+#ifdef IPV6_AF_TEMPORARY
+	    ap->flags & IPV6_AF_TEMPORARY ? "temporary " : "",
+#else
+	    "",
+#endif
+	    ap->saddr);
 	if (ap->prefix_pltime == ND6_INFINITE_LIFETIME &&
 	    ap->prefix_vltime == ND6_INFINITE_LIFETIME)
 		logger(ap->iface->ctx, LOG_DEBUG,
@@ -881,17 +887,22 @@ ipv6_freedrop_addrs(struct ipv6_addrhead
 		{
 			if (drop == 2)
 				TAILQ_REMOVE(addrs, ap, next);
-			/* Find the same address somewhere else */
-			apf = ipv6_findaddr(ap->iface->ctx, &ap->addr, 0);
-			if (apf == NULL ||
-			    (apf->iface != ap->iface))
-				ipv6_deleteaddr(ap);
-			if (!(ap->iface->options->options &
-			    DHCPCD_EXITING) && apf)
-			{
-				if (!timespecisset(&now))
-					clock_gettime(CLOCK_MONOTONIC, &now);
-				ipv6_addaddr(apf, &now);
+			/* Don't drop link-local addresses. */
+			if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
+				/* Find the same address somewhere else */
+				apf = ipv6_findaddr(ap->iface->ctx, &ap->addr,
+				    0);
+				if ((apf == NULL ||
+				    (apf->iface != ap->iface)))
+					ipv6_deleteaddr(ap);
+				if (!(ap->iface->options->options &
+				    DHCPCD_EXITING) && apf)
+				{
+					if (!timespecisset(&now))
+						clock_gettime(CLOCK_MONOTONIC,
+						    &now);
+					ipv6_addaddr(apf, &now);
+				}
 			}
 			if (drop == 2)
 				ipv6_freeaddr(ap);
@@ -1850,6 +1861,7 @@ ipv6_handlert(struct dhcpcd_ctx *ctx, in
 static int
 nc_route(struct rt6 *ort, struct rt6 *nrt)
 {
+	int change;
 
 	/* Don't set default routes if not asked to */
 	if (IN6_IS_ADDR_UNSPECIFIED(&nrt->dest) &&
@@ -1859,6 +1871,7 @@ nc_route(struct rt6 *ort, struct rt6 *nr
 
 	desc_route(ort == NULL ? "adding" : "changing", nrt);
 
+	change = 0;
 	if (ort == NULL) {
 		ort = ipv6_findrt(nrt->iface->ctx, nrt, 0);
 		if (ort &&
@@ -1868,7 +1881,27 @@ nc_route(struct rt6 *ort, struct rt6 *nr
 		    ort->metric == nrt->metric &&
 #endif
 		    IN6_ARE_ADDR_EQUAL(&ort->gate, &nrt->gate))))
+		{
+			if (ort->mtu == nrt->mtu)
+				return 0;
+			change = 1;
+		}
+	}
+
+#ifdef RTF_CLONING
+	/* BSD can set routes to be cloning routes.
+	 * Cloned routes inherit the parent flags.
+	 * As such, we need to delete and re-add the route to flush children
+	 * to correct the flags. */
+	if (change && ort != NULL && ort->flags & RTF_CLONING)
+		change = 0;
+#endif
+
+	if (change) {
+		if (if_route6(RTM_CHANGE, nrt) == 0)
 			return 0;
+		if (errno != ESRCH)
+			logger(nrt->iface->ctx, LOG_ERR, "if_route6 (CHG): %m");
 	}
 
 #ifdef HAVE_ROUTE_METRIC

Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.21 src/external/bsd/dhcpcd/dist/script.c:1.22
--- src/external/bsd/dhcpcd/dist/script.c:1.21	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/script.c	Fri Aug 21 10:39:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.21 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.22 2015/08/21 10:39:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -325,7 +325,7 @@ make_env(const struct interface *ifp, co
 	EMALLOC(6, e);
 	snprintf(env[6], e, "ifflags=%u", ifp->flags);
 	EMALLOC(7, e);
-	snprintf(env[7], e, "ifmtu=%d", if_getmtu(ifp->name));
+	snprintf(env[7], e, "ifmtu=%d", if_getmtu(ifp));
 	l = e = strlen("interface_order=");
 	TAILQ_FOREACH(ifp2, ifp->ctx->ifaces, next) {
 		e += strlen(ifp2->name) + 1;

Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.7 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.8
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf:1.7	Sat May 16 23:31:32 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/20-resolv.conf	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-# $NetBSD: 20-resolv.conf,v 1.7 2015/05/16 23:31:32 roy Exp $
+# $NetBSD: 20-resolv.conf,v 1.8 2015/08/21 10:39:00 roy Exp $
 
 # Generate /etc/resolv.conf
 # Support resolvconf(8) if available
@@ -119,14 +119,6 @@ add_resolv_conf()
 	new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss"
 	new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl"
 
-	# If we don't have any configuration, remove it
-	if [ -z "$new_domain_name_servers" -a \
-		-z "$new_domain_name" -a \
-		-z "$new_domain_search" ]; then
-		remove_resolv_conf
-		return $?
-	fi
-
 	# Derive a new domain from our various hostname options
 	if [ -z "$new_domain_name" ]; then
 		if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then
@@ -138,6 +130,14 @@ add_resolv_conf()
 		fi
 	fi
 
+	# If we don't have any configuration, remove it
+	if [ -z "$new_domain_name_servers" -a \
+		-z "$new_domain_name" -a \
+		-z "$new_domain_search" ]; then
+		remove_resolv_conf
+		return $?
+	fi
+
 	if [ -n "$new_domain_name" ]; then
 		set -- $new_domain_name
 		if valid_domainname "$1"; then

Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.6 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.7
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname:1.6	Fri Nov  7 20:51:03 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/30-hostname	Fri Aug 21 10:39:00 2015
@@ -1,4 +1,4 @@
-# $NetBSD: 30-hostname,v 1.6 2014/11/07 20:51:03 roy Exp $
+# $NetBSD: 30-hostname,v 1.7 2015/08/21 10:39:00 roy Exp $
 
 # Set the hostname from DHCP data if required
 
@@ -148,6 +148,7 @@ set_hostname()
 case "$reason" in
 BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6)
 	new_fqdn="$new_dhcp6_fqdn"
+	old_fqdn="$old_dhcp6_fqdn"
 	;;
 esac
 

Reply via email to