Module Name:    src
Committed By:   roy
Date:           Sun Oct  9 09:18:26 UTC 2016

Modified Files:
        src/external/bsd/dhcpcd/dist: arp.c auth.h common.c common.h config.h
            defs.h dhcp.c dhcp6.c dhcp6.h dhcpcd.c dhcpcd.h if-bsd.c
            if-options.c if.c if.h ipv4.c ipv4.h ipv4ll.c ipv4ll.h ipv6.c
            ipv6.h ipv6nd.c script.c
Removed Files:
        src/external/bsd/dhcpcd/dist: dhcpcd-embedded.c dhcpcd-embedded.h

Log Message:
Sync


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/arp.c \
    src/external/bsd/dhcpcd/dist/ipv6.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/auth.h
cvs rdiff -u -r1.20 -r1.21 src/external/bsd/dhcpcd/dist/common.c \
    src/external/bsd/dhcpcd/dist/ipv6.h
cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/common.h
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/config.h
cvs rdiff -u -r1.30 -r1.31 src/external/bsd/dhcpcd/dist/defs.h
cvs rdiff -u -r1.46 -r1.47 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.25 -r1.26 src/external/bsd/dhcpcd/dist/dhcp6.c \
    src/external/bsd/dhcpcd/dist/ipv4.c
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/dhcpcd/dist/dhcp6.h
cvs rdiff -u -r1.13 -r0 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c
cvs rdiff -u -r1.10 -r0 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h
cvs rdiff -u -r1.36 -r1.37 src/external/bsd/dhcpcd/dist/dhcpcd.c
cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/dhcpcd.h \
    src/external/bsd/dhcpcd/dist/ipv4.h
cvs rdiff -u -r1.33 -r1.34 src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.35 -r1.36 src/external/bsd/dhcpcd/dist/if-options.c
cvs rdiff -u -r1.23 -r1.24 src/external/bsd/dhcpcd/dist/if.c
cvs rdiff -u -r1.18 -r1.19 src/external/bsd/dhcpcd/dist/if.h \
    src/external/bsd/dhcpcd/dist/ipv4ll.c
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/ipv4ll.h
cvs rdiff -u -r1.32 -r1.33 src/external/bsd/dhcpcd/dist/ipv6nd.c
cvs rdiff -u -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/script.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/dhcpcd/dist/arp.c
diff -u src/external/bsd/dhcpcd/dist/arp.c:1.21 src/external/bsd/dhcpcd/dist/arp.c:1.22
--- src/external/bsd/dhcpcd/dist/arp.c:1.21	Fri Jul 29 10:07:57 2016
+++ src/external/bsd/dhcpcd/dist/arp.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: arp.c,v 1.21 2016/07/29 10:07:57 roy Exp $");
+ __RCSID("$NetBSD: arp.c,v 1.22 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -448,6 +448,8 @@ arp_handleifa(int cmd, struct ipv4_addr 
 	struct iarp_state *state;
 	struct arp_state *astate, *asn;
 
+	/* If the address is deleted, the ARP state should be freed by the
+	 * state owner, such as DHCP or IPv4LL. */
 	if (cmd != RTM_NEWADDR || (state = ARP_STATE(addr->iface)) == NULL)
 		return;
 
Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.21 src/external/bsd/dhcpcd/dist/ipv6.c:1.22
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.21	Mon Aug 15 11:04:53 2016
+++ src/external/bsd/dhcpcd/dist/ipv6.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.21 2016/08/15 11:04:53 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.22 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -104,20 +104,22 @@
 
 #if defined(HAVE_IN6_ADDR_GEN_MODE_NONE) || defined(ND6_IFF_AUTO_LINKLOCAL) || \
     defined(IFF_NOLINKLOCAL)
-/* If we're using a private SLAAC address on wireless,
- * don't add it until we have associated as we randomise
- * it based on the SSID. */
-#define CAN_ADD_LLADDR(ifp) \
-	(!((ifp)->options->options & DHCPCD_SLAACPRIVATE) || \
-	    (ifp)->carrier != LINK_DOWN)
-#elif __NetBSD__
-/* Earlier versions of NetBSD don't add duplicate LLADDR's if the interface
- * is brought up and one already exists. */
-#define CAN_ADD_LLADDR(ifp) (1)
+/* Only add the LL address if we have a carrier, so DaD works. */
+#define	CAN_ADD_LLADDR(ifp) \
+    (!((ifp)->options->options & DHCPCD_LINK) || (ifp)->carrier != LINK_DOWN)
+#ifdef __sun
+/* Although we can add our own LL address, we cannot drop it
+ * without unplumbing the if which is a lot of code.
+ * So just keep it for the time being. */
+#define	CAN_DROP_LLADDR(ifp)	(0)
+#else
+#define	CAN_DROP_LLADDR(ifp)	(1)
+#endif
 #else
 /* We have no control over the OS adding the LLADDR, so just let it do it
  * as we cannot force our own view on it. */
-#define CAN_ADD_LLADDR(ifp) (0)
+#define	CAN_ADD_LLADDR(ifp)	(0)
+#define	CAN_DROP_LLADDR(ifp)	(0)
 #endif
 
 #ifdef IPV6_MANAGETEMPADDR
@@ -163,13 +165,11 @@ ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx)
 	ctx->sndhdr.msg_controllen = sizeof(ctx->sndbuf);
 	ctx->rcvhdr.msg_name = &ctx->from;
 	ctx->rcvhdr.msg_namelen = sizeof(ctx->from);
-	ctx->rcvhdr.msg_iov = ctx->rcviov;
+	ctx->rcvhdr.msg_iov = dhcpcd_ctx->iov;
 	ctx->rcvhdr.msg_iovlen = 1;
-	ctx->rcvhdr.msg_control = ctx->rcvbuf;
+	ctx->rcvhdr.msg_control = ctx->ctlbuf;
 	// controllen is set at recieve
 	//ctx->rcvhdr.msg_controllen = sizeof(ctx->rcvbuf);
-	ctx->rcviov[0].iov_base = ctx->ansbuf;
-	ctx->rcviov[0].iov_len = sizeof(ctx->ansbuf);
 
 	ctx->nd_fd = -1;
 	ctx->dhcp_fd = -1;
@@ -344,6 +344,11 @@ ipv6_makestableprivate(struct in6_addr *
 	uint32_t dad;
 	int r;
 
+	if (ifp->ctx->secret_len == 0) {
+		if (ipv6_readsecret(ifp->ctx) == -1)
+			return -1;
+	}
+
 	dad = (uint32_t)*dad_counter;
 
 	/* For our implementation, we shall set the hardware address
@@ -372,10 +377,6 @@ ipv6_makeaddr(struct in6_addr *addr, str
 	}
 
 	if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
-		if (ifp->ctx->secret_len == 0) {
-			if (ipv6_readsecret(ifp->ctx) == -1)
-				return -1;
-		}
 		dad = 0;
 		if (ipv6_makestableprivate(addr,
 		    prefix, prefix_len, ifp, &dad) == -1)
@@ -571,20 +572,25 @@ ipv6_checkaddrflags(void *arg)
 {
 	struct ipv6_addr *ia;
 	int flags;
+	const char *alias;
 
 	ia = arg;
-	if ((flags = if_addrflags6(ia)) == -1) {
+#ifdef ALIAS_ADDR
+	alias = ia->alias;
+#else
+	alias = NULL;
+#endif
+	if ((flags = if_addrflags6(ia->iface, &ia->addr, alias)) == -1) {
 		logger(ia->iface->ctx, LOG_ERR,
 		    "%s: if_addrflags6: %m", ia->iface->name);
 		return;
 	}
 
-	ia->addr_flags = flags;
 	if (!(ia->addr_flags & IN6_IFF_TENTATIVE)) {
 		/* Simulate the kernel announcing the new address. */
 		ipv6_handleifa(ia->iface->ctx, RTM_NEWADDR,
 		    ia->iface->ctx->ifaces, ia->iface->name,
-		    &ia->addr, ia->prefix_len);
+		    &ia->addr, ia->prefix_len, flags);
 	} else {
 		/* Still tentative? Check again in a bit. */
 		struct timespec tv;
@@ -605,8 +611,9 @@ ipv6_deleteaddr(struct ipv6_addr *ia)
 	logger(ia->iface->ctx, LOG_INFO, "%s: deleting address %s",
 	    ia->iface->name, ia->saddr);
 	if (if_address6(RTM_DELADDR, ia) == -1 &&
-	    errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV)
-		logger(ia->iface->ctx, LOG_ERR, "if_address6: :%m");
+	    errno != EADDRNOTAVAIL && errno != ESRCH &&
+	    errno != ENXIO && errno != ENODEV)
+		logger(ia->iface->ctx, LOG_ERR, "if_address6: %m");
 
 	/* NOREJECT is set if we delegated exactly the prefix to another
 	 * address.
@@ -1007,8 +1014,8 @@ ipv6_freedrop_addrs(struct ipv6_addrhead
 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
 		{
 			/* Don't drop link-local addresses. */
-			if (!(IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
-			    CAN_ADD_LLADDR(ap->iface)))
+			if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr) ||
+			    CAN_DROP_LLADDR(ap->iface))
 			{
 				if (drop == 2)
 					TAILQ_REMOVE(addrs, ap, next);
@@ -1063,13 +1070,12 @@ ipv6_getstate(struct interface *ifp)
 void
 ipv6_handleifa(struct dhcpcd_ctx *ctx,
     int cmd, struct if_head *ifs, const char *ifname,
-    const struct in6_addr *addr, uint8_t prefix_len)
+    const struct in6_addr *addr, uint8_t prefix_len, int addrflags)
 {
 	struct interface *ifp;
 	struct ipv6_state *state;
 	struct ipv6_addr *ia;
 	struct ll_callback *cb;
-	int flags;
 
 #if 0
 	char dbuf[INET6_ADDRSTRLEN];
@@ -1151,14 +1157,7 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 			ia->acquired = ia->created;
 			TAILQ_INSERT_TAIL(&state->addrs, ia, next);
 		}
-		flags = if_addrflags6(ia);
-		if (flags == -1) {
-			logger(ia->iface->ctx, LOG_ERR,
-			    "%s: %s: if_addrflags6: %m",
-			    ia->iface->name, ia->saddr);
-			return;
-		}
-		ia->addr_flags = flags;
+		ia->addr_flags = addrflags;
 #ifdef IPV6_MANAGETEMPADDR
 		if (ia->addr_flags & IN6_IFF_TEMPORARY)
 			ia->flags |= IPV6_AF_TEMPORARY;
@@ -1439,14 +1438,28 @@ nextslaacprivate:
 static int
 ipv6_tryaddlinklocal(struct interface *ifp)
 {
+	struct ipv6_addr *ia;
 
 	/* We can't assign a link-locak address to this,
 	 * the ppp process has to. */
 	if (ifp->flags & IFF_POINTOPOINT)
 		return 0;
 
-	if (ipv6_iffindaddr(ifp, NULL, IN6_IFF_DUPLICATED) != NULL ||
-	    !CAN_ADD_LLADDR(ifp))
+	ia = ipv6_iffindaddr(ifp, NULL, IN6_IFF_DUPLICATED);
+	if (ia != NULL) {
+#ifdef IPV6_POLLADDRFLAG
+		if (ia->addr_flags & IN6_IFF_TENTATIVE) {
+			struct timespec tv;
+
+			ms_to_ts(&tv, RETRANS_TIMER / 2);
+			eloop_timeout_add_tv(
+			    ia->iface->ctx->eloop,
+			    &tv, ipv6_checkaddrflags, ia);
+		}
+#endif
+		return 0;
+	}
+	if (!CAN_ADD_LLADDR(ifp))
 		return 0;
 
 	return ipv6_addlinklocal(ifp);
@@ -1599,6 +1612,27 @@ ipv6_startstatic(struct interface *ifp)
 int
 ipv6_start(struct interface *ifp)
 {
+#ifdef IPV6_POLLADDRFLAG
+	struct ipv6_state *state;
+
+	/* We need to update the address flags. */
+	if ((state = IPV6_STATE(ifp)) != NULL) {
+		struct ipv6_addr *ia;
+		const char *alias;
+		int flags;
+
+		TAILQ_FOREACH(ia, &state->addrs, next) {
+#ifdef ALIAS_ADDR
+			alias = ia->alias;
+#else
+			alias = NULL;
+#endif
+			flags = if_addrflags6(ia->iface, &ia->addr, alias);
+			if (flags != -1)
+				ia->addr_flags = flags;
+		}
+	}
+#endif
 
 	if (ipv6_tryaddlinklocal(ifp) == -1)
 		return -1;
@@ -1612,8 +1646,6 @@ ipv6_start(struct interface *ifp)
 
 	/* Load existing routes */
 	if_initrt6(ifp->ctx);
-	if (!IN6_IS_ADDR_UNSPECIFIED(&ifp->options->req_addr6))
-		ipv6_buildroutes(ifp->ctx);
 	return 0;
 }
 
@@ -1629,6 +1661,12 @@ ipv6_freedrop(struct interface *ifp, int
 	if ((state = IPV6_STATE(ifp)) == NULL)
 		return;
 
+	/* If we got here, we can get rid of any LL callbacks. */
+	while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
+		TAILQ_REMOVE(&state->ll_callbacks, cb, next);
+		free(cb);
+	}
+
 	ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL);
 	if (drop) {
 		if (ifp->ctx->ipv6 != NULL) {
@@ -1638,10 +1676,6 @@ ipv6_freedrop(struct interface *ifp, int
 	} else {
 		/* Because we need to cache the addresses we don't control,
 		 * we only free the state on when NOT dropping addresses. */
-		while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
-			TAILQ_REMOVE(&state->ll_callbacks, cb, next);
-			free(cb);
-		}
 		free(state);
 		ifp->if_data[IF_DATA_IPV6] = NULL;
 		eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
@@ -1786,8 +1820,6 @@ ipv6_gentempifid(struct interface *ifp)
 	    state->randomseed1, sizeof(state->randomseed1));
 
 again:
-	/* RFC4941 Section 3.2.1.1
-	 * Take the left-most 64bits and set bit 6 to zero */
 	MD5Init(&md5);
 	MD5Update(&md5, seed, sizeof(seed));
 	MD5Final(digest, &md5);
@@ -2257,8 +2289,22 @@ nc_route(struct rt6 *ort, struct rt6 *nr
 
 	/* No route metrics, we need to delete the old route before
 	 * adding the new one. */
+#ifdef ROUTE_PER_GATEWAY
+	errno = 0;
+#endif
 	if (ort && if_route6(RTM_DELETE, ort) == -1 && errno != ESRCH)
-		logger(nrt->iface->ctx, LOG_ERR, "if_route6: %m");
+		logger(nrt->iface->ctx, LOG_ERR, "if_route6 (DEL): %m");
+#ifdef ROUTE_PER_GATEWAY
+	/* The OS allows many routes to the same dest with different gateways.
+	 * dhcpcd does not support this yet, so for the time being just keep on
+	 * deleting the route until there is an error. */
+	if (ort && errno == 0) {
+		for (;;) {
+			if (if_route6(RTM_DELETE, ort) == -1)
+				break;
+		}
+	}
+#endif
 	if (if_route6(RTM_ADD, nrt) != -1)
 		return 0;
 #ifdef HAVE_ROUTE_METRIC

Index: src/external/bsd/dhcpcd/dist/auth.h
diff -u src/external/bsd/dhcpcd/dist/auth.h:1.9 src/external/bsd/dhcpcd/dist/auth.h:1.10
--- src/external/bsd/dhcpcd/dist/auth.h:1.9	Sat May 16 23:31:32 2015
+++ src/external/bsd/dhcpcd/dist/auth.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: auth.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */
+/* $NetBSD: auth.h,v 1.10 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -65,12 +65,14 @@ TAILQ_HEAD(token_head, token);
 
 struct auth {
 	int options;
+#ifdef AUTH
 	uint8_t protocol;
 	uint8_t algorithm;
 	uint8_t rdm;
 	uint64_t last_replay;
 	uint8_t last_replay_set;
 	struct token_head tokens;
+#endif
 };
 
 struct authstate {

Index: src/external/bsd/dhcpcd/dist/common.c
diff -u src/external/bsd/dhcpcd/dist/common.c:1.20 src/external/bsd/dhcpcd/dist/common.c:1.21
--- src/external/bsd/dhcpcd/dist/common.c:1.20	Mon May  9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/common.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: common.c,v 1.20 2016/05/09 10:15:59 roy Exp $");
+ __RCSID("$NetBSD: common.c,v 1.21 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,7 +30,11 @@
 
 #include <sys/param.h>
 #include <sys/time.h>
+#ifdef __sun
+#include <sys/sysmacros.h>
+#endif
 
+#include <assert.h>
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
@@ -56,6 +60,9 @@
 #  define _PATH_DEVNULL "/dev/null"
 #endif
 
+/* Most route(4) messages are less than 256 bytes. */
+#define IOVEC_BUFSIZ	256
+
 #if USE_LOGFILE
 void
 logger_open(struct dhcpcd_ctx *ctx)
@@ -377,3 +384,51 @@ read_hwaddr_aton(uint8_t **data, const c
 	fclose(fp);
 	return len;
 }
+
+ssize_t
+recvmsg_realloc(int fd, struct msghdr *msg, int flags)
+{
+	struct iovec *iov;
+	ssize_t slen;
+	size_t len;
+	void *n;
+
+	assert(msg != NULL);
+	assert(msg->msg_iov != NULL && msg->msg_iovlen > 0);
+	assert((flags & (MSG_PEEK | MSG_TRUNC)) == 0);
+
+	/* Assume we are reallocing the last iovec. */
+	iov = &msg->msg_iov[msg->msg_iovlen - 1];
+
+	for (;;) {
+		/* Passing MSG_TRUNC should return the actual size needed. */
+		slen = recvmsg(fd, msg, flags | MSG_PEEK | MSG_TRUNC);
+		if (slen == -1)
+			return -1;
+		if (!(msg->msg_flags & MSG_TRUNC))
+			break;
+
+		len = (size_t)slen;
+
+		/* Some kernels return the size of the receive buffer
+		 * on truncation, not the actual size needed.
+		 * So grow the buffer and try again. */
+		if (iov->iov_len == len)
+			len++;
+		else if (iov->iov_len > len)
+			break;
+		len = roundup(len, IOVEC_BUFSIZ);
+		if ((n = realloc(iov->iov_base, len)) == NULL)
+			return -1;
+		iov->iov_base = n;
+		iov->iov_len = len;
+	}
+
+	slen = recvmsg(fd, msg, flags);
+	if (slen != -1 && msg->msg_flags & MSG_TRUNC) {
+		/* This should not be possible ... */
+		errno = ENOBUFS;
+		return -1;
+	}
+	return slen;
+}
Index: src/external/bsd/dhcpcd/dist/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.20 src/external/bsd/dhcpcd/dist/ipv6.h:1.21
--- src/external/bsd/dhcpcd/dist/ipv6.h:1.20	Fri Jul 29 10:07:58 2016
+++ src/external/bsd/dhcpcd/dist/ipv6.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.20 2016/07/29 10:07:58 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.21 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -262,17 +262,14 @@ struct ipv6_state {
 #define IP6BUFLEN	(CMSG_SPACE(sizeof(struct in6_pktinfo)) + \
 			CMSG_SPACE(sizeof(int)))
 
-
 #ifdef INET6
 struct ipv6_ctx {
+	unsigned char ctlbuf[IP6BUFLEN];
 	struct sockaddr_in6 from;
 	struct msghdr sndhdr;
-	struct iovec sndiov[2];
+	struct iovec sndiov[1];
 	unsigned char sndbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
 	struct msghdr rcvhdr;
-	struct iovec rcviov[2];
-	unsigned char rcvbuf[IP6BUFLEN];
-	unsigned char ansbuf[1500];
 	char ntopbuf[INET6_ADDRSTRLEN];
 	const char *sfrom;
 
@@ -302,7 +299,7 @@ ssize_t ipv6_addaddrs(struct ipv6_addrhe
 void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
     const struct interface *);
 void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *,
-    const char *, const struct in6_addr *, uint8_t);
+    const char *, const struct in6_addr *, uint8_t, int);
 int ipv6_handleifa_addrs(int, struct ipv6_addrhead *, const struct ipv6_addr *);
 struct ipv6_addr *ipv6_iffindaddr(struct interface *,
     const struct in6_addr *, int);

Index: src/external/bsd/dhcpcd/dist/common.h
diff -u src/external/bsd/dhcpcd/dist/common.h:1.14 src/external/bsd/dhcpcd/dist/common.h:1.15
--- src/external/bsd/dhcpcd/dist/common.h:1.14	Mon May  9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/common.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: common.h,v 1.14 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: common.h,v 1.15 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -167,6 +167,10 @@ int get_monotonic(struct timespec *);
  * However, this results in a ugly output on the command line
  * and relies on syslogd(8) starting before dhcpcd which is not
  * always the case. */
+#ifdef SMALL
+# undef USE_LOGFILE
+# define USE_LOGFILE 0
+#endif
 #ifndef USE_LOGFILE
 # define USE_LOGFILE 1
 #endif
@@ -198,4 +202,6 @@ ssize_t addvard(struct dhcpcd_ctx *,
 char *hwaddr_ntoa(const uint8_t *, size_t, char *, size_t);
 size_t hwaddr_aton(uint8_t *, const char *);
 size_t read_hwaddr_aton(uint8_t **, const char *);
+
+ssize_t recvmsg_realloc(int, struct msghdr *, int);
 #endif

Index: src/external/bsd/dhcpcd/dist/config.h
diff -u src/external/bsd/dhcpcd/dist/config.h:1.11 src/external/bsd/dhcpcd/dist/config.h:1.12
--- src/external/bsd/dhcpcd/dist/config.h:1.11	Mon May  9 10:15:59 2016
+++ src/external/bsd/dhcpcd/dist/config.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: config.h,v 1.11 2016/05/09 10:15:59 roy Exp $ */
+/* $NetBSD: config.h,v 1.12 2016/10/09 09:18:26 roy Exp $ */
 
 /* netbsd */
 #define SYSCONFDIR	"/etc"
@@ -7,6 +7,9 @@
 #define LIBEXECDIR	"/libexec"
 #define DBDIR		"/var/db"
 #define RUNDIR		"/var/run"
+#define HAVE_IFAM_PID
+#define HAVE_IFAM_ADDRFLAGS
+#define HAVE_IFADDRS_ADDRFLAGS
 #define HAVE_UTIL_H
 #define HAVE_SYS_QUEUE_H
 #define HAVE_SPAWN_H

Index: src/external/bsd/dhcpcd/dist/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.30 src/external/bsd/dhcpcd/dist/defs.h:1.31
--- src/external/bsd/dhcpcd/dist/defs.h:1.30	Mon Aug 15 11:04:53 2016
+++ src/external/bsd/dhcpcd/dist/defs.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.30 2016/08/15 11:04:53 roy Exp $ */
+/* $NetBSD: defs.h,v 1.31 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
 #define CONFIG_H
 
 #define PACKAGE			"dhcpcd"
-#define VERSION			"6.11.3"
+#define VERSION			"6.11.4"
 
 #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.46 src/external/bsd/dhcpcd/dist/dhcp.c:1.47
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.46	Sun Sep 18 15:37:23 2016
+++ src/external/bsd/dhcpcd/dist/dhcp.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.46 2016/09/18 15:37:23 christos Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.47 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -742,7 +742,7 @@ make_message(struct bootp **bootpm, cons
 	const char *hostname;
 	const struct vivco *vivco;
 	int mtu;
-#ifndef NO_AUTH
+#ifdef AUTH
 	uint8_t *auth, auth_len;
 #endif
 
@@ -977,6 +977,7 @@ make_message(struct bootp **bootpm, cons
 			p += ifo->vendor[0] + 1;
 		}
 
+#ifdef AUTH
 		if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
 		    DHCPCD_AUTH_SENDREQUIRE)
 		{
@@ -986,6 +987,7 @@ make_message(struct bootp **bootpm, cons
 			*p++ = 1;
 			*p++ = AUTH_ALG_HMAC_MD5;
 		}
+#endif
 
 		if (ifo->vivco_len) {
 			AREA_CHECK(sizeof(ul));
@@ -1059,11 +1061,9 @@ make_message(struct bootp **bootpm, cons
 		*n_params = (uint8_t)(p - n_params - 1);
 	}
 
-#ifndef NO_AUTH
-	/* silence GCC */
+#ifdef AUTH
+	auth = NULL;	/* appease GCC */
 	auth_len = 0;
-	auth = NULL;
-
 	if (ifo->auth.options & DHCPCD_AUTH_SEND) {
 		ssize_t alen = dhcp_auth_encode(&ifo->auth,
 		    state->auth.token,
@@ -1085,6 +1085,7 @@ make_message(struct bootp **bootpm, cons
 		}
 	}
 #endif
+
 	*p++ = DHO_END;
 	len = (size_t)(p - (uint8_t *)bootp);
 
@@ -1097,7 +1098,7 @@ make_message(struct bootp **bootpm, cons
 		*p++ = DHO_PAD;
 		len++;
 	}
-#ifndef NO_AUTH
+#ifdef AUTH
 	if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0)
 		dhcp_auth_encode(&ifo->auth, state->auth.token,
 		    (uint8_t *)bootp, len, 4, type, auth, auth_len);
@@ -1138,9 +1139,9 @@ read_lease(struct interface *ifp, struct
 	uint8_t *lease;
 	size_t bytes;
 	uint8_t type;
-#ifndef NO_AUTH
-	size_t auth_len;
+#ifdef AUTH
 	const uint8_t *auth;
+	size_t auth_len;
 #endif
 
 	/* Safety */
@@ -1194,7 +1195,7 @@ read_lease(struct interface *ifp, struct
 	    DHO_MESSAGETYPE) == -1)
 		type = 0;
 
-#ifndef NO_AUTH
+#ifdef AUTH
 	/* Authenticate the message */
 	auth = get_option(ifp->ctx, (struct bootp *)lease, bytes,
 	    DHO_AUTHENTICATION, &auth_len);
@@ -1223,6 +1224,7 @@ read_lease(struct interface *ifp, struct
 		return 0;
 	}
 #endif
+
 out:
 	*bootp = (struct bootp *)lease;
 	return bytes;
@@ -1845,9 +1847,11 @@ dhcp_discover(void *arg)
 	if (ifo->fallback)
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    ifo->reboot, dhcp_fallback, ifp);
+#ifdef IPV4LL
 	else if (ifo->options & DHCPCD_IPV4LL)
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    ifo->reboot, ipv4ll_start, ifp);
+#endif
 	if (ifo->options & DHCPCD_REQUEST)
 		logger(ifp->ctx, LOG_INFO,
 		    "%s: soliciting a DHCP lease (requesting %s)",
@@ -2510,10 +2514,12 @@ dhcp_reboot(struct interface *ifp)
 	state->lease.server.s_addr = 0;
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
+#ifdef IPV4LL
 	/* Need to add this before dhcp_expire and friends. */
 	if (!ifo->fallback && ifo->options & DHCPCD_IPV4LL)
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    ifo->reboot, ipv4ll_start, ifp);
+#endif
 
 	if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo)
 		eloop_timeout_add_sec(ifp->ctx->eloop,
@@ -2571,7 +2577,7 @@ dhcp_drop(struct interface *ifp, const c
 	}
 
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
-#ifndef NO_AUTH
+#ifdef AUTH
 	dhcp_auth_reset(&state->auth);
 #endif
 	dhcp_close(ifp);
@@ -2698,13 +2704,13 @@ dhcp_handledhcp(struct interface *ifp, s
 	unsigned int i;
 	char *msg;
 	bool bootp_copied;
-#ifdef IN_IFF_DUPLICATED
-	struct ipv4_addr *ia;
-#endif
-#ifndef NO_AUTH
 	const uint8_t *auth;
+#ifdef AUTH
 	size_t auth_len;
 #endif
+#ifdef IN_IFF_DUPLICATED
+	struct ipv4_addr *ia;
+#endif
 
 #define LOGDHCP0(l, m) \
 	log_dhcp((l), (m), ifp, bootp, bootp_len, from, 0)
@@ -2741,8 +2747,8 @@ dhcp_handledhcp(struct interface *ifp, s
 		return;
 	}
 
+#ifdef AUTH
 	/* Authenticate the message */
-#ifndef NO_AUTH
 	auth = get_option(ifp->ctx, bootp, bootp_len,
 	    DHO_AUTHENTICATION, &auth_len);
 	if (auth) {
@@ -2769,7 +2775,10 @@ dhcp_handledhcp(struct interface *ifp, s
 		}
 		LOGDHCP0(LOG_WARNING, "no authentication");
 	}
+#else
+	auth = NULL;
 #endif
+
 	/* RFC 3203 */
 	if (type == DHCP_FORCERENEW) {
 		if (from->s_addr == INADDR_ANY ||
@@ -2778,13 +2787,11 @@ dhcp_handledhcp(struct interface *ifp, s
 			LOGDHCP(LOG_ERR, "discarding Force Renew");
 			return;
 		}
-#ifndef NO_AUTH
 		if (auth == NULL) {
 			LOGDHCP(LOG_ERR, "unauthenticated Force Renew");
 			if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
 				return;
 		}
-#endif
 		if (state->state != DHS_BOUND && state->state != DHS_INFORM) {
 			LOGDHCP(LOG_DEBUG, "not bound, ignoring Force Renew");
 			return;
@@ -2906,6 +2913,7 @@ dhcp_handledhcp(struct interface *ifp, s
 			    "%s: message: %s", ifp->name, msg);
 			free(msg);
 		}
+#ifdef IPV4LL
 		if (state->state == DHS_DISCOVER &&
 		    get_option_uint8(ifp->ctx, &tmp, bootp, bootp_len,
 		    DHO_AUTOCONFIGURE) == 0)
@@ -2930,6 +2938,7 @@ dhcp_handledhcp(struct interface *ifp, s
 			eloop_timeout_add_sec(ifp->ctx->eloop,
 			    DHCP_MAX, dhcp_discover, ifp);
 		}
+#endif
 		return;
 	}
 
@@ -3580,11 +3589,13 @@ dhcp_start1(void *arg)
 		}
 	}
 
+#ifdef IPV4LL
 	if (!(ifo->options & DHCPCD_DHCP)) {
 		if (ifo->options & DHCPCD_IPV4LL)
 			ipv4ll_start(ifp);
 		return;
 	}
+#endif
 
 	if (state->offer == NULL || !IS_DHCP(state->offer))
 		dhcp_discover(ifp);
@@ -3671,9 +3682,12 @@ dhcp_handleifa(int cmd, struct ipv4_addr
 		return;
 
 	if (cmd == RTM_DELADDR) {
-		if (IPV4_BRD_EQ(state->addr, ia)) {
+		if (state->addr == ia) {
 			logger(ifp->ctx, LOG_INFO,
 			    "%s: deleted IP address %s", ifp->name, ia->saddr);
+			state->addr = NULL;
+			/* Don't clear the added state as we need
+			 * to drop the lease. */
 			dhcp_drop(ifp, "EXPIRE");
 		}
 		return;

Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.25 src/external/bsd/dhcpcd/dist/dhcp6.c:1.26
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.25	Sun Sep 18 15:37:23 2016
+++ src/external/bsd/dhcpcd/dist/dhcp6.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.25 2016/09/18 15:37:23 christos Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.26 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -75,6 +75,7 @@
 #define IPV6_RECVPKTINFO IPV6_PKTINFO
 #endif
 
+#ifdef DHCP6
 struct dhcp6_op {
 	uint16_t type;
 	const char *name;
@@ -360,6 +361,7 @@ dhcp6_newxid(const struct interface *ifp
 	m->xid[2] = xid & 0xff;
 }
 
+#ifndef SMALL
 static const struct if_sla *
 dhcp6_findselfsla(struct interface *ifp, const uint8_t *iaid)
 {
@@ -492,31 +494,36 @@ dhcp6_delegateaddr(struct in6_addr *addr
 
 	return sla->prefix_len;
 }
+#endif
 
 static int
 dhcp6_makemessage(struct interface *ifp)
 {
 	struct dhcp6_state *state;
 	struct dhcp6_message *m;
-	struct dhcp6_option *o, *so, *eo;
+	struct dhcp6_option *o, *so;
 	const struct dhcp6_option *si, *unicast;
 	size_t l, n, len, ml;
-	uint8_t u8, type;
+	uint8_t type;
 	uint16_t u16, n_options;
 	struct if_options *ifo;
 	const struct dhcp_opt *opt, *opt2;
 	uint8_t IA, *p;
-	const uint8_t *pp;
 	uint32_t u32;
 	const struct ipv6_addr *ap;
 	char hbuf[HOSTNAME_MAX_LEN + 1];
 	const char *hostname;
 	int fqdn;
 	struct dhcp6_ia_addr *iap;
-	struct dhcp6_pd_addr *pdp;
-#ifndef NO_AUTH
+#ifdef AUTH
 	uint16_t auth_len;
 #endif
+#ifndef SMALL
+	struct dhcp6_option *eo;
+	struct dhcp6_pd_addr *pdp;
+	uint8_t u8;
+	const uint8_t *pp;
+#endif
 
 	state = D6_STATE(ifp);
 	if (state->send) {
@@ -564,6 +571,7 @@ dhcp6_makemessage(struct interface *ifp)
 				len += sizeof(u16);
 			}
 		}
+#ifndef SMALL
 		for (l = 0, opt = ifo->dhcp6_override;
 		    l < ifo->dhcp6_override_len;
 		    l++, opt++)
@@ -580,6 +588,7 @@ dhcp6_makemessage(struct interface *ifp)
 			n_options++;
 			len += sizeof(u16);
 		}
+#endif
 		if (len)
 			len += sizeof(*o);
 
@@ -633,6 +642,7 @@ dhcp6_makemessage(struct interface *ifp)
 			    !(ap->flags & IPV6_AF_REQUEST))
 				continue;
 			if (ap->ia_type == D6_OPTION_IA_PD) {
+#ifndef SMALL
 				len += sizeof(*o) + sizeof(u8) +
 				    sizeof(u32) + sizeof(u32) +
 				    sizeof(ap->prefix);
@@ -640,6 +650,7 @@ dhcp6_makemessage(struct interface *ifp)
 					len += sizeof(*o) + 1 +
 					    (uint8_t)((ap->prefix_exclude_len -
 					    ap->prefix_len - 1) / NBBY) + 1;
+#endif
 			} else
 				len += sizeof(*o) + sizeof(ap->addr) +
 				    sizeof(u32) + sizeof(u32);
@@ -695,7 +706,7 @@ dhcp6_makemessage(struct interface *ifp)
 		return -1;
 	}
 
-#ifndef NO_AUTH
+#ifdef AUTH
 	auth_len = 0;
 	if (ifo->auth.options & DHCPCD_AUTH_SEND) {
 		ssize_t alen = dhcp_auth_encode(&ifo->auth,
@@ -776,6 +787,7 @@ dhcp6_makemessage(struct interface *ifp)
 				continue;
 			so = D6_NEXT_OPTION(o);
 			if (ap->ia_type == D6_OPTION_IA_PD) {
+#ifndef SMALL
 				so->code = htons(D6_OPTION_IAPREFIX);
 				so->len = htons(sizeof(ap->prefix) +
 				    sizeof(u32) + sizeof(u32) + sizeof(u8));
@@ -814,6 +826,7 @@ dhcp6_makemessage(struct interface *ifp)
 				u16 = (uint16_t)(ntohs(o->len) + sizeof(*so)
 				    + ntohs(so->len));
 				o->len = htons(u16);
+#endif
 			} else {
 				so->code = htons(D6_OPTION_IA_ADDR);
 				so->len = sizeof(ap->addr) +
@@ -870,6 +883,7 @@ dhcp6_makemessage(struct interface *ifp)
 			    l < ifp->ctx->dhcp6_opts_len;
 			    l++, opt++)
 			{
+#ifndef SMALL
 				for (n = 0, opt2 = ifo->dhcp6_override;
 				    n < ifo->dhcp6_override_len;
 				    n++, opt2++)
@@ -879,6 +893,7 @@ dhcp6_makemessage(struct interface *ifp)
 				}
 				if (n < ifo->dhcp6_override_len)
 				    continue;
+#endif
 				if (!(opt->type & OT_NOREQ) &&
 				    (opt->type & OT_REQUEST ||
 				    has_option_mask(ifo->requestmask6,
@@ -890,6 +905,7 @@ dhcp6_makemessage(struct interface *ifp)
 					o->len = (uint16_t)(o->len+sizeof(u16));
 				}
 			}
+#ifndef SMALL
 			for (l = 0, opt = ifo->dhcp6_override;
 			    l < ifo->dhcp6_override_len;
 			    l++, opt++)
@@ -910,12 +926,13 @@ dhcp6_makemessage(struct interface *ifp)
 				memcpy(p, &u16, sizeof(u16));
 				o->len = (uint16_t)(o->len + sizeof(u16));
 			}
+#endif
 			o->len = htons(o->len);
 		}
 	}
 
+#ifdef AUTH
 	/* This has to be the last option */
-#ifndef NO_AUTH
 	if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0) {
 		o = D6_NEXT_OPTION(o);
 		o->code = htons(D6_OPTION_AUTH);
@@ -952,6 +969,7 @@ dhcp6_freedrop_addrs(struct interface *i
 	}
 }
 
+#ifndef SMALL
 static void dhcp6_delete_delegates(struct interface *ifp)
 {
 	struct interface *ifp0;
@@ -963,8 +981,9 @@ static void dhcp6_delete_delegates(struc
 		}
 	}
 }
+#endif
 
-#ifndef NO_AUTH
+#ifdef AUTH
 static ssize_t
 dhcp6_update_auth(struct interface *ifp, struct dhcp6_message *m, size_t len)
 {
@@ -1124,7 +1143,7 @@ logsend:
 
 	/* Update the elapsed time */
 	dhcp6_updateelapsed(ifp, state->send, state->send_len);
-#ifndef NO_AUTH
+#ifdef AUTH
 	if (ifp->options->auth.options & DHCPCD_AUTH_SEND &&
 	    dhcp6_update_auth(ifp, state->send, state->send_len) == -1)
 	{
@@ -1385,7 +1404,9 @@ dhcp6_startdiscover(void *arg)
 	struct dhcp6_state *state;
 
 	ifp = arg;
+#ifndef SMALL
 	dhcp6_delete_delegates(ifp);
+#endif
 	logger(ifp->ctx, LOG_INFO, "%s: soliciting a DHCPv6 lease", ifp->name);
 	state = D6_STATE(ifp);
 	state->state = DH6S_DISCOVER;
@@ -1440,6 +1461,9 @@ dhcp6_failrequest(void *arg)
 	dhcp6_startdiscover(ifp);
 }
 
+#ifdef SMALL
+#define dhcp6_hasprefixdelegation(a)	(0)
+#else
 static void
 dhcp6_failrebind(void *arg)
 {
@@ -1455,7 +1479,6 @@ dhcp6_failrebind(void *arg)
 	dhcp6_startdiscover(ifp);
 }
 
-
 static int
 dhcp6_hasprefixdelegation(struct interface *ifp)
 {
@@ -1473,13 +1496,16 @@ dhcp6_hasprefixdelegation(struct interfa
 	}
 	return t == D6_OPTION_IA_PD ? 1 : 0;
 }
+#endif
 
 static void
 dhcp6_startrebind(void *arg)
 {
 	struct interface *ifp;
 	struct dhcp6_state *state;
+#ifndef SMALL
 	int pd;
+#endif
 
 	ifp = arg;
 	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrenew, ifp);
@@ -1494,13 +1520,16 @@ dhcp6_startrebind(void *arg)
 	state->RTC = 0;
 	state->MRC = 0;
 
+#ifndef SMALL
 	/* RFC 3633 section 12.1 */
 	pd = dhcp6_hasprefixdelegation(ifp);
 	if (pd) {
 		state->IMD = CNF_MAX_DELAY;
 		state->IRT = CNF_TIMEOUT;
 		state->MRT = CNF_MAX_RT;
-	} else {
+	} else
+#endif
+	{
 		state->IRT = REB_TIMEOUT;
 		state->MRT = REB_MAX_RT;
 	}
@@ -1511,10 +1540,12 @@ dhcp6_startrebind(void *arg)
 	else
 		dhcp6_sendrebind(ifp);
 
+#ifndef SMALL
 	/* RFC 3633 section 12.1 */
 	if (pd)
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    CNF_MAX_RD, dhcp6_failrebind, ifp);
+#endif
 }
 
 
@@ -1601,7 +1632,9 @@ dhcp6_startexpire(void *arg)
 
 	logger(ifp->ctx, LOG_ERR, "%s: DHCPv6 lease expired", ifp->name);
 	dhcp6_freedrop_addrs(ifp, 1, NULL);
+#ifndef SMALL
 	dhcp6_delete_delegates(ifp);
+#endif
 	script_runreason(ifp, "EXPIRE6");
 	if (ipv6nd_hasradhcp(ifp) || dhcp6_hasprefixdelegation(ifp))
 		dhcp6_startdiscover(ifp);
@@ -1837,6 +1870,7 @@ dhcp6_findna(struct interface *ifp, uint
 	return i;
 }
 
+#ifndef SMALL
 static int
 dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
     const uint8_t *d, size_t l, const struct timespec *acquired)
@@ -1979,6 +2013,7 @@ dhcp6_findpd(struct interface *ifp, cons
 	}
 	return i;
 }
+#endif
 
 static int
 dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
@@ -2091,12 +2126,14 @@ dhcp6_findia(struct interface *ifp, cons
 			continue;
 		}
 		if (code == D6_OPTION_IA_PD) {
+#ifndef SMALL
 			if (dhcp6_findpd(ifp, iaid, p, ol, acquired) == 0) {
 				logger(ifp->ctx, LOG_WARNING,
 				    "%s: %s: DHCPv6 REPLY missing Prefix",
 				    ifp->name, sfrom);
 				continue;
 			}
+#endif
 		} else {
 			if (dhcp6_findna(ifp, code, iaid, p, ol, acquired) == 0)
 			{
@@ -2138,7 +2175,7 @@ dhcp6_validatelease(struct interface *if
     const char *sfrom, const struct timespec *acquired)
 {
 	struct dhcp6_state *state;
-	int nia;
+	int ok, nia;
 	struct timespec aq;
 
 	if (len <= sizeof(*m)) {
@@ -2148,7 +2185,7 @@ dhcp6_validatelease(struct interface *if
 	}
 
 	state = D6_STATE(ifp);
-	if (dhcp6_checkstatusok(ifp, m, NULL, len) == -1)
+	if ((ok = dhcp6_checkstatusok(ifp, m, NULL, len)) == -1)
 		return -1;
 
 	state->renew = state->rebind = state->expire = 0;
@@ -2159,9 +2196,19 @@ dhcp6_validatelease(struct interface *if
 	}
 	nia = dhcp6_findia(ifp, m, len, sfrom, acquired);
 	if (nia == 0) {
-		logger(ifp->ctx, LOG_ERR,
-		    "%s: no useable IA found in lease", ifp->name);
-		return -1;
+		if (state->state != DH6S_CONFIRM && ok != 1) {
+			logger(ifp->ctx, LOG_ERR,
+			    "%s: no useable IA found in lease", ifp->name);
+			return -1;
+		}
+
+		/* We are confirming and have an OK,
+		 * so look for ia's in our old lease.
+		 * IA's must have existed here otherwise we would
+		 * have rejected it earlier. */
+		assert(state->new != NULL && state->new_len != 0);
+		nia = dhcp6_findia(ifp, state->new, state->new_len,
+		    sfrom, acquired);
 	}
 	return nia;
 }
@@ -2198,7 +2245,7 @@ dhcp6_readlease(struct interface *ifp, i
 	time_t now;
 	int retval;
 	bool fd_opened;
-#ifndef NO_AUTH
+#ifdef AUTH
 	const struct dhcp6_option *o;
 #endif
 
@@ -2264,7 +2311,7 @@ dhcp6_readlease(struct interface *ifp, i
 
 auth:
 	retval = 0;
-#ifndef NO_AUTH
+#ifdef AUTH
 	/* Authenticate the message */
 	o = dhcp6_getmoption(D6_OPTION_AUTH, state->new, state->new_len);
 	if (o) {
@@ -2293,6 +2340,7 @@ auth:
 		goto ex;
 	}
 #endif
+
 	return fd;
 
 ex:
@@ -2343,9 +2391,11 @@ dhcp6_startinit(struct interface *ifp)
 				    ifp->name, state->leasefile);
 		} else if (r != 0) {
 			/* RFC 3633 section 12.1 */
+#ifndef SMALL
 			if (dhcp6_hasprefixdelegation(ifp))
 				dhcp6_startrebind(ifp);
 			else
+#endif
 				dhcp6_startconfirm(ifp);
 			return;
 		}
@@ -2353,6 +2403,7 @@ dhcp6_startinit(struct interface *ifp)
 	dhcp6_startdiscover(ifp);
 }
 
+#ifndef SMALL
 static struct ipv6_addr *
 dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix,
     const struct if_sla *sla, struct if_ia *if_ia)
@@ -2446,6 +2497,7 @@ dhcp6_ifdelegateaddr(struct interface *i
 
 	return ia;
 }
+#endif
 
 static void
 dhcp6_script_try_run(struct interface *ifp, int delegated)
@@ -2482,6 +2534,14 @@ dhcp6_script_try_run(struct interface *i
 		    "%s: waiting for DHCPv6 DAD to complete", ifp->name);
 }
 
+#ifdef SMALL
+size_t
+dhcp6_find_delegates(__unused struct interface *ifp)
+{
+
+	return 0;
+}
+#else
 static void
 dhcp6_delegate_prefix(struct interface *ifp)
 {
@@ -2638,6 +2698,7 @@ dhcp6_find_delegates(struct interface *i
 	}
 	return k;
 }
+#endif
 
 /* ARGSUSED */
 static void
@@ -2653,21 +2714,17 @@ dhcp6_handledata(void *arg)
 	const char *op;
 	struct dhcp6_message *r;
 	struct dhcp6_state *state;
-	const struct dhcp6_option *o;
+	const struct dhcp6_option *o, *auth;
 	const struct dhcp_opt *opt;
 	const struct if_options *ifo;
 	struct ipv6_addr *ap;
-	uint8_t has_new;
-	int error;
+	bool valid_op, has_new;
 	uint32_t u32;
-#ifndef NO_AUTH
-	const struct dhcp6_option *auth;
-#endif
 
 	dctx = arg;
 	ctx = dctx->ipv6;
 	ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
-	bytes = recvmsg(ctx->dhcp_fd, &ctx->rcvhdr, 0);
+	bytes = recvmsg_realloc(ctx->dhcp_fd, &ctx->rcvhdr, 0);
 	if (bytes == -1) {
 		logger(dctx, LOG_ERR, "%s: recvmsg: %m", __func__);
 		close(ctx->dhcp_fd);
@@ -2788,7 +2845,8 @@ dhcp6_handledata(void *arg)
 			return;
 		}
 	}
-#ifndef NO_AUTH
+
+#ifdef AUTH
 	/* Authenticate the message */
 	auth = dhcp6_getmoption(D6_OPTION_AUTH, r, len);
 	if (auth) {
@@ -2819,9 +2877,12 @@ dhcp6_handledata(void *arg)
 		logger(ifp->ctx, LOG_WARNING,
 		    "%s: no authentication from %s", ifp->name, ctx->sfrom);
 	}
+#else
+	auth = NULL;
 #endif
 
 	op = dhcp6_get_op(r->type);
+	valid_op = op != NULL;
 	switch(r->type) {
 	case DHCP6_REPLY:
 		switch(state->state) {
@@ -2841,14 +2902,7 @@ dhcp6_handledata(void *arg)
 			}
 			break;
 		case DH6S_CONFIRM:
-			error = dhcp6_checkstatusok(ifp, r, NULL, len);
-			/* If we got an OK status the chances are that we
-			 * didn't get the IA's returned, so preserve them
-			 * from our saved response */
-			if (error == 1)
-				goto recv;
-			if (error == -1 ||
-			    dhcp6_validatelease(ifp, r, len,
+			if (dhcp6_validatelease(ifp, r, len,
 			    ctx->sfrom, NULL) == -1)
 			{
 				dhcp6_startdiscover(ifp);
@@ -2856,12 +2910,16 @@ dhcp6_handledata(void *arg)
 			}
 			break;
 		case DH6S_DISCOVER:
-			if (has_option_mask(ifo->requestmask6,
-			    D6_OPTION_RAPID_COMMIT) &&
-			    dhcp6_getmoption(D6_OPTION_RAPID_COMMIT, r, len))
-				state->state = DH6S_REQUEST;
-			else
-				op = NULL;
+			/* Only accept REPLY in DISCOVER for RAPID_COMMIT.
+			 * Normally we get an ADVERTISE for a DISCOVER. */
+			if (!has_option_mask(ifo->requestmask6,
+			    D6_OPTION_RAPID_COMMIT) ||
+			    !dhcp6_getmoption(D6_OPTION_RAPID_COMMIT, r, len))
+			{
+				valid_op = false;
+				break;
+			}
+			/* Validate lease before setting state to REQUEST. */
 			/* FALLTHROUGH */
 		case DH6S_REQUEST: /* FALLTHROUGH */
 		case DH6S_RENEW: /* FALLTHROUGH */
@@ -2869,21 +2927,27 @@ dhcp6_handledata(void *arg)
 			if (dhcp6_validatelease(ifp, r, len,
 			    ctx->sfrom, NULL) == -1)
 			{
+#ifndef SMALL
 				/* PD doesn't use CONFIRM, so REBIND could
 				 * throw up an invalid prefix if we
 				 * changed link */
-				if (dhcp6_hasprefixdelegation(ifp))
+				if (state->state == DH6S_REBIND &&
+				    dhcp6_hasprefixdelegation(ifp))
 					dhcp6_startdiscover(ifp);
+#endif
 				return;
 			}
+			if (state->state == DH6S_DISCOVER)
+				state->state = DH6S_REQUEST;
 			break;
 		default:
-			op = NULL;
+			valid_op = false;
+			break;
 		}
 		break;
 	case DHCP6_ADVERTISE:
 		if (state->state != DH6S_DISCOVER) {
-			op = NULL;
+			valid_op = false;
 			break;
 		}
 		/* RFC7083 */
@@ -2920,7 +2984,6 @@ dhcp6_handledata(void *arg)
 			return;
 		break;
 	case DHCP6_RECONFIGURE:
-#ifndef NO_AUTH
 		if (auth == NULL) {
 			logger(ifp->ctx, LOG_ERR,
 			    "%s: unauthenticated %s from %s",
@@ -2928,7 +2991,6 @@ dhcp6_handledata(void *arg)
 			if (ifo->auth.options & DHCPCD_AUTH_REQUIRE)
 				return;
 		}
-#endif
 		logger(ifp->ctx, LOG_INFO, "%s: %s from %s",
 		    ifp->name, op, ctx->sfrom);
 		o = dhcp6_getmoption(D6_OPTION_RECONF_MSG, r, len);
@@ -2976,7 +3038,7 @@ dhcp6_handledata(void *arg)
 		    ifp->name, op, r->type);
 		return;
 	}
-	if (op == NULL) {
+	if (!valid_op) {
 		logger(ifp->ctx, LOG_WARNING,
 		    "%s: invalid state for DHCP6 type %s (%d)",
 		    ifp->name, op, r->type);
@@ -3013,11 +3075,10 @@ dhcp6_handledata(void *arg)
 		return;
 	}
 
-recv:
-	has_new = 0;
+	has_new = false;
 	TAILQ_FOREACH(ap, &state->addrs, next) {
 		if (ap->flags & IPV6_AF_NEW) {
-			has_new = 1;
+			has_new = true;
 			break;
 		}
 	}
@@ -3081,18 +3142,10 @@ recv:
 				state->renew = state->rebind = 0;
 			}
 		}
-		if (state->renew == 0) {
-			if (state->expire == ND6_INFINITE_LIFETIME)
-				state->renew = ND6_INFINITE_LIFETIME;
-			else if (state->lowpl != ND6_INFINITE_LIFETIME)
-				state->renew = (uint32_t)(state->lowpl * 0.5);
-		}
-		if (state->rebind == 0) {
-			if (state->expire == ND6_INFINITE_LIFETIME)
-				state->rebind = ND6_INFINITE_LIFETIME;
-			else if (state->lowpl != ND6_INFINITE_LIFETIME)
-				state->rebind = (uint32_t)(state->lowpl * 0.8);
-		}
+		if (state->renew == 0 && state->lowpl != ND6_INFINITE_LIFETIME)
+			state->renew = (uint32_t)(state->lowpl * 0.5);
+		if (state->rebind == 0 && state->lowpl != ND6_INFINITE_LIFETIME)
+			state->rebind = (uint32_t)(state->lowpl * 0.8);
 		break;
 	default:
 		state->reason = "UNKNOWN6";
@@ -3147,7 +3200,9 @@ recv:
 		if_initrt6(ifp->ctx);
 		ipv6_buildroutes(ifp->ctx);
 		dhcp6_writelease(ifp);
+#ifndef SMALL
 		dhcp6_delegate_prefix(ifp);
+#endif
 		dhcp6_script_try_run(ifp, 0);
 	}
 
@@ -3230,6 +3285,7 @@ errexit:
 	return -1;
 }
 
+#ifndef SMALL
 static void
 dhcp6_activateinterfaces(struct interface *ifp)
 {
@@ -3259,6 +3315,7 @@ dhcp6_activateinterfaces(struct interfac
 		}
 	}
 }
+#endif
 
 static void
 dhcp6_start1(void *arg)
@@ -3290,9 +3347,11 @@ dhcp6_start1(void *arg)
 			add_option_mask(ifo->requestmask6, D6_OPTION_FQDN);
 	}
 
+#ifndef SMALL
 	/* Rapid commit won't work with Prefix Delegation Exclusion */
 	if (dhcp6_findselfsla(ifp, NULL))
 		del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT);
+#endif
 
 	if (state->state == DH6S_INFORM) {
 		add_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME);
@@ -3302,7 +3361,9 @@ dhcp6_start1(void *arg)
 		dhcp6_startinit(ifp);
 	}
 
+#ifndef SMALL
 	dhcp6_activateinterfaces(ifp);
+#endif
 }
 
 int
@@ -3329,7 +3390,9 @@ dhcp6_start(struct interface *ifp, enum 
 		}
 		/* We're already running DHCP6 */
 		/* XXX: What if the managed flag vanishes from all RA? */
+#ifndef SMALL
 		dhcp6_activateinterfaces(ifp);
+#endif
 		return 0;
 	}
 
@@ -3388,7 +3451,9 @@ dhcp6_freedrop(struct interface *ifp, in
 	struct dhcp6_state *state;
 	struct dhcpcd_ctx *ctx;
 	unsigned long long options;
+#ifndef SMALL
 	int dropdele;
+#endif
 
 	/*
 	 * As the interface is going away from dhcpcd we need to
@@ -3410,14 +3475,18 @@ dhcp6_freedrop(struct interface *ifp, in
 		options = ifp->options->options;
 	else
 		options = ifp->ctx->options;
+#ifndef SMALL
 	dropdele = (options & (DHCPCD_STOPPING | DHCPCD_RELEASE) &&
 	    (options & DHCPCD_NODROP) != DHCPCD_NODROP);
+#endif
 
 	if (ifp->ctx->eloop)
 		eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
+#ifndef SMALL
 	if (dropdele)
 		dhcp6_delete_delegates(ifp);
+#endif
 
 	state = D6_STATE(ifp);
 	if (state) {
@@ -3491,8 +3560,10 @@ dhcp6_free(struct interface *ifp)
 	dhcp6_freedrop(ifp, 0, NULL);
 }
 
-void dhcp6_dropnondelegates(struct interface *ifp)
+void
+dhcp6_dropnondelegates(struct interface *ifp)
 {
+#ifndef SMALL
 	struct dhcp6_state *state;
 	struct ipv6_addr *ia;
 
@@ -3502,6 +3573,7 @@ void dhcp6_dropnondelegates(struct inter
 		if (ia->flags & (IPV6_AF_DELEGATED | IPV6_AF_DELEGATEDPFX))
 			return;
 	}
+#endif
 	dhcp6_drop(ifp, "EXPIRE6");
 }
 
@@ -3680,3 +3752,4 @@ dhcp6_dump(struct interface *ifp)
 	state->reason = "DUMP6";
 	return script_runreason(ifp, state->reason);
 }
+#endif
Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.25 src/external/bsd/dhcpcd/dist/ipv4.c:1.26
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.25	Mon Aug 15 11:04:53 2016
+++ src/external/bsd/dhcpcd/dist/ipv4.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.25 2016/08/15 11:04:53 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.26 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -40,6 +40,7 @@
 #include <assert.h>
 #include <ctype.h>
 #include <errno.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -198,14 +199,14 @@ int
 ipv4_hasaddr(const struct interface *ifp)
 {
 	const struct dhcp_state *dstate;
-	const struct ipv4ll_state *istate;
+
+	if (IPV4LL_STATE_RUNNING(ifp))
+		return 1;
 
 	dstate = D_CSTATE(ifp);
-	istate = IPV4LL_CSTATE(ifp);
-	return ((dstate &&
+	return (dstate &&
 	    dstate->added == STATE_ADDED &&
-	    dstate->addr != NULL) ||
-	    (istate && istate->addr));
+	    dstate->addr != NULL);
 }
 
 void
@@ -395,6 +396,19 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, in
 	return flags ? 0 : ipv4ll_handlert(ctx, cmd, rt);
 }
 
+static void
+d_kroute(struct rt *rt)
+{
+	struct dhcpcd_ctx *ctx;
+
+	ctx = rt->iface->ctx;
+	rt = ipv4_findrt(ctx, rt, 1);
+	if (rt != NULL) {
+		TAILQ_REMOVE(ctx->ipv4_kroutes, rt, next);
+		free(rt);
+	}
+}
+
 #define n_route(a)	 nc_route(NULL, a)
 #define c_route(a, b)	 nc_route(a, b)
 static int
@@ -472,8 +486,26 @@ nc_route(struct rt *ort, struct rt *nrt)
 
 	/* No route metrics, we need to delete the old route before
 	 * adding the new one. */
-	if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
-		logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
+#ifdef ROUTE_PER_GATEWAY
+	errno = 0;
+#endif
+	if (ort) {
+		if (if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
+			logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
+		else
+			d_kroute(ort);
+	}
+#ifdef ROUTE_PER_GATEWAY
+	/* The OS allows many routes to the same dest with different gateways.
+	 * dhcpcd does not support this yet, so for the time being just keep on
+	 * deleting the route until there is an error. */
+	if (ort && errno == 0) {
+		for (;;) {
+			if (if_route(RTM_DELETE, ort) == -1)
+				break;
+		}
+	}
+#endif
 	if (if_route(RTM_ADD, nrt) != -1)
 		return 0;
 #ifdef HAVE_ROUTE_METRIC
@@ -493,6 +525,10 @@ d_route(struct rt *rt)
 	if (retval == -1 && errno != ENOENT && errno != ESRCH)
 		logger(rt->iface->ctx, LOG_ERR,
 		    "%s: if_delroute: %m", rt->iface->name);
+	/* Remove the route from our kernel table so we can add a
+	 * IPv4LL default route if possible. */
+	else
+		d_kroute(rt);
 	return retval;
 }
 
@@ -643,7 +679,8 @@ add_router_host_route(struct rt_head *rt
 		return rt;
 
 	TAILQ_FOREACH(rtp, rt, next) {
-		if (rtp->dest.s_addr != INADDR_ANY)
+		if (rtp->dest.s_addr != INADDR_ANY ||
+		    rtp->gate.s_addr == INADDR_ANY)
 			continue;
 		/* Scan for a route to match */
 		TAILQ_FOREACH(rtn, rt, next) {
@@ -838,7 +875,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx)
 
 	/* Remove old routes we used to manage */
 	if (ctx->ipv4_routes) {
-		TAILQ_FOREACH(rt, ctx->ipv4_routes, next) {
+		TAILQ_FOREACH_REVERSE(rt, ctx->ipv4_routes, rt_head, next) {
 			if (find_route(nrs, rt, NULL) == NULL &&
 			    (rt->iface->options->options &
 			    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
@@ -862,8 +899,9 @@ ipv4_deladdr(struct ipv4_addr *addr, int
 	    "%s: deleting IP address %s", addr->iface->name, addr->saddr);
 
 	r = if_address(RTM_DELADDR, addr);
-	if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO &&
-	    errno != ENODEV)
+	if (r == -1 &&
+	    errno != EADDRNOTAVAIL && errno != ESRCH &&
+	    errno != ENXIO && errno != ENODEV)
 		logger(addr->iface->ctx, LOG_ERR, "%s: %s: %m",
 		    addr->iface->name, __func__);
 
@@ -899,7 +937,10 @@ delete_address(struct interface *ifp)
 
 	state = D_STATE(ifp);
 	ifo = ifp->options;
-	if (ifo->options & DHCPCD_INFORM ||
+	/* The lease could have been added, but the address deleted
+	 * by a 3rd party. */
+	if (state->addr == NULL ||
+	    ifo->options & DHCPCD_INFORM ||
 	    (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
 		return 0;
 	r = ipv4_deladdr(state->addr, 0);
@@ -1235,12 +1276,12 @@ void
 ipv4_handleifa(struct dhcpcd_ctx *ctx,
     int cmd, struct if_head *ifs, const char *ifname,
     const struct in_addr *addr, const struct in_addr *mask,
-    const struct in_addr *brd)
+    const struct in_addr *brd, const int addrflags)
 {
 	struct interface *ifp;
 	struct ipv4_state *state;
 	struct ipv4_addr *ia;
-	int flags;
+	bool ia_is_new;
 
 	if (ifs == NULL)
 		ifs = ctx->ifaces;
@@ -1265,28 +1306,28 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
 			}
 			ia->iface = ifp;
 			ia->addr = *addr;
+			ia->mask = *mask;
+			ia_is_new = true;
 #ifdef ALIAS_ADDR
 			strlcpy(ia->alias, ifname, sizeof(ia->alias));
 #endif
 			TAILQ_INSERT_TAIL(&state->addrs, ia, next);
-		}
+		} else
+			ia_is_new = false;
 		/* Mask could have changed */
-		ia->mask = *mask;
-		snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
-		    inet_ntoa(*addr), inet_ntocidr(*mask));
+		if (ia_is_new ||
+		    (mask->s_addr != INADDR_ANY &&
+		    mask->s_addr != ia->mask.s_addr))
+		{
+			ia->mask = *mask;
+			snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
+			    inet_ntoa(*addr), inet_ntocidr(*mask));
+		}
 		if (brd != NULL)
 			ia->brd = *brd;
 		else
 			ia->brd.s_addr = INADDR_ANY;
-
-		flags = if_addrflags(ia);
-		if (flags == -1) {
-			logger(ia->iface->ctx, LOG_ERR,
-			    "%s: %s: if_addrflags: %m",
-			    ia->iface->name, ia->saddr);
-			return;
-		}
-		ia->addr_flags = flags;
+		ia->addr_flags = addrflags;
 		break;
 	case RTM_DELADDR:
 		if (ia == NULL)

Index: src/external/bsd/dhcpcd/dist/dhcp6.h
diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.15 src/external/bsd/dhcpcd/dist/dhcp6.h:1.16
--- src/external/bsd/dhcpcd/dist/dhcp6.h:1.15	Fri Jul 29 10:07:57 2016
+++ src/external/bsd/dhcpcd/dist/dhcp6.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp6.h,v 1.15 2016/07/29 10:07:57 roy Exp $ */
+/* $NetBSD: dhcp6.h,v 1.16 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -232,7 +232,7 @@ struct dhcp6_state {
 #define D6_COPTION_DATA(o)						       \
     ((const uint8_t *)(o) + sizeof(struct dhcp6_option))
 
-#ifdef INET6
+#ifdef DHCP6
 void dhcp6_printoptions(const struct dhcpcd_ctx *,
     const struct dhcp_opt *, size_t);
 const struct ipv6_addr *dhcp6_iffindaddr(const struct interface *ifp,
@@ -252,14 +252,19 @@ void dhcp6_drop(struct interface *, cons
 void dhcp6_dropnondelegates(struct interface *ifp);
 int dhcp6_dump(struct interface *);
 #else
+#define dhcp6_printoptions(a, b, c) {}
+#define dhcp6_iffindaddr(a, b, c) (NULL)
+#define dhcp6_findaddr(a, b, c) (NULL)
 #define dhcp6_find_delegates(a) {}
 #define dhcp6_start(a, b) (0)
 #define dhcp6_reboot(a) {}
 #define dhcp6_renew(a) {}
-#define dhcp6_env(a, b, c, d, e) {}
+#define dhcp6_env(a, b, c, d, e) (0)
 #define dhcp6_free(a) {}
+#define dhcp6_handleifa(a, b) {}
 #define dhcp6_dadcompleted(a) (0)
 #define dhcp6_drop(a, b) {}
+#define dhcp6_dropnondelegates(a) {}
 #define dhcp6_dump(a) (-1)
 #endif
 

Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.36 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.37
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.36	Fri Jul 29 10:07:57 2016
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.36 2016/07/29 10:07:57 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.37 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -382,9 +382,6 @@ stop_interface(struct interface *ifp)
 	struct dhcpcd_ctx *ctx;
 
 	ctx = ifp->ctx;
-	if (!ifp->active)
-		goto stop;
-
 	logger(ctx, LOG_INFO, "%s: removing interface", ifp->name);
 	ifp->options->options |= DHCPCD_STOPPING;
 
@@ -403,7 +400,6 @@ stop_interface(struct interface *ifp)
 	/* Set the link state to unknown as we're no longer tracking it. */
 	ifp->carrier = LINK_UNKNOWN;
 
-stop:
 	if (!(ctx->options & (DHCPCD_MASTER | DHCPCD_TEST)))
 		eloop_exit(ctx->eloop, EXIT_FAILURE);
 }
@@ -603,8 +599,11 @@ configure_interface(struct interface *if
 
 	old = ifp->options ? ifp->options->mtime : 0;
 	dhcpcd_selectprofile(ifp, NULL);
-	if (ifp->options == NULL)
+	if (ifp->options == NULL) {
+		/* dhcpcd cannot continue with this interface. */
+		ifp->active = IF_INACTIVE;
 		return;
+	}
 	add_options(ifp->ctx, ifp->name, ifp->options, argc, argv);
 	ifp->options->options |= options;
 	configure_interface1(ifp);
@@ -661,15 +660,6 @@ dhcpcd_initstate2(struct interface *ifp,
 		logger(ifp->ctx, LOG_ERR, "ipv6_init: %m");
 		ifo->options &= ~DHCPCD_IPV6RS;
 	}
-
-	/* Add our link-local address before upping the interface
-	 * so our RFC7217 address beats the hwaddr based one.
-	 * This needs to happen before PREINIT incase a hook script
-	 * inadvertently ups the interface. */
-	if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) {
-		logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name);
-		ifo->options &= ~DHCPCD_IPV6;
-	}
 }
 
 static void
@@ -678,7 +668,8 @@ dhcpcd_initstate1(struct interface *ifp,
 {
 
 	configure_interface(ifp, argc, argv, options);
-	dhcpcd_initstate2(ifp, 0);
+	if (ifp->active)
+		dhcpcd_initstate2(ifp, 0);
 }
 
 static void
@@ -812,20 +803,6 @@ warn_iaid_conflict(struct interface *ifp
 		    ifp->name, ifn->name);
 }
 
-static void
-pre_start(struct interface *ifp)
-{
-
-	/* Add our link-local address before upping the interface
-	 * so our RFC7217 address beats the hwaddr based one.
-	 * This is also a safety check incase it was ripped out
-	 * from under us. */
-	if (ifp->options->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) {
-		logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name);
-		ifp->options->options &= ~DHCPCD_IPV6;
-	}
-}
-
 void
 dhcpcd_startinterface(void *arg)
 {
@@ -890,6 +867,10 @@ dhcpcd_startinterface(void *arg)
 		}
 	}
 
+	if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) {
+		logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name);
+		ifo->options &= ~DHCPCD_IPV6;
+	}
 	if (ifo->options & DHCPCD_IPV6) {
 		ipv6_startstatic(ifp);
 
@@ -944,7 +925,6 @@ dhcpcd_prestartinterface(void *arg)
 {
 	struct interface *ifp = arg;
 
-	pre_start(ifp);
 	if ((!(ifp->ctx->options & DHCPCD_MASTER) ||
 	    ifp->options->options & DHCPCD_IF_UP) &&
 	    if_up(ifp) == -1)
@@ -972,7 +952,6 @@ static void
 run_preinit(struct interface *ifp)
 {
 
-	pre_start(ifp);
 	if (ifp->ctx->options & DHCPCD_TEST)
 		return;
 
@@ -990,9 +969,13 @@ dhcpcd_activateinterface(struct interfac
 	if (!ifp->active) {
 		ifp->active = IF_ACTIVE;
 		dhcpcd_initstate2(ifp, options);
-		configure_interface1(ifp);
-		run_preinit(ifp);
-		dhcpcd_prestartinterface(ifp);
+		/* It's possible we might not have been able to load
+		 * a config. */
+		if (ifp->active) {
+			configure_interface1(ifp);
+			run_preinit(ifp);
+			dhcpcd_prestartinterface(ifp);
+		}
 	}
 }
 
@@ -1142,7 +1125,8 @@ reload_config(struct dhcpcd_ctx *ctx)
 	struct if_options *ifo;
 
 	free_globals(ctx);
-	ifo = read_config(ctx, NULL, NULL, NULL);
+	if ((ifo = read_config(ctx, NULL, NULL, NULL)) == NULL)
+		return;
 	add_options(ctx, NULL, ifo, ctx->argc, ctx->argv);
 	/* We need to preserve these two options. */
 	if (ctx->options & DHCPCD_MASTER)
@@ -1188,13 +1172,13 @@ stop_all_interfaces(struct dhcpcd_ctx *c
 	ctx->options |= DHCPCD_EXITING;
 	/* Drop the last interface first */
 	TAILQ_FOREACH_REVERSE(ifp, ctx->ifaces, if_head, next) {
-		if (ifp->options) {
+		if (ifp->active) {
 			ifp->options->options |= opts;
 			if (ifp->options->options & DHCPCD_RELEASE)
 				ifp->options->options &= ~DHCPCD_PERSISTENT;
 			ifp->options->options |= DHCPCD_EXITING;
+			stop_interface(ifp);
 		}
-		stop_interface(ifp);
 	}
 }
 
@@ -1407,6 +1391,8 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx
 		for (oi = optind; oi < argc; oi++) {
 			if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
 				continue;
+			if (!ifp->active)
+				continue;
 			ifp->options->options |= opts;
 			if (opts & DHCPCD_RELEASE)
 				ifp->options->options &= ~DHCPCD_PERSISTENT;
@@ -1459,6 +1445,23 @@ main(int argc, char **argv)
 			return EXIT_SUCCESS;
 		} else if (strcmp(argv[1], "--version") == 0) {
 			printf(""PACKAGE" "VERSION"\n%s\n", dhcpcd_copyright);
+			printf("Compiled in features:"
+#ifdef INET
+			" INET"
+#endif
+#ifdef IPV4LL
+			" IPv4LL"
+#endif
+#ifdef INET6
+			" INET6"
+#endif
+#ifdef DHCP6
+			" DHCPv6"
+#endif
+#ifdef AUTH
+			" AUTH"
+#endif
+			"\n");
 			return EXIT_SUCCESS;
 		}
 	}
@@ -1974,6 +1977,7 @@ exit1:
 	if (control_stop(&ctx) == -1)
 		logger(&ctx, LOG_ERR, "control_stop: %m:");
 	eloop_free(ctx.eloop);
+	free(ctx.iov[0].iov_base);
 
 	if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED))
 		logger(&ctx, LOG_INFO, PACKAGE " exited");

Index: src/external/bsd/dhcpcd/dist/dhcpcd.h
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.19 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.20
--- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.19	Fri Jul 29 10:07:58 2016
+++ src/external/bsd/dhcpcd/dist/dhcpcd.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcpcd.h,v 1.19 2016/07/29 10:07:58 roy Exp $ */
+/* $NetBSD: dhcpcd.h,v 1.20 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -123,6 +123,7 @@ struct dhcpcd_ctx {
 	int link_fd;
 	int seq;	/* route message sequence no */
 	int sseq;	/* successful seq no sent */
+	struct iovec iov[1];	/* generic iovec buffer */
 
 #ifdef USE_SIGNALS
 	sigset_t sigset;
Index: src/external/bsd/dhcpcd/dist/ipv4.h
diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.19 src/external/bsd/dhcpcd/dist/ipv4.h:1.20
--- src/external/bsd/dhcpcd/dist/ipv4.h:1.19	Fri Jul 29 10:07:58 2016
+++ src/external/bsd/dhcpcd/dist/ipv4.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4.h,v 1.19 2016/07/29 10:07:58 roy Exp $ */
+/* $NetBSD: ipv4.h,v 1.20 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -154,7 +154,8 @@ struct ipv4_addr *ipv4_findaddr(struct d
 struct ipv4_addr *ipv4_findmaskaddr(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 *);
+    const struct in_addr *, const struct in_addr *, const struct in_addr *,
+    int);
 
 void ipv4_freeroutes(struct rt_head *);
 

Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.33 src/external/bsd/dhcpcd/dist/if-bsd.c:1.34
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.33	Mon Aug 15 11:04:53 2016
+++ src/external/bsd/dhcpcd/dist/if-bsd.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.33 2016/08/15 11:04:53 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.34 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -740,7 +740,7 @@ if_route(unsigned char cmd, const struct
 #endif
 
 	addrs = 0;
-	flags = 0;
+	flags = (int)rt->flags;
 
 	if (cmd == RTM_ADD || cmd == RTM_CHANGE) {
 		addrs |= RTA_GATEWAY | RTA_IFP;
@@ -852,26 +852,30 @@ if_initrt(struct dhcpcd_ctx *ctx)
 	return 0;
 }
 
+#if !(defined(HAVE_IFADDRS_ADDRFLAGS) && defined(HAVE_IFAM_ADDRFLAGS))
 int
-if_addrflags(const struct ipv4_addr *ia)
+if_addrflags(const struct interface *ifp, const struct in_addr *addr,
+    __unused const char *alias)
 {
 #ifdef SIOCGIFAFLAG_IN
 	struct ifreq ifr;
 	struct sockaddr_in *sin;
 
 	memset(&ifr, 0, sizeof(ifr));
-	strlcpy(ifr.ifr_name, ia->iface->name, sizeof(ifr.ifr_name));
+	strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
 	sin = (void *)&ifr.ifr_addr;
 	sin->sin_family = AF_INET;
-	sin->sin_addr = ia->addr;
-	if (ioctl(ia->iface->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1)
+	sin->sin_addr = *addr;
+	if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1)
 		return -1;
 	return ifr.ifr_addrflags;
 #else
-	UNUSED(ia);
+	UNUSED(ifp);
+	UNUSED(addr);
 	return 0;
 #endif
 }
+#endif
 #endif /* INET */
 
 #ifdef INET6
@@ -970,11 +974,13 @@ if_address6(unsigned char cmd, const str
 	 * This issue is discussed on the NetBSD mailing lists here:
 	 * http://mail-index.netbsd.org/tech-net/2016/08/05/msg006044.html
 	 *
-	 * NOT fixed in NetBSD - patch under development
+	 * Fixed in NetBSD-7.99.36
 	 * NOT fixed in FreeBSD - bug 195197
 	 * Fixed in OpenBSD-5.9
 	 */
-#if !(defined(OpenBSD) && OpenBSD >= 201605)
+
+#if !((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 799003600) || \
+      (defined(__OpenBSD__)))
 	if (cmd == RTM_NEWADDR && !(ia->flags & IPV6_AF_ADDED)) {
 		ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
 		ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
@@ -982,8 +988,22 @@ if_address6(unsigned char cmd, const str
 	}
 #endif
 
+#if defined(__OpenBSD__)
+	/* BUT OpenBSD does not reset the address lifetime
+	 * for subsequent calls...
+	 * Luckily dhcpcd will remove the lease when it expires so
+	 * just set an infinite lifetime, unless a temporary address. */
+	if (ifa.ifra_flags & IN6_IFF_PRIVACY) {
+		ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime;
+		ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime;
+	} else {
+		ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
+		ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
+	}
+#else
 	ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime;
 	ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime;
+#endif
 
 	return ioctl(priv->pf_inet6_fd,
 	    cmd == RTM_DELADDR ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
@@ -1200,25 +1220,28 @@ if_initrt6(struct dhcpcd_ctx *ctx)
 	return 0;
 }
 
+#if !(defined(HAVE_IFADDRS_ADDRFLAGS) && defined(HAVE_IFAM_ADDRFLAGS))
 int
-if_addrflags6(const struct ipv6_addr *ia)
+if_addrflags6(const struct interface *ifp, const struct in6_addr *addr,
+    __unused const char *alias)
 {
 	int flags;
 	struct in6_ifreq ifr6;
 	struct priv *priv;
 
 	memset(&ifr6, 0, sizeof(ifr6));
-	strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name));
+	strlcpy(ifr6.ifr_name, ifp->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);
-	priv = (struct priv *)ia->iface->ctx->priv;
+	ifr6.ifr_addr.sin6_addr = *addr;
+	ifa_scope(&ifr6.ifr_addr, ifp->index);
+	priv = (struct priv *)ifp->ctx->priv;
 	if (ioctl(priv->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
 		flags = ifr6.ifr_ifru.ifru_flags6;
 	else
 		flags = -1;
 	return flags;
 }
+#endif
 
 int
 if_getlifetime6(struct ipv6_addr *ia)
@@ -1275,55 +1298,67 @@ static void
 if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm)
 {
 	struct interface *ifp;
-	int state;
+	int link_state;
 
 	if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL)
 		return;
 	switch (ifm->ifm_data.ifi_link_state) {
 	case LINK_STATE_DOWN:
-		state = LINK_DOWN;
+		link_state = LINK_DOWN;
 		break;
 	case LINK_STATE_UP:
-		state = LINK_UP;
+		/* dhcpcd considers the link down if IFF_UP is not set. */
+		link_state = ifm->ifm_flags & IFF_UP ? LINK_UP : LINK_DOWN;
 		break;
 	default:
 		/* handle_carrier will re-load the interface flags and check for
 		 * IFF_RUNNING as some drivers that don't handle link state also
 		 * don't set IFF_RUNNING when this routing message is generated.
 		 * As such, it is a race ...*/
-		state = LINK_UNKNOWN;
+		link_state = LINK_UNKNOWN;
 		break;
 	}
-	dhcpcd_handlecarrier(ctx, state,
+	dhcpcd_handlecarrier(ctx, link_state,
 	    (unsigned int)ifm->ifm_flags, ifp->name);
 }
 
-static void
-if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
+static int
+if_ownmsgpid(struct dhcpcd_ctx *ctx, pid_t pid, int seq)
 {
-	const struct sockaddr *sa;
 
 	/* Ignore messages generated by us */
-	if (rtm->rtm_pid == getpid()) {
+	if (getpid() == pid) {
 		ctx->options &= ~DHCPCD_RTM_PPID;
-		return;
+		return 1;
 	}
 
 	/* Ignore messages sent by the parent after forking */
 	if ((ctx->options &
 	    (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) ==
 	    (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) &&
-	    rtm->rtm_pid == ctx->ppid)
+	    ctx->ppid == pid)
 	{
 		/* If this is the last successful message sent,
 		 * clear the check flag as it's possible another
 		 * process could re-use the same pid and also
-		 * manipulate therouting table. */
-		if (rtm->rtm_seq == ctx->pseq)
+		 * manipulate the routing table. */
+		if (ctx->pseq == seq)
 			ctx->options &= ~DHCPCD_RTM_PPID;
-		return;
+		return 1;
 	}
 
+	/* Not a message we made. */
+	return 0;
+}
+
+static void
+if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
+{
+	const struct sockaddr *sa;
+
+	if (if_ownmsgpid(ctx, rtm->rtm_pid, rtm->rtm_seq))
+		return;
+
 	sa = (const void *)(rtm + 1);
 	switch (sa->sa_family) {
 #ifdef INET
@@ -1380,15 +1415,21 @@ if_ifa(struct dhcpcd_ctx *ctx, const str
 {
 	struct interface *ifp;
 	const struct sockaddr *rti_info[RTAX_MAX];
+	int addrflags;
+
+#ifdef HAVE_IFAM_PID
+	if (if_ownmsgpid(ctx, ifam->ifam_pid, 0))
+		return;
+#endif
 
-	/* XXX We have no way of knowing who generated these
-	 * messages wich truely sucks because we want to
-	 * avoid listening to our own delete messages. */
 	if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL)
 		return;
 	get_addrs(ifam->ifam_addrs, ifam + 1, rti_info);
 	if (rti_info[RTAX_IFA] == NULL)
 		return;
+#ifdef HAVE_IFAM_ADDRFLAGS
+	addrflags = ifam->ifam_addrflags;
+#endif
 	switch (rti_info[RTAX_IFA]->sa_family) {
 	case AF_LINK:
 	{
@@ -1421,8 +1462,45 @@ if_ifa(struct dhcpcd_ctx *ctx, const str
 		sin = (const void *)rti_info[RTAX_BRD];
 		bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ?
 		    sin->sin_addr.s_addr : INADDR_ANY;
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+		/* FreeBSD sends RTM_DELADDR for each assigned address
+		 * to an interface just brought down.
+		 * This is wrong, because the address still exists.
+		 * So we need to ignore it.
+		 * Oddly enough this only happens for INET addresses. */
+		if (ifam->ifam_type == RTM_DELADDR) {
+			struct ifreq ifr;
+			struct sockaddr_in *ifr_sin;
+
+			memset(&ifr, 0, sizeof(ifr));
+			strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+			ifr_sin = (void *)&ifr.ifr_addr;
+			ifr_sin->sin_family = AF_INET;
+			ifr_sin->sin_addr = addr;
+			if (ioctl(ctx->pf_inet_fd, SIOCGIFADDR, &ifr) == 0) {
+				logger(ctx, LOG_WARNING,
+				    "%s: ignored false RTM_DELADDR for %s",
+				    ifp->name, inet_ntoa(addr));
+				break;
+			}
+		}
+#endif
+
+#ifndef HAVE_IFAM_ADDRFLAGS
+		if (ifam->ifam_type == RTM_DELADDR ||
+		    (addrflags = if_addrflags(ifp, &addr, NULL)) == -1)
+		{
+			if (ifam->ifam_type != RTM_DELADDR || errno != EEXIST)
+				logger(ctx, LOG_ERR,
+				    "%s: if_addrflags: %s: %m",
+				    ifp->name, inet_ntoa(addr));
+			addrflags = 0;
+		}
+#endif
+
 		ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name,
-		    &addr, &mask, &bcast);
+		    &addr, &mask, &bcast, addrflags);
 		break;
 	}
 #endif
@@ -1438,8 +1516,21 @@ if_ifa(struct dhcpcd_ctx *ctx, const str
 		sin6 = (const void *)rti_info[RTAX_NETMASK];
 		mask6 = sin6->sin6_addr;
 		DESCOPE(&mask6);
+
+#ifndef HAVE_IFAM_ADDRFLAGS
+		if (ifam->ifam_type == RTM_DELADDR ||
+		    (addrflags = if_addrflags6(ifp, &addr6, NULL)) == -1)
+		{
+			if (ifam->ifam_type != RTM_DELADDR || errno != EEXIST)
+				logger(ctx, LOG_ERR,
+				    "%s: if_addrflags: %m",
+				    ifp->name);
+			addrflags = 0;
+		}
+#endif
+
 		ipv6_handleifa(ctx, ifam->ifam_type, NULL,
-		    ifp->name, &addr6, ipv6_prefixlen(&mask6));
+		    ifp->name, &addr6, ipv6_prefixlen(&mask6), addrflags);
 		break;
 	}
 #endif
@@ -1450,6 +1541,9 @@ static void
 if_dispatch(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
 {
 
+	if (rtm->rtm_version != RTM_VERSION)
+		return;
+
 	switch(rtm->rtm_type) {
 #ifdef RTM_IFANNOUNCE
 	case RTM_IFANNOUNCE:
@@ -1477,21 +1571,17 @@ if_dispatch(struct dhcpcd_ctx *ctx, cons
 int
 if_handlelink(struct dhcpcd_ctx *ctx)
 {
-	/* route and ifwatchd like a msg buf size of 2048 */
-	char buf[2048];
-	const char *p, *e;
-	size_t msglen;
-	ssize_t bytes;
-	const struct rt_msghdr *rtm;
+	struct msghdr msg;
+	ssize_t len;
 
-	if ((bytes = read(ctx->link_fd, buf, sizeof(buf))) == -1)
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = ctx->iov;
+	msg.msg_iovlen = 1;
+
+	if ((len = recvmsg_realloc(ctx->link_fd, &msg, 0)) == -1)
 		return -1;
-	e = buf + bytes;
-	for (p = buf; p < e; p += msglen) {
-		rtm = (const void *)p;
-		msglen = rtm->rtm_msglen;
-		if_dispatch(ctx, rtm);
-	}
+	if (len != 0)
+		if_dispatch(ctx, ctx->iov[0].iov_base);
 	return 0;
 }
 
@@ -1688,10 +1778,6 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 	int ra;
 
 	if (ifp) {
-#ifdef ND6_IFF_OVERRIDE_RTADV
-		int override;
-#endif
-
 #ifdef ND6_IFF_AUTO_LINKLOCAL
 		if (own) {
 			int all;
@@ -1729,24 +1815,6 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 		}
 #endif
 
-#ifdef ND6_IFF_OVERRIDE_RTADV
-		override = get_if_nd6_flag(s, ifp, ND6_IFF_OVERRIDE_RTADV);
-		if (override == -1)
-			logger(ifp->ctx, LOG_ERR,
-			    "%s: get_if_nd6_flag: ND6_IFF_OVERRIDE_RTADV: %m",
-			    ifp->name);
-		else if (override == 0 && own) {
-			if (set_if_nd6_flag(s, ifp, ND6_IFF_OVERRIDE_RTADV)
-			    == -1)
-				logger(ifp->ctx, LOG_ERR,
-				    "%s: set_if_nd6_flag: "
-				    "ND6_IFF_OVERRIDE_RTADV: %m",
-				    ifp->name);
-			else
-				override = 1;
-		}
-#endif
-
 #ifdef ND6_IFF_ACCEPT_RTADV
 		ra = get_if_nd6_flag(s, ifp, ND6_IFF_ACCEPT_RTADV);
 		if (ra == -1)
@@ -1800,10 +1868,6 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 #endif
 
 #ifdef ND6_IFF_ACCEPT_RTADV
-#ifdef ND6_IFF_OVERRIDE_RTADV
-		if (override == 0 && ra)
-			return ctx->ra_global;
-#endif
 		return ra;
 #else
 		return ctx->ra_global;

Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.35 src/external/bsd/dhcpcd/dist/if-options.c:1.36
--- src/external/bsd/dhcpcd/dist/if-options.c:1.35	Fri Jul 29 10:07:58 2016
+++ src/external/bsd/dhcpcd/dist/if-options.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.35 2016/07/29 10:07:58 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.36 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -290,7 +290,7 @@ parse_string_hwaddr(char *sbuf, size_t s
 	size_t l;
 	const char *p;
 	int i, punt_last = 0;
-	char c[4];
+	char c[4], cmd;
 
 	/* If surrounded by quotes then it's a string */
 	if (*str == '"') {
@@ -328,28 +328,25 @@ parse_string_hwaddr(char *sbuf, size_t s
 		}
 		if (*str == '\\') {
 			str++;
-			switch(*str) {
+			switch((cmd = *str++)) {
 			case '\0':
+				str--;
 				break;
 			case 'b':
 				if (sbuf)
 					*sbuf++ = '\b';
-				str++;
 				break;
 			case 'n':
 				if (sbuf)
 					*sbuf++ = '\n';
-				str++;
 				break;
 			case 'r':
 				if (sbuf)
 					*sbuf++ = '\r';
-				str++;
 				break;
 			case 't':
 				if (sbuf)
 					*sbuf++ = '\t';
-				str++;
 				break;
 			case 'x':
 				/* Grab a hex code */
@@ -383,8 +380,7 @@ parse_string_hwaddr(char *sbuf, size_t s
 				break;
 			default:
 				if (sbuf)
-					*sbuf++ = *str;
-				str++;
+					*sbuf++ = cmd;
 				break;
 			}
 		} else {
@@ -434,12 +430,14 @@ parse_iaid(uint8_t *iaid, const char *ar
 	return parse_iaid1(iaid, arg, len, 1);
 }
 
+#ifdef AUTH
 static int
 parse_uint32(uint32_t *i, const char *arg)
 {
 
 	return parse_iaid1((uint8_t *)i, arg, sizeof(uint32_t), 0);
 }
+#endif
 
 static char **
 splitv(struct dhcpcd_ctx *ctx, int *argc, char **argv, const char *arg)
@@ -629,6 +627,7 @@ strskipwhite(const char *s)
 	return UNCONST(s);
 }
 
+#ifdef AUTH
 /* Find the end pointer of a string. */
 static char *
 strend(const char *s)
@@ -650,6 +649,7 @@ strend(const char *s)
 	}
 	return UNCONST(++s);
 }
+#endif
 
 static int
 parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
@@ -668,12 +668,14 @@ parse_option(struct dhcpcd_ctx *ctx, con
 	struct dhcp_opt **dop, *ndop;
 	size_t *dop_len, dl, odl;
 	struct vivco *vivco;
-	struct token *token;
 	struct group *grp;
+#ifdef AUTH
+	struct token *token;
+#endif
 #ifdef _REENTRANT
 	struct group grpbuf;
 #endif
-#ifdef INET6
+#ifdef DHCP6
 	size_t sl;
 	struct if_ia *ia;
 	uint8_t iaid[4];
@@ -1329,7 +1331,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 	case O_NOALIAS:
 		ifo->options |= DHCPCD_NOALIAS;
 		break;
-#ifdef INET6
+#ifdef DHCP6
 	case O_IA_NA:
 		i = D6_OPTION_IA_NA;
 		/* FALLTHROUGH */
@@ -1903,6 +1905,7 @@ err_sla:
 		break;
 	case O_AUTHPROTOCOL:
 		ARG_REQUIRED;
+#ifdef AUTH
 		fp = strwhite(arg);
 		if (fp)
 			*fp++ = '\0';
@@ -1951,8 +1954,13 @@ err_sla:
 		}
 		ifo->auth.options |= DHCPCD_AUTH_SEND;
 		break;
+#else
+		logger(ctx, LOG_ERR, "no authentication support");
+		return -1;
+#endif
 	case O_AUTHTOKEN:
 		ARG_REQUIRED;
+#ifdef AUTH
 		fp = strwhite(arg);
 		if (fp == NULL) {
 			logger(ctx, LOG_ERR, "authtoken requires a realm");
@@ -2045,6 +2053,10 @@ err_sla:
 		token->key = malloc(token->key_len);
 		parse_string((char *)token->key, token->key_len, arg);
 		TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next);
+#else
+		logger(ctx, LOG_ERR, "no authentication support");
+		return -1;
+#endif
 		break;
 	case O_AUTHNOTREQUIRED:
 		ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE;
@@ -2251,7 +2263,9 @@ default_config(struct dhcpcd_ctx *ctx)
 	ifo->reboot = DEFAULT_REBOOT;
 	ifo->metric = -1;
 	ifo->auth.options |= DHCPCD_AUTH_REQUIRE;
+#ifdef AUTH
 	TAILQ_INIT(&ifo->auth.tokens);
+#endif
 
 	/* Inherit some global defaults */
 	if (ctx->options & DHCPCD_PERSISTENT)
@@ -2571,7 +2585,9 @@ free_options(struct if_options *ifo)
 	size_t i;
 	struct dhcp_opt *opt;
 	struct vivco *vo;
+#ifdef AUTH
 	struct token *token;
+#endif
 
 	if (ifo) {
 		if (ifo->environ) {
@@ -2624,6 +2640,7 @@ free_options(struct if_options *ifo)
 #endif
 		free(ifo->ia);
 
+#ifdef AUTH
 		while ((token = TAILQ_FIRST(&ifo->auth.tokens))) {
 			TAILQ_REMOVE(&ifo->auth.tokens, token, next);
 			if (token->realm_len)
@@ -2631,6 +2648,7 @@ free_options(struct if_options *ifo)
 			free(token->key);
 			free(token);
 		}
+#endif
 		free(ifo);
 	}
 }

Index: src/external/bsd/dhcpcd/dist/if.c
diff -u src/external/bsd/dhcpcd/dist/if.c:1.23 src/external/bsd/dhcpcd/dist/if.c:1.24
--- src/external/bsd/dhcpcd/dist/if.c:1.23	Fri Jul 29 10:07:58 2016
+++ src/external/bsd/dhcpcd/dist/if.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if.c,v 1.23 2016/07/29 10:07:58 roy Exp $");
+ __RCSID("$NetBSD: if.c,v 1.24 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -201,12 +201,16 @@ static void if_learnaddrs(struct dhcpcd_
 #ifdef INET6
 	struct sockaddr_in6 *sin6, *net6;
 #endif
+	int addrflags;
 
 	for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
 		if (ifa->ifa_addr == NULL)
 			continue;
 		if ((ifp = if_find(ifs, ifa->ifa_name)) == NULL)
 			continue;
+#ifdef HAVE_IFADDRS_ADDRFLAGS
+		addrflags = (int)ifa->ifa_addrflags;
+#endif
 		switch(ifa->ifa_addr->sa_family) {
 #ifdef INET
 		case AF_INET:
@@ -216,9 +220,21 @@ static void if_learnaddrs(struct dhcpcd_
 				brd = (void *)ifa->ifa_dstaddr;
 			else
 				brd = (void *)ifa->ifa_broadaddr;
+#ifndef HAVE_IFADDRS_ADDRFLAGS
+			addrflags = if_addrflags(ifp, &addr->sin_addr,
+			    ifa->ifa_name);
+			if (addrflags == -1) {
+				if (errno != EEXIST)
+					logger(ctx, LOG_ERR,
+					    "%s: if_addrflags: %s: %m",
+					    __func__,
+					    inet_ntoa(addr->sin_addr));
+				continue;
+			}
+#endif
 			ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name,
 				&addr->sin_addr, &net->sin_addr,
-				brd ? &brd->sin_addr : NULL);
+				brd ? &brd->sin_addr : NULL, addrflags);
 			break;
 #endif
 #ifdef INET6
@@ -231,9 +247,19 @@ static void if_learnaddrs(struct dhcpcd_
 				sin6->sin6_addr.s6_addr[2] =
 				    sin6->sin6_addr.s6_addr[3] = '\0';
 #endif
+#ifndef HAVE_IFADDRS_ADDRFLAGS
+			addrflags = if_addrflags6(ifp, &sin6->sin6_addr,
+			    ifa->ifa_name);
+			if (addrflags == -1) {
+				if (errno != EEXIST)
+					logger(ctx, LOG_ERR,
+					    "%s: if_addrflags6:  %m", __func__);
+				continue;
+			}
+#endif
 			ipv6_handleifa(ctx, RTM_NEWADDR, ifs,
 			    ifa->ifa_name, &sin6->sin6_addr,
-			    ipv6_prefixlen(&net6->sin6_addr));
+			    ipv6_prefixlen(&net6->sin6_addr), addrflags);
 			break;
 #endif
 		}

Index: src/external/bsd/dhcpcd/dist/if.h
diff -u src/external/bsd/dhcpcd/dist/if.h:1.18 src/external/bsd/dhcpcd/dist/if.h:1.19
--- src/external/bsd/dhcpcd/dist/if.h:1.18	Fri Jul 29 10:07:58 2016
+++ src/external/bsd/dhcpcd/dist/if.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.18 2016/07/29 10:07:58 roy Exp $ */
+/* $NetBSD: if.h,v 1.19 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -45,6 +45,12 @@
 # endif
 #endif
 
+#if defined(__OpenBSD) || defined (__sun)
+#  define ROUTE_PER_GATEWAY
+/* XXX dhcpcd doesn't really support this yet.
+ * But that's generally OK if only dhcpcd is managing routes. */
+#endif
+
 /* Some systems have in-built IPv4 DAD.
  * However, we need them to do DAD at carrier up as well. */
 #ifdef IN_IFF_TENTATIVE
@@ -181,7 +187,8 @@ ssize_t if_readraw(struct interface *, i
 void if_closeraw(struct interface *, int);
 
 int if_address(unsigned char, const struct ipv4_addr *);
-int if_addrflags(const struct ipv4_addr *);
+int if_addrflags(const struct interface *, const struct in_addr *,
+    const char *);
 
 int if_route(unsigned char, const struct rt *rt);
 int if_initrt(struct dhcpcd_ctx *);
@@ -198,7 +205,8 @@ int ip6_temp_valid_lifetime(const char *
 #endif
 
 int if_address6(unsigned char, const struct ipv6_addr *);
-int if_addrflags6(const struct ipv6_addr *);
+int if_addrflags6(const struct interface *, const struct in6_addr *,
+    const char *);
 int if_getlifetime6(struct ipv6_addr *);
 
 int if_route6(unsigned char, const struct rt6 *rt);
Index: src/external/bsd/dhcpcd/dist/ipv4ll.c
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.18 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.19
--- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.18	Fri Jul 29 10:07:58 2016
+++ src/external/bsd/dhcpcd/dist/ipv4ll.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4ll.c,v 1.18 2016/07/29 10:07:58 roy Exp $");
+ __RCSID("$NetBSD: ipv4ll.c,v 1.19 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -48,6 +48,7 @@
 #include "ipv4ll.h"
 #include "script.h"
 
+#ifdef IPV4LL
 static const struct in_addr inaddr_llmask = {
 	.s_addr = HTONL(LINKLOCAL_MASK)
 };
@@ -493,3 +494,4 @@ ipv4ll_handlert(struct dhcpcd_ctx *ctx, 
 	return 0;
 }
 #endif
+#endif

Index: src/external/bsd/dhcpcd/dist/ipv4ll.h
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.h:1.12 src/external/bsd/dhcpcd/dist/ipv4ll.h:1.13
--- src/external/bsd/dhcpcd/dist/ipv4ll.h:1.12	Fri Jun 17 19:42:32 2016
+++ src/external/bsd/dhcpcd/dist/ipv4ll.h	Sun Oct  9 09:18:26 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4ll.h,v 1.12 2016/06/17 19:42:32 roy Exp $ */
+/* $NetBSD: ipv4ll.h,v 1.13 2016/10/09 09:18:26 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,17 +30,17 @@
 #ifndef IPV4LL_H
 #define IPV4LL_H
 
-#ifdef INET
-#include "arp.h"
-
-#define LINKLOCAL_ADDR	0xa9fe0000
-#define LINKLOCAL_MASK	IN_CLASSB_NET
-#define LINKLOCAL_BCAST	(LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
+#define	LINKLOCAL_ADDR		0xa9fe0000
+#define	LINKLOCAL_MASK		IN_CLASSB_NET
+#define	LINKLOCAL_BCAST		(LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
 
 #ifndef IN_LINKLOCAL
 # define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR)
 #endif
 
+#ifdef IPV4LL
+#include "arp.h"
+
 struct ipv4ll_state {
 	struct ipv4_addr *addr;
 	struct arp_state *arp;
@@ -50,11 +50,11 @@ struct ipv4ll_state {
 	uint8_t down;
 };
 
-#define IPV4LL_STATE(ifp)						       \
+#define	IPV4LL_STATE(ifp)						       \
 	((struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL])
-#define IPV4LL_CSTATE(ifp)						       \
+#define	IPV4LL_CSTATE(ifp)						       \
 	((const struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL])
-#define IPV4LL_STATE_RUNNING(ifp)					       \
+#define	IPV4LL_STATE_RUNNING(ifp)					       \
 	(IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down &&		       \
 	(IPV4LL_CSTATE((ifp))->addr != NULL))
 
@@ -67,16 +67,19 @@ void ipv4ll_handle_failure(void *);
 #ifdef HAVE_ROUTE_METRIC
 int ipv4ll_handlert(struct dhcpcd_ctx *, int, const struct rt *);
 #else
-#define ipv4ll_handlert(a, b, c) (0)
+#define	ipv4ll_handlert(a, b, c)	(0)
 #endif
 
-#define ipv4ll_free(ifp) ipv4ll_freedrop((ifp), 0);
-#define ipv4ll_drop(ifp) ipv4ll_freedrop((ifp), 1);
+#define	ipv4ll_free(ifp) ipv4ll_freedrop((ifp), 0);
+#define	ipv4ll_drop(ifp) ipv4ll_freedrop((ifp), 1);
 void ipv4ll_freedrop(struct interface *, int);
 #else
-#define IPV4LL_STATE_RUNNING(ifp) (0)
-#define ipv4ll_free(a) {}
-#define ipv4ll_drop(a) {}
+#define	IPV4LL_STATE_RUNNING(ifp)	(0)
+#define	ipv4ll_subnet_route(ifp)	(NULL)
+#define	ipv4ll_default_route(ifp)	(NULL)
+#define	ipv4ll_handlert(a, b, c)	(0)
+#define	ipv4ll_free(a)			{}
+#define	ipv4ll_drop(a)			{}
 #endif
 
 #endif

Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.32 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.33
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.32	Mon Aug 15 11:04:53 2016
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.32 2016/08/15 11:04:53 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.33 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -715,6 +715,19 @@ try_script:
 	}
 }
 
+#ifndef DHCP6
+/* If DHCPv6 is compiled out, supply a shim to provide an error message
+ * if IPv6RA requests DHCPv6. */
+#undef dhcp6_start
+static int
+dhcp6_start(__unused struct interface *ifp, __unused enum DH6S init_state)
+{
+
+	errno = ENOTSUP;
+	return -1;
+}
+#endif
+
 static void
 ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
     struct icmp6_hdr *icp, size_t len, int hoplimit)
@@ -1105,13 +1118,19 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx,
 handle_flag:
 	if (!(ifp->options->options & DHCPCD_DHCP6))
 		goto nodhcp6;
+/* Only log a DHCPv6 start error if compiled in or debugging is enabled. */
+#ifdef DHCP6
+#define LOG_DHCP6	LOG_ERR
+#else
+#define LOG_DHCP6	LOG_DEBUG
+#endif
 	if (rap->flags & ND_RA_FLAG_MANAGED) {
 		if (new_data && dhcp6_start(ifp, DH6S_INIT) == -1)
-			logger(ifp->ctx, LOG_ERR,
+			logger(ifp->ctx, LOG_DHCP6,
 			    "dhcp6_start: %s: %m", ifp->name);
 	} else if (rap->flags & ND_RA_FLAG_OTHER) {
 		if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1)
-			logger(ifp->ctx, LOG_ERR,
+			logger(ifp->ctx, LOG_DHCP6,
 			    "dhcp6_start: %s: %m", ifp->name);
 	} else {
 		if (new_data)
@@ -1554,7 +1573,7 @@ ipv6nd_handledata(void *arg)
 	ctx = dctx->ipv6;
 	ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
 	    CMSG_SPACE(sizeof(int));
-	len = recvmsg(ctx->nd_fd, &ctx->rcvhdr, 0);
+	len = recvmsg_realloc(ctx->nd_fd, &ctx->rcvhdr, 0);
 	if (len == -1) {
 		logger(dctx, LOG_ERR, "recvmsg: %m");
 		eloop_event_delete(dctx->eloop, ctx->nd_fd);

Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.27 src/external/bsd/dhcpcd/dist/script.c:1.28
--- src/external/bsd/dhcpcd/dist/script.c:1.27	Fri Jun 17 19:42:32 2016
+++ src/external/bsd/dhcpcd/dist/script.c	Sun Oct  9 09:18:26 2016
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.27 2016/06/17 19:42:32 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.28 2016/10/09 09:18:26 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -239,8 +239,10 @@ make_env(const struct interface *ifp, co
 #ifdef INET
 	int dhcp, ipv4ll;
 	const struct dhcp_state *state;
+#ifdef IPV4LL
 	const struct ipv4ll_state *istate;
 #endif
+#endif
 #ifdef INET6
 	const struct dhcp6_state *d6_state;
 	int static6, dhcp6, ra;
@@ -249,8 +251,10 @@ make_env(const struct interface *ifp, co
 #ifdef INET
 	dhcp = ipv4ll = 0;
 	state = D_STATE(ifp);
+#ifdef IPV4LL
 	istate = IPV4LL_CSTATE(ifp);
 #endif
+#endif
 #ifdef INET6
 	static6 = dhcp6 = ra = 0;
 	d6_state = D6_CSTATE(ifp);
@@ -264,8 +268,10 @@ make_env(const struct interface *ifp, co
 			ra = 1;
 #endif
 #ifdef INET
+#ifdef IPV4LL
 		else if (istate && istate->addr != NULL)
 			ipv4ll = 1;
+#endif
 		else
 			dhcp = 1;
 #endif
@@ -288,8 +294,10 @@ make_env(const struct interface *ifp, co
 		/* This space left intentionally blank */
 	}
 #ifdef INET
+#ifdef IPV4LL
 	else if (strcmp(reason, "IPV4LL") == 0)
 		ipv4ll = 1;
+#endif
 	else
 		dhcp = 1;
 #endif
@@ -362,8 +370,10 @@ make_env(const struct interface *ifp, co
 	} else if (1 == 2 /* appease ifdefs */
 #ifdef INET
 	    || (dhcp && state && state->new)
+#ifdef IPV4LL
 	    || (ipv4ll && IPV4LL_STATE_RUNNING(ifp))
 #endif
+#endif
 #ifdef INET6
 	    || (static6 && IPV6_STATE_RUNNING(ifp))
 	    || (dhcp6 && d6_state && d6_state->new)
@@ -465,6 +475,7 @@ make_env(const struct interface *ifp, co
 
 dumplease:
 #ifdef INET
+#ifdef IPV4LL
 	if (ipv4ll) {
 		n = ipv4ll_env(NULL, NULL, ifp);
 		if (n > 0) {
@@ -479,6 +490,7 @@ dumplease:
 			elen += (size_t)n;
 		}
 	}
+#endif
 	if (dhcp && state && state->new) {
 		n = dhcp_env(NULL, NULL, state->new, state->new_len, ifp);
 		if (n > 0) {
@@ -634,11 +646,13 @@ send_interface(struct fd_list *fd, const
 		if (send_interface1(fd, ifp, d->reason) == -1)
 			retval = -1;
 	}
+#ifdef IPV4LL
 	if (IPV4LL_STATE_RUNNING(ifp)) {
 		if (send_interface1(fd, ifp, "IPV4LL") == -1)
 			retval = -1;
 	}
 #endif
+#endif
 
 #ifdef INET6
 	if (IPV6_STATE_RUNNING(ifp)) {

Reply via email to