Module Name:    src
Committed By:   roy
Date:           Mon Nov 30 16:33:01 UTC 2015

Modified Files:
        src/external/bsd/dhcpcd/dist: arp.c common.c common.h defs.h
            dhcp-common.c dhcp-common.h dhcp.c dhcp.h dhcp6.c dhcp6.h
            dhcpcd-definitions.conf dhcpcd-embedded.c dhcpcd.8.in dhcpcd.c
            dhcpcd.conf.5.in duid.c if-bsd.c if-options.c if-options.h if.c
            ipv4.c ipv4.h ipv4ll.c ipv6.c ipv6.h script.c
        src/external/bsd/dhcpcd/dist/dhcpcd-hooks: 50-ntp.conf

Log Message:
Sync


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/arp.c \
    src/external/bsd/dhcpcd/dist/common.c \
    src/external/bsd/dhcpcd/dist/if-options.h \
    src/external/bsd/dhcpcd/dist/ipv6.c src/external/bsd/dhcpcd/dist/ipv6.h
cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/common.h \
    src/external/bsd/dhcpcd/dist/dhcp.h
cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/defs.h
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/dhcp-common.c \
    src/external/bsd/dhcpcd/dist/dhcp-common.h \
    src/external/bsd/dhcpcd/dist/dhcp6.h \
    src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c
cvs rdiff -u -r1.35 -r1.36 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/dhcpcd/dist/dhcp6.c
cvs rdiff -u -r1.9 -r1.10 \
    src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf \
    src/external/bsd/dhcpcd/dist/duid.c
cvs rdiff -u -r1.44 -r1.45 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.28 -r1.29 src/external/bsd/dhcpcd/dist/dhcpcd.c
cvs rdiff -u -r1.23 -r1.24 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in \
    src/external/bsd/dhcpcd/dist/script.c
cvs rdiff -u -r1.24 -r1.25 src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/if-options.c
cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/if.c
cvs rdiff -u -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/ipv4.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/ipv4.h
cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/ipv4ll.c
cvs rdiff -u -r1.6 -r1.7 \
    src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf

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.14 src/external/bsd/dhcpcd/dist/arp.c:1.15
--- src/external/bsd/dhcpcd/dist/arp.c:1.14	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/arp.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: arp.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: arp.c,v 1.15 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -382,33 +382,33 @@ arp_free(struct arp_state *astate)
 	}
 }
 
-void
-arp_free_but(struct arp_state *astate)
+static void
+arp_free_but1(struct interface *ifp, struct arp_state *astate)
 {
 	struct iarp_state *state;
-	struct arp_state *p, *n;
 
-	state = ARP_STATE(astate->iface);
-	TAILQ_FOREACH_SAFE(p, &state->arp_states, next, n) {
-		if (p != astate)
-			arp_free(p);
+	if ((state = ARP_STATE(ifp)) != NULL) {
+		struct arp_state *p, *n;
+
+		TAILQ_FOREACH_SAFE(p, &state->arp_states, next, n) {
+			if (p != astate)
+				arp_free(p);
+		}
 	}
 }
 
 void
+arp_free_but(struct arp_state *astate)
+{
+
+	arp_free_but1(astate->iface, astate);
+}
+
+void
 arp_close(struct interface *ifp)
 {
-	struct iarp_state *state;
-	struct arp_state *astate;
 
-	/* Freeing the last state will also free the main state,
-	 * so test for both. */
-	for (;;) {
-		if ((state = ARP_STATE(ifp)) == NULL ||
-		    (astate = TAILQ_FIRST(&state->arp_states)) == NULL)
-			break;
-		arp_free(astate);
-	}
+	arp_free_but1(ifp, NULL);
 }
 
 void
Index: src/external/bsd/dhcpcd/dist/common.c
diff -u src/external/bsd/dhcpcd/dist/common.c:1.14 src/external/bsd/dhcpcd/dist/common.c:1.15
--- src/external/bsd/dhcpcd/dist/common.c:1.14	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/common.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: common.c,v 1.14 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: common.c,v 1.15 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -56,29 +56,6 @@
 #  define _PATH_DEVNULL "/dev/null"
 #endif
 
-const char *
-get_hostname(char *buf, size_t buflen, int short_hostname)
-{
-	char *p;
-
-	if (gethostname(buf, buflen) != 0)
-		return NULL;
-	buf[buflen - 1] = '\0';
-	if (strcmp(buf, "(none)") == 0 ||
-	    strcmp(buf, "localhost") == 0 ||
-	    strncmp(buf, "localhost.", strlen("localhost.")) == 0 ||
-	    buf[0] == '.')
-		return NULL;
-
-	if (short_hostname) {
-		p = strchr(buf, '.');
-		if (p)
-			*p = '\0';
-	}
-
-	return buf;
-}
-
 #if USE_LOGFILE
 void
 logger_open(struct dhcpcd_ctx *ctx)
@@ -115,6 +92,21 @@ logger_close(struct dhcpcd_ctx *ctx)
 	closelog();
 }
 
+/*
+ * NetBSD's gcc has been modified to check for the non standard %m in printf
+ * like functions and warn noisily about it that they should be marked as
+ * syslog like instead.
+ * This is all well and good, but our logger also goes via vfprintf and
+ * when marked as a sysloglike funcion, gcc will then warn us that the
+ * function should be printflike instead!
+ * This creates an infinte loop of gcc warnings.
+ * Until NetBSD solves this issue, we have to disable a gcc diagnostic
+ * for our fully standards compliant code in the logger function.
+ */
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-format-attribute"
+#endif
 void
 logger(struct dhcpcd_ctx *ctx, int pri, const char *fmt, ...)
 {
@@ -124,9 +116,6 @@ logger(struct dhcpcd_ctx *ctx, int pri, 
 	char fmt_cpy[1024];
 #endif
 
-	if (pri >= LOG_DEBUG && ctx && !(ctx->options & DHCPCD_DEBUG))
-		return;
-
 	serrno = errno;
 	va_start(va, fmt);
 
@@ -147,8 +136,18 @@ logger(struct dhcpcd_ctx *ctx, int pri, 
 				fmt_left -= 2;
 				p++;
 			} else if (p[0] == '%' && p[1] == 'm') {
-				if (serr == NULL)
+				if (serr == NULL) {
+					/* strerror_r isn't portable.
+					 * strerror_l isn't widely found
+					 * and also problematic to use.
+					 * Also, if strerror_l exists then
+					 * strerror could easily be made
+					 * treadsafe in the same libc.
+					 * dhcpcd is only threaded in RTEMS
+					 * where strerror is threadsafe,
+					 * so this should be fine. */
 					serr = strerror(serrno);
+				}
 				fmt_wrote = strlcpy(fp, serr, fmt_left);
 				if (fmt_wrote > fmt_left)
 					break;
@@ -165,44 +164,62 @@ logger(struct dhcpcd_ctx *ctx, int pri, 
 		*fp++ = '\0';
 		fmt = fmt_cpy;
 	}
-
 #endif
 
-	if (ctx == NULL || !(ctx->options & DHCPCD_QUIET)) {
+	if ((ctx == NULL || !(ctx->options & DHCPCD_QUIET)) &&
+	    (pri < LOG_DEBUG || (ctx->options & DHCPCD_DEBUG)))
+	{
 		va_list vac;
 
 		va_copy(vac, va);
+#ifdef HAVE_PRINTF_M
+		errno = serrno;
+#endif
 		vfprintf(pri <= LOG_ERR ? stderr : stdout, fmt, vac);
 		fputc('\n', pri <= LOG_ERR ? stderr : stdout);
 		va_end(vac);
 	}
 
-#ifdef HAVE_PRINTF_M
-	errno = serrno;
-#endif
+	/* Don't send to syslog if dumping leases or testing */
+	if (ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))
+		goto out;
+
 	if (ctx && ctx->log_fd != -1) {
-		struct timeval tv;
-		char buf[32];
+		if (pri < LOG_DEBUG || (ctx->options & DHCPCD_DEBUG)) {
+			struct timeval tv;
+			char buf[32];
+
+			/* Write the time, syslog style. month day time - */
+			if (gettimeofday(&tv, NULL) != -1) {
+				time_t now;
+				struct tm tmnow;
+
+				tzset();
+				now = tv.tv_sec;
+				localtime_r(&now, &tmnow);
+				strftime(buf, sizeof(buf), "%b %d %T ", &tmnow);
+				dprintf(ctx->log_fd, "%s", buf);
+			}
 
-		/* Write the time, syslog style. month day time - */
-		if (gettimeofday(&tv, NULL) != -1) {
-			time_t now;
-			struct tm tmnow;
-
-			tzset();
-			now = tv.tv_sec;
-			localtime_r(&now, &tmnow);
-			strftime(buf, sizeof(buf), "%b %d %T ", &tmnow);
-			dprintf(ctx->log_fd, "%s", buf);
+#ifdef HAVE_PRINTF_M
+			errno = serrno;
+#endif
+			vdprintf(ctx->log_fd, fmt, va);
+			dprintf(ctx->log_fd, "\n");
 		}
-
-		vdprintf(ctx->log_fd, fmt, va);
-		dprintf(ctx->log_fd, "\n");
-	} else
+	} else {
+#ifdef HAVE_PRINTF_M
+		errno = serrno;
+#endif
 		vsyslog(pri, fmt, va);
+	}
+out:
 	va_end(va);
 }
 #endif
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
+#pragma GCC diagnostic pop
+#endif
 
 ssize_t
 setvar(struct dhcpcd_ctx *ctx,
Index: src/external/bsd/dhcpcd/dist/if-options.h
diff -u src/external/bsd/dhcpcd/dist/if-options.h:1.14 src/external/bsd/dhcpcd/dist/if-options.h:1.15
--- src/external/bsd/dhcpcd/dist/if-options.h:1.14	Fri Sep  4 12:25:01 2015
+++ src/external/bsd/dhcpcd/dist/if-options.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: if-options.h,v 1.14 2015/09/04 12:25:01 roy Exp $ */
+/* $NetBSD: if-options.h,v 1.15 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -44,7 +44,7 @@
 /* Don't set any optional arguments here so we retain POSIX
  * compatibility with getopt */
 #define IF_OPTS "46bc:de:f:gh:i:j:kl:m:no:pqr:s:t:u:v:wxy:z:" \
-		"ABC:DEF:GHI:JKLMO:Q:S:TUVW:X:Z:"
+		"ABC:DEF:GHI:JKLMNO:Q:S:TUVW:X:Z:"
 
 #define DEFAULT_TIMEOUT		30
 #define DEFAULT_REBOOT		5
@@ -107,7 +107,7 @@
 #define DHCPCD_DHCP			(1ULL << 49)
 #define DHCPCD_DHCP6			(1ULL << 50)
 #define DHCPCD_IF_UP			(1ULL << 51)
-// unassigned				(1ULL << 52)
+#define DHCPCD_INFORM6			(1ULL << 52)
 // unassinged				(1ULL << 53)
 #define DHCPCD_IPV6RA_AUTOCONF		(1ULL << 54)
 #define DHCPCD_ROUTER_HOST_ROUTE_WARNED	(1ULL << 55)
Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.14 src/external/bsd/dhcpcd/dist/ipv6.c:1.15
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.14	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/ipv6.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.14 2015/08/21 10:39:00 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.15 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -38,6 +38,16 @@
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 
+#ifdef BSD
+/* Purely for the ND6_IFF_AUTO_LINKLOCAL #define which is solely used
+ * to generate our CAN_ADD_LLADDR #define. */
+#  ifdef __FreeBSD__
+#    include <net/if_var.h>
+#  endif
+#  include <netinet6/in6_var.h>
+#  include <netinet6/nd6.h>
+#endif
+
 #include <errno.h>
 #include <ifaddrs.h>
 #include <inttypes.h>
@@ -105,6 +115,16 @@
 #  endif
 #endif
 
+#if defined(HAVE_IN6_ADDR_GEN_MODE_NONE) || defined(ND6_IFF_AUTO_LINKLOCAL)
+/* 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)
+#else
+#define CAN_ADD_LLADDR(ifp) (1)
+#endif
 
 #ifdef IPV6_MANAGETEMPADDR
 static void ipv6_regentempifid(void *);
@@ -885,10 +905,12 @@ ipv6_freedrop_addrs(struct ipv6_addrhead
 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
 		{
-			if (drop == 2)
-				TAILQ_REMOVE(addrs, ap, next);
 			/* Don't drop link-local addresses. */
-			if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
+			if (!(IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
+			    CAN_ADD_LLADDR(ap->iface)))
+			{
+				if (drop == 2)
+					TAILQ_REMOVE(addrs, ap, next);
 				/* Find the same address somewhere else */
 				apf = ipv6_findaddr(ap->iface->ctx, &ap->addr,
 				    0);
@@ -903,9 +925,9 @@ ipv6_freedrop_addrs(struct ipv6_addrhead
 						    &now);
 					ipv6_addaddr(apf, &now);
 				}
+				if (drop == 2)
+					ipv6_freeaddr(ap);
 			}
-			if (drop == 2)
-				ipv6_freeaddr(ap);
 		}
 		if (drop != 2)
 			ipv6_freeaddr(ap);
@@ -948,11 +970,13 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
 	struct ll_callback *cb;
 
 #if 0
-	char buf[INET6_ADDRSTRLEN];
-	inet_ntop(AF_INET6, &addr->s6_addr,
-	    buf, INET6_ADDRSTRLEN);
-	logger(ctx, LOG_DEBUG, "%s: cmd %d addr %s flags %d",
-	    ifname, cmd, buf, flags);
+	char dbuf[INET6_ADDRSTRLEN];
+	const char *dbp;
+
+	dbp = inet_ntop(AF_INET6, &addr->s6_addr,
+	    dbuf, INET6_ADDRSTRLEN);
+	logger(ctx, LOG_INFO, "%s: cmd %d addr %s flags %d",
+	    ifname, cmd, dbp, flags);
 #endif
 
 	if (ifs == NULL)
@@ -1280,7 +1304,9 @@ ipv6_start(struct interface *ifp)
 	} else
 		ap = NULL;
 
-	if (ap == NULL && ipv6_addlinklocal(ifp) == -1)
+	if (ap == NULL &&
+	    CAN_ADD_LLADDR(ifp) &&
+	    ipv6_addlinklocal(ifp) == -1)
 		return -1;
 
 	/* Load existing routes */
@@ -1302,7 +1328,7 @@ ipv6_freedrop(struct interface *ifp, int
 
 	ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL);
 
-	/* Becuase we need to cache the addresses we don't control,
+	/* Because we need to cache the addresses we don't control,
 	 * we only free the state on when NOT dropping addresses. */
 	if (drop == 0) {
 		while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
@@ -1898,16 +1924,21 @@ nc_route(struct rt6 *ort, struct rt6 *nr
 #endif
 
 	if (change) {
-		if (if_route6(RTM_CHANGE, nrt) == 0)
+		if (if_route6(RTM_CHANGE, nrt) != -1)
 			return 0;
 		if (errno != ESRCH)
 			logger(nrt->iface->ctx, LOG_ERR, "if_route6 (CHG): %m");
 	}
 
+	/* If the old route does not have an interface, give it the
+	 * interface of the new route for context. */
+	if (ort && ort->iface == NULL)
+		ort->iface = nrt->iface;
+
 #ifdef HAVE_ROUTE_METRIC
 	/* With route metrics, we can safely add the new route before
 	 * deleting the old route. */
-	if (if_route6(RTM_ADD, nrt) == 0) {
+	if (if_route6(RTM_ADD, nrt) != -1) {
 		if (ort && if_route6(RTM_DELETE, ort) == -1 &&
 		    errno != ESRCH)
 			logger(nrt->iface->ctx, LOG_ERR, "if_route6 (DEL): %m");
@@ -1924,7 +1955,7 @@ nc_route(struct rt6 *ort, struct rt6 *nr
 	 * adding the new one. */
 	if (ort && if_route6(RTM_DELETE, ort) == -1 && errno != ESRCH)
 		logger(nrt->iface->ctx, LOG_ERR, "if_route6: %m");
-	if (if_route6(RTM_ADD, nrt) == 0)
+	if (if_route6(RTM_ADD, nrt) != -1)
 		return 0;
 #ifdef HAVE_ROUTE_METRIC
 logerr:
@@ -1939,8 +1970,8 @@ d_route(struct rt6 *rt)
 	int retval;
 
 	desc_route("deleting", rt);
-	retval = if_route6(RTM_DELETE, rt);
-	if (retval != 0 && errno != ENOENT && errno != ESRCH)
+	retval = if_route6(RTM_DELETE, rt) == -1 ? -1 : 0;
+	if (retval == -1 && errno != ENOENT && errno != ESRCH)
 		logger(rt->iface->ctx, LOG_ERR,
 		    "%s: if_delroute6: %m", rt->iface->name);
 	return retval;
@@ -2127,7 +2158,8 @@ ipv6_buildroutes(struct dhcpcd_ctx *ctx)
 			    rt->metric != or->metric ||
 #endif
 		//	    or->src.s_addr != ifp->addr.s_addr ||
-			    !IN6_ARE_ADDR_EQUAL(&rt->gate, &or->gate))
+			    !IN6_ARE_ADDR_EQUAL(&or->gate, &rt->gate) ||
+			    or->mtu != rt->mtu)
 			{
 				if (c_route(or, rt) != 0)
 					continue;
Index: src/external/bsd/dhcpcd/dist/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.14 src/external/bsd/dhcpcd/dist/ipv6.h:1.15
--- src/external/bsd/dhcpcd/dist/ipv6.h:1.14	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/ipv6.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.14 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.15 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -94,15 +94,29 @@
 #  undef IPV6_POLLADDRFLAG
 #endif
 
-/* Linux-3.18 can manage temporary addresses even with RA
- * processing disabled. */
-//#undef IFA_F_MANAGETEMPADDR
-#if defined(__linux__) && defined(IFA_F_MANAGETEMPADDR)
+/*
+ * If dhcpcd handles RA processing instead of the kernel, the kernel needs
+ * to either allow userland to set temporary addresses or mark an address
+ * for the kernel to manage temporary addresses from.
+ * If the kernel allows the former, a global #define is needed, otherwise
+ * the address marking will be handled in the platform specific address handler.
+ *
+ * Some BSDs do not allow userland to set temporary addresses.
+ * Linux-3.18 allows the marking of addresses from which to manage temp addrs.
+ */
+#if defined(BSD) && defined(IN6_IFF_TEMPORARY)
 #define IPV6_MANAGETEMPADDR
 #endif
 
-/* Some BSDs do not allow userland to set temporary addresses. */
-#if defined(BSD) && defined(IN6_IFF_TEMPORARY)
+/*
+ * You could enable IPV6_MANAGETEMPADDR anyway and disable the platform
+ * specific address marking to test dhcpcd's temporary address handling as well,
+ * but this will not affect source address selection so is of very limited use.
+ */
+#if 0
+/* Pretend we have an old Linux kernel. */
+#undef IFA_F_MANAGETEMPADDR
+/* Enable dhcpcd handling temporary addresses. */
 #define IPV6_MANAGETEMPADDR
 #endif
 

Index: src/external/bsd/dhcpcd/dist/common.h
diff -u src/external/bsd/dhcpcd/dist/common.h:1.11 src/external/bsd/dhcpcd/dist/common.h:1.12
--- src/external/bsd/dhcpcd/dist/common.h:1.11	Wed Oct 14 15:58:08 2015
+++ src/external/bsd/dhcpcd/dist/common.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: common.h,v 1.11 2015/10/14 15:58:08 christos Exp $ */
+/* $NetBSD: common.h,v 1.12 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -115,25 +115,19 @@
 #endif
 
 #if __GNUC__ > 2 || defined(__INTEL_COMPILER)
-# ifndef __dead
-#  define __dead __attribute__((__noreturn__))
-# endif
 # ifndef __packed
-#  define __packed   __attribute__((__packed__))
-# endif
-# ifndef __syslog_attribute__
-#  define __syslog__ __printf__
+#  define __packed __attribute__((__packed__))
 # endif
 # ifndef __sysloglike
-#  define __sysloglike(a, b) __attribute__((__format__(__syslog__, a, b)))
+#  ifndef __syslog_attribute_
+#    define __syslog__ __printf__
+#  endif
+#  define __sysloglike(a, b) __attribute__((format(__syslog__, a, b)))
 # endif
 # ifndef __unused
-#  define __unused   __attribute__((__unused__))
+#  define __unused __attribute__((__unused__))
 # endif
 #else
-# ifndef __dead
-#  define __dead
-# endif
 # ifndef __packed
 #  define __packed
 # endif
@@ -146,7 +140,7 @@
 #endif
 
 #ifndef __arraycount
-#define __arraycount(__x)       (sizeof(__x) / sizeof(__x[0]))
+#  define __arraycount(__x)       (sizeof(__x) / sizeof(__x[0]))
 #endif
 
 /* We don't really need this as our supported systems define __restrict
@@ -162,7 +156,6 @@
 #endif
 
 void get_line_free(void);
-const char *get_hostname(char *, size_t, int);
 extern int clock_monotonic;
 int get_monotonic(struct timespec *);
 
@@ -177,7 +170,7 @@ int get_monotonic(struct timespec *);
 #if USE_LOGFILE
 void logger_open(struct dhcpcd_ctx *);
 #define logger_mask(ctx, lvl) setlogmask((lvl))
-__sysloglike(3, 4) void logger(struct dhcpcd_ctx *, int, const char *, ...);
+void logger(struct dhcpcd_ctx *, int, const char *, ...) __sysloglike(3, 4);
 void logger_close(struct dhcpcd_ctx *);
 #else
 #define logger_open(ctx) openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON)
Index: src/external/bsd/dhcpcd/dist/dhcp.h
diff -u src/external/bsd/dhcpcd/dist/dhcp.h:1.11 src/external/bsd/dhcpcd/dist/dhcp.h:1.12
--- src/external/bsd/dhcpcd/dist/dhcp.h:1.11	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/dhcp.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp.h,v 1.11 2015/08/21 10:39:00 roy Exp $ */
+/* $NetBSD: dhcp.h,v 1.12 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -239,7 +239,6 @@ struct dhcp_state {
 #ifdef INET
 char *decode_rfc3361(const uint8_t *, size_t);
 ssize_t decode_rfc3442(char *, size_t, const uint8_t *p, size_t);
-ssize_t decode_rfc5969(char *, size_t, const uint8_t *p, size_t);
 
 void dhcp_printoptions(const struct dhcpcd_ctx *,
     const struct dhcp_opt *, size_t);
@@ -269,6 +268,7 @@ void dhcp_start(struct interface *);
 void dhcp_abort(struct interface *);
 void dhcp_discover(void *);
 void dhcp_inform(struct interface *);
+void dhcp_renew(struct interface *);
 void dhcp_bind(struct interface *);
 void dhcp_reboot_newopts(struct interface *, unsigned long long);
 void dhcp_close(struct interface *);
@@ -278,6 +278,7 @@ int dhcp_dump(struct interface *);
 #define dhcp_drop(a, b) {}
 #define dhcp_start(a) {}
 #define dhcp_abort(a) {}
+#define dhcp_renew(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/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.21 src/external/bsd/dhcpcd/dist/defs.h:1.22
--- src/external/bsd/dhcpcd/dist/defs.h:1.21	Fri Sep  4 12:25:01 2015
+++ src/external/bsd/dhcpcd/dist/defs.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.21 2015/09/04 12:25:01 roy Exp $ */
+/* $NetBSD: defs.h,v 1.22 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
 #define CONFIG_H
 
 #define PACKAGE			"dhcpcd"
-#define VERSION			"6.9.3"
+#define VERSION			"6.9.4"
 
 #ifndef CONFIG
 # define CONFIG			SYSCONFDIR "/" PACKAGE ".conf"

Index: src/external/bsd/dhcpcd/dist/dhcp-common.c
diff -u src/external/bsd/dhcpcd/dist/dhcp-common.c:1.10 src/external/bsd/dhcpcd/dist/dhcp-common.c:1.11
--- src/external/bsd/dhcpcd/dist/dhcp-common.c:1.10	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcp-common.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp-common.c,v 1.10 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: dhcp-common.c,v 1.11 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -55,6 +55,36 @@
 #define NS_MAXLABEL MAXLABEL
 #endif
 
+const char *
+dhcp_get_hostname(char *buf, size_t buf_len, const struct if_options *ifo)
+{
+
+	if (ifo->hostname[0] == '\0') {
+		if (gethostname(buf, buf_len) != 0)
+			return NULL;
+		buf[buf_len - 1] = '\0';
+	} else
+		strlcpy(buf, ifo->hostname, sizeof(buf));
+
+	/* Deny sending of these local hostnames */
+	if (strcmp(buf, "(none)") == 0 ||
+	    strcmp(buf, "localhost") == 0 ||
+	    strncmp(buf, "localhost.", strlen("localhost.")) == 0 ||
+	    buf[0] == '.')
+		return NULL;
+
+	/* Shorten the hostname if required */
+	if (ifo->options & DHCPCD_HOSTNAME_SHORT) {
+		char *hp;
+
+		hp = strchr(buf, '.');
+		if (hp != NULL)
+			*hp = '\0';
+	}
+
+	return buf;
+}
+
 void
 dhcp_print_option_encoding(const struct dhcp_opt *opt, int cols)
 {
@@ -106,8 +136,6 @@ dhcp_print_option_encoding(const struct 
 		printf(" rfc3361");
 	if (opt->type & RFC3442)
 		printf(" rfc3442");
-	if (opt->type & RFC5969)
-		printf(" rfc5969");
 	if (opt->type & REQUEST)
 		printf(" request");
 	if (opt->type & NOREQ)
@@ -562,7 +590,7 @@ dhcp_optlen(const struct dhcp_opt *opt, 
 	size_t sz;
 
 	if (opt->type == 0 ||
-	    opt->type & (STRING | BINHEX | RFC3442 | RFC5969))
+	    opt->type & (STRING | BINHEX | RFC3442))
 	{
 		if (opt->len) {
 			if ((size_t)opt->len > dl)
@@ -642,9 +670,6 @@ print_option(char *s, size_t len, const 
 
 	if (opt->type & RFC3442)
 		return decode_rfc3442(s, len, data, dl);
-
-	if (opt->type & RFC5969)
-		return decode_rfc5969(s, len, data, dl);
 #endif
 
 	if (opt->type & STRING)
@@ -906,9 +931,10 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, c
 		if (eo == -1) {
 			if (env == NULL)
 				logger(ctx, LOG_ERR,
-				    "%s: %s: malformed embedded option %d:%d",
+				    "%s: %s: malformed embedded option"
+				    " %d:%d/%zu",
 				    ifname, __func__, opt->option,
-				    eopt->option);
+				    eopt->option, i);
 			goto out;
 		}
 		if (eo == 0) {
@@ -916,15 +942,13 @@ dhcp_envoption(struct dhcpcd_ctx *ctx, c
 			 * data for it.
 			 * This may not be an error as some options like
 			 * DHCP FQDN in RFC4702 have a string as the last
-			 * option which is optional.
-			 * FIXME: Add an flag to the options to indicate
-			 * wether this is allowable or not. */
+			 * option which is optional. */
 			if (env == NULL &&
-			    (ol != 0 || i + 1 < opt->embopts_len))
+			    (ol != 0 || !(eopt->type & OPTIONAL)))
 				logger(ctx, LOG_ERR,
-				    "%s: %s: malformed embedded option %d:%d",
+				    "%s: %s: missing embedded option %d:%d/%zu",
 				    ifname, __func__, opt->option,
-				    eopt->option);
+				    eopt->option, i);
 			goto out;
 		}
 		/* Use the option prefix if the embedded option
Index: src/external/bsd/dhcpcd/dist/dhcp-common.h
diff -u src/external/bsd/dhcpcd/dist/dhcp-common.h:1.10 src/external/bsd/dhcpcd/dist/dhcp-common.h:1.11
--- src/external/bsd/dhcpcd/dist/dhcp-common.h:1.10	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcp-common.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp-common.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: dhcp-common.h,v 1.11 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -54,7 +54,7 @@
 #define RFC3361		(1 << 9)
 #define RFC1035		(1 << 10)
 #define RFC3442		(1 << 11)
-#define RFC5969		(1 << 12)
+#define OPTIONAL	(1 << 12)
 #define ADDRIPV6	(1 << 13)
 #define BINHEX		(1 << 14)
 #define FLAG		(1 << 15)
@@ -90,6 +90,7 @@ struct dhcp_opt {
 	size_t encopts_len;
 };
 
+const char *dhcp_get_hostname(char *, size_t, const struct if_options *);
 struct dhcp_opt *vivso_find(uint32_t, const void *);
 
 ssize_t dhcp_vendor(char *, size_t);
Index: src/external/bsd/dhcpcd/dist/dhcp6.h
diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.10 src/external/bsd/dhcpcd/dist/dhcp6.h:1.11
--- src/external/bsd/dhcpcd/dist/dhcp6.h:1.10	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcp6.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dhcp6.h,v 1.10 2015/07/09 10:15:34 roy Exp $ */
+/* $NetBSD: dhcp6.h,v 1.11 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -243,6 +243,7 @@ size_t dhcp6_find_delegates(struct inter
 int dhcp6_has_public_addr(const struct interface *);
 int dhcp6_start(struct interface *, enum DH6S);
 void dhcp6_reboot(struct interface *);
+void dhcp6_renew(struct interface *);
 ssize_t dhcp6_env(char **, const char *, const struct interface *,
     const struct dhcp6_message *, size_t);
 void dhcp6_free(struct interface *);
Index: src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.10 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.11
--- src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c:1.10	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.10 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.11 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * DO NOT EDIT!
@@ -125,7 +125,7 @@ const char * const dhcpcd_embedded_conf[
 "embed bitflags=0000NEOS flags",
 "embed byte rcode1",
 "embed byte rcode2",
-"embed domain fqdn",
+"embed optional domain fqdn",
 "define 85 array ipaddress nds_servers",
 "define 86 raw nds_tree_name",
 "define 87 raw nds_context",
@@ -195,7 +195,11 @@ const char * const dhcpcd_embedded_conf[
 "define 209 string config_file",
 "define 210 string path_prefix",
 "define 211 uint32 reboot_time",
-"define 212 rfc5969 sixrd",
+"define 212 embed sixrd",
+"embed byte mask_len",
+"embed byte prefix_len",
+"embed ip6address prefix",
+"embed array ipaddress brip_address",
 "define 213 domain access_domain",
 "define 221 encap vss",
 "encap 0 string nvt",

Index: src/external/bsd/dhcpcd/dist/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.35 src/external/bsd/dhcpcd/dist/dhcp.c:1.36
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.35	Fri Sep  4 12:25:01 2015
+++ src/external/bsd/dhcpcd/dist/dhcp.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.35 2015/09/04 12:25:01 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.36 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -43,6 +43,7 @@
 #include <netinet/udp.h>
 #undef __FAVOR_BSD
 
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -483,74 +484,6 @@ decode_rfc3361(const uint8_t *data, size
 	return sip;
 }
 
-/* Decode an RFC5969 6rd order option into a space
- * separated string. Returns length of string (including
- * terminating zero) or zero on error. */
-ssize_t
-decode_rfc5969(char *out, size_t len, const uint8_t *p, size_t pl)
-{
-	uint8_t ipv4masklen, ipv6prefixlen;
-	uint8_t ipv6prefix[16];
-	uint8_t br[4];
-	int i;
-	ssize_t b, bytes = 0;
-
-	if (pl < 22) {
-		errno = EINVAL;
-		return 0;
-	}
-
-	ipv4masklen = *p++;
-	pl--;
-	ipv6prefixlen = *p++;
-	pl--;
-
-	for (i = 0; i < 16; i++) {
-		ipv6prefix[i] = *p++;
-		pl--;
-	}
-	if (out) {
-		b= snprintf(out, len,
-		    "%d %d "
-		    "%02x%02x:%02x%02x:"
-		    "%02x%02x:%02x%02x:"
-		    "%02x%02x:%02x%02x:"
-		    "%02x%02x:%02x%02x",
-		    ipv4masklen, ipv6prefixlen,
-		    ipv6prefix[0], ipv6prefix[1], ipv6prefix[2], ipv6prefix[3],
-		    ipv6prefix[4], ipv6prefix[5], ipv6prefix[6], ipv6prefix[7],
-		    ipv6prefix[8], ipv6prefix[9], ipv6prefix[10],ipv6prefix[11],
-		    ipv6prefix[12],ipv6prefix[13],ipv6prefix[14], ipv6prefix[15]
-		);
-
-		len -= (size_t)b;
-		out += b;
-		bytes += b;
-	} else {
-		bytes += 16 * 2 + 8 + 2 + 1 + 2;
-	}
-
-	while (pl >= 4) {
-		br[0] = *p++;
-		br[1] = *p++;
-		br[2] = *p++;
-		br[3] = *p++;
-		pl -= 4;
-
-		if (out) {
-			b= snprintf(out, len, " %d.%d.%d.%d",
-			    br[0], br[1], br[2], br[3]);
-			len -= (size_t)b;
-			out += b;
-			bytes += b;
-		} else {
-			bytes += (4 * 4);
-		}
-	}
-
-	return bytes;
-}
-
 static char *
 get_option_string(struct dhcpcd_ctx *ctx,
     const struct dhcp_message *dhcp, uint8_t option)
@@ -681,8 +614,9 @@ get_option_routes(struct interface *ifp,
 			{
 				route->gate.s_addr = htonl(INADDR_ANY);
 				route->net.s_addr = htonl(INADDR_BROADCAST);
-			}
-			route->net.s_addr = route_netmask(route->dest.s_addr);
+			} else
+				route->net.s_addr =
+				    route_netmask(route->dest.s_addr);
 			TAILQ_INSERT_TAIL(routes, route, next);
 		}
 	}
@@ -953,11 +887,7 @@ make_message(struct dhcp_message **messa
 			}
 		}
 
-		if (ifo->hostname[0] == '\0')
-			hostname = get_hostname(hbuf, sizeof(hbuf),
-			    ifo->options & DHCPCD_HOSTNAME_SHORT ? 1 : 0);
-		else
-			hostname = ifo->hostname;
+		hostname = dhcp_get_hostname(hbuf, sizeof(hbuf), ifo);
 
 		/*
 		 * RFC4702 3.1 States that if we send the Client FQDN option
@@ -1200,15 +1130,21 @@ read_lease(struct interface *ifp)
 	uint8_t type;
 	size_t auth_len;
 
-	fd = open(state->leasefile, O_RDONLY);
+	if (state->leasefile[0] == '\0')
+		fd = fileno(stdin);
+	else
+		fd = open(state->leasefile, O_RDONLY);
 	if (fd == -1) {
 		if (errno != ENOENT)
 			logger(ifp->ctx, LOG_ERR, "%s: open `%s': %m",
 			    ifp->name, state->leasefile);
 		return NULL;
 	}
-	logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
-	    ifp->name, state->leasefile);
+	if (state->leasefile[0] == '\0')
+		logger(ifp->ctx, LOG_DEBUG, "reading standard input");
+	else
+		logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
+		    ifp->name, state->leasefile);
 	dhcp = calloc(1, sizeof(*dhcp));
 	if (dhcp == NULL) {
 		close(fd);
@@ -1221,6 +1157,9 @@ read_lease(struct interface *ifp)
 		return NULL;
 	}
 
+	if (ifp->ctx->options & DHCPCD_DUMPLEASE)
+		return dhcp;
+
 	/* We may have found a BOOTP server */
 	if (get_option_uint8(ifp->ctx, &type, dhcp, DHO_MESSAGETYPE) == -1)
 		type = 0;
@@ -1462,6 +1401,8 @@ get_lease(struct dhcpcd_ctx *ctx,
     struct dhcp_lease *lease, const struct dhcp_message *dhcp)
 {
 
+	assert(dhcp != NULL);
+
 	lease->cookie = dhcp->cookie;
 	/* BOOTP does not set yiaddr for replies when ciaddr is set. */
 	if (dhcp->yiaddr)
@@ -1897,23 +1838,39 @@ dhcp_decline(struct interface *ifp)
 }
 
 static void
-dhcp_renew(void *arg)
+dhcp_startrenew(void *arg)
 {
 	struct interface *ifp = arg;
-	struct dhcp_state *state = D_STATE(ifp);
-	struct dhcp_lease *lease = &state->lease;
+	struct dhcp_state *state;
+	struct dhcp_lease *lease;
 
+	if ((state = D_STATE(ifp)) == NULL)
+		return;
+
+	/* Only renew in the bound or renew states */
+	if (state->state != DHS_BOUND &&
+	    state->state != DHS_RENEW)
+		return;
+
+	/* Remove the timeout as the renew may have been forced. */
+	eloop_timeout_delete(ifp->ctx->eloop, dhcp_startrenew, ifp);
+
+	lease = &state->lease;
 	logger(ifp->ctx, LOG_DEBUG, "%s: renewing lease of %s",
 	    ifp->name, inet_ntoa(lease->addr));
-	logger(ifp->ctx, LOG_DEBUG, "%s: rebind in %"PRIu32" seconds,"
-	    " expire in %"PRIu32" seconds",
-	    ifp->name, lease->rebindtime - lease->renewaltime,
-	    lease->leasetime - lease->renewaltime);
 	state->state = DHS_RENEW;
 	state->xid = dhcp_xid(ifp);
+	state->interval = 0;
 	send_renew(ifp);
 }
 
+void
+dhcp_renew(struct interface *ifp)
+{
+
+	dhcp_startrenew(ifp);
+}
+
 static void
 dhcp_arp_announced(struct arp_state *astate)
 {
@@ -1935,6 +1892,7 @@ dhcp_rebind(void *arg)
 	state->state = DHS_REBIND;
 	eloop_timeout_delete(ifp->ctx->eloop, send_renew, ifp);
 	state->lease.server.s_addr = 0;
+	state->interval = 0;
 	ifp->options->options &= ~(DHCPCD_CSR_WARNED |
 	    DHCPCD_ROUTER_HOST_ROUTE_WARNED);
 	send_rebind(ifp);
@@ -1963,11 +1921,27 @@ dhcp_arp_probed(struct arp_state *astate
 
 	logger(astate->iface->ctx, LOG_DEBUG, "%s: DAD completed for %s",
 	    astate->iface->name, inet_ntoa(astate->addr));
-	dhcp_bind(astate->iface);
+	if (state->state != DHS_INFORM)
+		dhcp_bind(astate->iface);
+#ifndef IN_IFF_TENTATIVE
+	else {
+		struct dhcp_message *oldnew;
+
+		oldnew = state->new;
+		state->new = state->offer;
+		get_lease(astate->iface->ctx, &state->lease, state->new);
+		ipv4_applyaddr(astate->iface);
+		state->new = oldnew;
+	}
+#endif
+		
 	arp_announce(astate);
 
 	/* Stop IPv4LL now we have a working DHCP address */
 	ipv4ll_drop(astate->iface);
+
+	if (ifo->options & DHCPCD_INFORM)
+		dhcp_inform(astate->iface);
 }
 
 static void
@@ -2048,10 +2022,14 @@ dhcp_bind(struct interface *ifp)
 	struct dhcp_lease *lease = &state->lease;
 
 	state->reason = NULL;
-	free(state->old);
-	state->old = state->new;
-	state->new = state->offer;
-	state->offer = NULL;
+	/* If we don't have an offer, we are re-binding a lease on preference,
+	 * normally when two interfaces have a lease matching IP addresses. */
+	if (state->offer) {
+		free(state->old);
+		state->old = state->new;
+		state->new = state->offer;
+		state->offer = NULL;
+	}
 	get_lease(ifp->ctx, lease, state->new);
 	if (ifo->options & DHCPCD_STATIC) {
 		logger(ifp->ctx, LOG_INFO, "%s: using static address %s/%d",
@@ -2060,10 +2038,6 @@ dhcp_bind(struct interface *ifp)
 		lease->leasetime = ~0U;
 		state->reason = "STATIC";
 	} else if (ifo->options & DHCPCD_INFORM) {
-		if (ifo->req_addr.s_addr != 0)
-			lease->addr.s_addr = ifo->req_addr.s_addr;
-		else
-			lease->addr.s_addr = state->addr.s_addr;
 		logger(ifp->ctx, LOG_INFO, "%s: received approval for %s",
 		    ifp->name, inet_ntoa(lease->addr));
 		lease->leasetime = ~0U;
@@ -2123,7 +2097,8 @@ dhcp_bind(struct interface *ifp)
 	if (state->reason == NULL) {
 		if (state->old && !(state->added & STATE_FAKE)) {
 			if (state->old->yiaddr == state->new->yiaddr &&
-			    lease->server.s_addr)
+			    lease->server.s_addr &&
+			    state->state != DHS_REBIND)
 				state->reason = "RENEW";
 			else
 				state->reason = "REBIND";
@@ -2136,7 +2111,7 @@ dhcp_bind(struct interface *ifp)
 		lease->renewaltime = lease->rebindtime = lease->leasetime;
 	else {
 		eloop_timeout_add_sec(ifp->ctx->eloop,
-		    (time_t)lease->renewaltime, dhcp_renew, ifp);
+		    (time_t)lease->renewaltime, dhcp_startrenew, ifp);
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    (time_t)lease->rebindtime, dhcp_rebind, ifp);
 		eloop_timeout_add_sec(ifp->ctx->eloop,
@@ -2189,8 +2164,8 @@ dhcp_message_new(const struct in_addr *a
 	return dhcp;
 }
 
-static void
-dhcp_arp_bind(struct interface *ifp)
+static int
+dhcp_arp_address(struct interface *ifp)
 {
 	const struct dhcp_state *state;
 	struct in_addr addr;
@@ -2200,7 +2175,8 @@ dhcp_arp_bind(struct interface *ifp)
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
 	state = D_CSTATE(ifp);
-	addr.s_addr = state->offer->yiaddr;
+	addr.s_addr = state->offer->yiaddr == INADDR_ANY ?
+	    state->offer->ciaddr : state->offer->yiaddr;
 	/* If the interface already has the address configured
 	 * then we can't ARP for duplicate detection. */
 	ia = ipv4_findaddr(ifp->ctx, &addr);
@@ -2221,14 +2197,14 @@ dhcp_arp_bind(struct interface *ifp)
 		} else
 			logger(ifp->ctx, LOG_INFO, "%s: waiting for DAD on %s",
 			    ifp->name, inet_ntoa(addr));
-		return;
+		return 0;
 	}
 #else
 	if (ifp->options->options & DHCPCD_ARP && ia == NULL) {
 		struct dhcp_lease l;
 
 		get_lease(ifp->ctx, &l, state->offer);
-		logger(ifp->ctx, LOG_INFO, "%s: probing static address %s/%d",
+		logger(ifp->ctx, LOG_INFO, "%s: probing address %s/%d",
 		    ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.net));
 		if ((astate = arp_new(ifp, &addr)) != NULL) {
 			astate->probed_cb = dhcp_arp_probed;
@@ -2237,11 +2213,19 @@ dhcp_arp_bind(struct interface *ifp)
 			/* We need to handle DAD. */
 			arp_probe(astate);
 		}
-		return;
+		return 0;
 	}
 #endif
 
-	dhcp_bind(ifp);
+	return 1;
+}
+
+static void
+dhcp_arp_bind(struct interface *ifp)
+{
+
+	if (dhcp_arp_address(ifp) == 1)
+		dhcp_bind(ifp);
 }
 
 static void
@@ -2278,41 +2262,52 @@ dhcp_inform(struct interface *ifp)
 {
 	struct dhcp_state *state;
 	struct if_options *ifo;
-	struct ipv4_addr *ap;
+	struct ipv4_addr *ia;
 
 	state = D_STATE(ifp);
 	ifo = ifp->options;
-	if (ifp->ctx->options & DHCPCD_TEST) {
-		state->addr.s_addr = ifo->req_addr.s_addr;
-		state->net.s_addr = ifo->req_mask.s_addr;
-	} else {
-		if (ifo->req_addr.s_addr == INADDR_ANY) {
-			state = D_STATE(ifp);
-			ap = ipv4_iffindaddr(ifp, NULL, NULL);
-			if (ap == NULL) {
-				logger(ifp->ctx, LOG_INFO,
-				    "%s: waiting for 3rd party to "
-				    "configure IP address",
-				    ifp->name);
+
+	state->state = DHS_INFORM;
+	free(state->offer);
+	state->offer = NULL;
+
+	if (ifo->req_addr.s_addr == INADDR_ANY) {
+		ia = ipv4_iffindaddr(ifp, NULL, NULL);
+		if (ia == NULL) {
+			logger(ifp->ctx, LOG_INFO,
+			    "%s: waiting for 3rd party to configure IP address",
+			    ifp->name);
+			if (!(ifp->ctx->options & DHCPCD_TEST)) {
 				state->reason = "3RDPARTY";
 				script_runreason(ifp, state->reason);
+			}
+			return;
+		}
+	} else {
+		ia = ipv4_iffindaddr(ifp, &ifo->req_addr, &ifo->req_mask);
+		if (ia == NULL) {
+			if (ifp->ctx->options & DHCPCD_TEST) {
+				logger(ifp->ctx, LOG_ERR,
+				    "%s: cannot add IP address in test mode",
+				    ifp->name);
 				return;
 			}
-			state->offer =
-			    dhcp_message_new(&ap->addr, &ap->net);
-		} else
-			state->offer =
-			    dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
-		if (state->offer) {
-			ifo->options |= DHCPCD_STATIC;
-			dhcp_bind(ifp);
-			ifo->options &= ~DHCPCD_STATIC;
+			state->offer = dhcp_message_new(&ifo->req_addr,
+			    &ifo->req_mask);
+			if (dhcp_arp_address(ifp) == 0)
+				return;
+			ia = ipv4_iffindaddr(ifp,
+			    &ifo->req_addr, &ifo->req_mask);
+			assert(ia != NULL);
 		}
 	}
 
-	state->state = DHS_INFORM;
-	state->xid = dhcp_xid(ifp);
-	send_inform(ifp);
+	state->offer = dhcp_message_new(&ia->addr, &ia->net);
+	if (state->offer) {
+		state->xid = dhcp_xid(ifp);
+		get_lease(ifp->ctx, &state->lease, state->offer);
+		send_inform(ifp);
+	}
 }
 
 void
@@ -2406,7 +2401,9 @@ dhcp_drop(struct interface *ifp, const c
 		return;
 	}
 
-	if (ifp->options->options & DHCPCD_RELEASE) {
+	if (ifp->options->options & DHCPCD_RELEASE &&
+	    !(ifp->options->options & DHCPCD_INFORM))
+	{
 		/* Failure to send the release may cause this function to
 		 * re-enter so guard by setting the state. */
 		if (state->state == DHS_RELEASE)
@@ -2627,11 +2624,9 @@ dhcp_handledhcp(struct interface *ifp, s
 		log_dhcp(LOG_ERR, "Force Renew from", ifp, dhcp, from);
 		/* The rebind and expire timings are still the same, we just
 		 * enter the renew state early */
-		if (state->state == DHS_BOUND) {
-			eloop_timeout_delete(ifp->ctx->eloop,
-			    dhcp_renew, ifp);
+		if (state->state == DHS_BOUND)
 			dhcp_renew(ifp);
-		} else {
+		else {
 			eloop_timeout_delete(ifp->ctx->eloop,
 			    send_inform, ifp);
 			dhcp_inform(ifp);
@@ -3425,7 +3420,7 @@ dhcp_handleifa(int cmd, struct interface
 	const struct in_addr *addr,
 	const struct in_addr *net,
 	const struct in_addr *dst,
-	__unused int flags)
+	int flags)
 {
 	struct dhcp_state *state;
 	struct if_options *ifo;
@@ -3451,6 +3446,13 @@ dhcp_handleifa(int cmd, struct interface
 	if (cmd != RTM_NEWADDR)
 		return;
 
+#ifdef IN_IFF_NOTUSEABLE
+	if (flags & IN_IFF_NOTUSEABLE)
+		return;
+#else
+	UNUSED(flags);
+#endif
+
 	ifo = ifp->options;
 	if (ifo->options & DHCPCD_INFORM) {
 		if (state->state != DHS_INFORM)

Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.15 src/external/bsd/dhcpcd/dist/dhcp6.c:1.16
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.15	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/dhcp6.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.15 2015/08/21 10:39:00 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.16 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -116,7 +116,8 @@ static const char * const dhcp6_statuses
 	"No Addresses Available",
 	"No Binding",
 	"Not On Link",
-	"Use Multicast"
+	"Use Multicast",
+	"No Prefix Available"
 };
 
 struct dhcp6_ia_addr {
@@ -561,13 +562,9 @@ dhcp6_makemessage(struct interface *ifp)
 		 * hostname and FQDN according to RFC4702 */
 		fqdn = FQDN_BOTH;
 	}
-	if (fqdn != FQDN_DISABLE) {
-		if (ifo->hostname[0] == '\0')
-			hostname = get_hostname(hbuf, sizeof(hbuf),
-			    ifo->options & DHCPCD_HOSTNAME_SHORT ? 1 : 0);
-		else
-			hostname = ifo->hostname;
-	} else
+	if (fqdn != FQDN_DISABLE)
+		hostname = dhcp_get_hostname(hbuf, sizeof(hbuf), ifo);
+	else
 		hostname = NULL; /* appearse gcc */
 
 	/* Work out option size first */
@@ -696,7 +693,6 @@ dhcp6_makemessage(struct interface *ifp)
 	unicast = NULL;
 	/* Depending on state, get the unicast address */
 	switch(state->state) {
-		break;
 	case DH6S_INIT: /* FALLTHROUGH */
 	case DH6S_DISCOVER:
 		type = DHCP6_SOLICIT;
@@ -1254,7 +1250,17 @@ dhcp6_startrenew(void *arg)
 	struct dhcp6_state *state;
 
 	ifp = arg;
-	state = D6_STATE(ifp);
+	if ((state = D6_STATE(ifp)) == NULL)
+		return;
+
+	/* Only renew in the bound or renew states */
+	if (state->state != DH6S_BOUND &&
+	    state->state != DH6S_RENEW)
+		return;
+
+	/* Remove the timeout as the renew may have been forced. */
+	eloop_timeout_delete(ifp->ctx->eloop, dhcp6_startrenew, ifp);
+
 	state->state = DH6S_RENEW;
 	state->RTC = 0;
 	state->IRT = REN_TIMEOUT;
@@ -1268,6 +1274,12 @@ dhcp6_startrenew(void *arg)
 		dhcp6_sendrenew(ifp);
 }
 
+void dhcp6_renew(struct interface *ifp)
+{
+
+	dhcp6_startrenew(ifp);
+}
+
 int
 dhcp6_dadcompleted(const struct interface *ifp)
 {
@@ -1623,9 +1635,10 @@ dhcp6_finishrelease(void *arg)
 	struct dhcp6_state *state;
 
 	ifp = (struct interface *)arg;
-	state = D6_STATE(ifp);
-	state->state = DH6S_RELEASED;
-	dhcp6_drop(ifp, "RELEASE6");
+	if ((state = D6_STATE(ifp)) != NULL) {
+		state->state = DH6S_RELEASED;
+		dhcp6_drop(ifp, "RELEASE6");
+	}
 }
 
 static void
@@ -1665,7 +1678,8 @@ dhcp6_checkstatusok(const struct interfa
 {
 	const struct dhcp6_option *o;
 	uint16_t code;
-	char *status;
+	char buf[32], *sbuf;
+	const char *status;
 
 	if (p)
 		o = dhcp6_findoption(D6_OPTION_STATUS_CODE, p, len);
@@ -1691,24 +1705,25 @@ dhcp6_checkstatusok(const struct interfa
 	len -= sizeof(code);
 
 	if (len == 0) {
-		if (code < sizeof(dhcp6_statuses) / sizeof(char *)) {
-			p = (const uint8_t *)dhcp6_statuses[code];
-			len = strlen((const char *)p);
-		} else
-			p = NULL;
-	} else
-		p += sizeof(code);
-
-	status = malloc(len + 1);
-	if (status == NULL) {
-		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
-		return -1;
+		sbuf = NULL;
+		if (code < sizeof(dhcp6_statuses) / sizeof(char *))
+			status = dhcp6_statuses[code];
+		else {
+			snprintf(buf, sizeof(buf), "Unknown Status (%d)", code);
+			status = buf;
+		}
+	} else {
+		if ((sbuf = malloc(len + 1)) == NULL) {
+			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
+			return -1;
+		}
+		memcpy(sbuf, p + sizeof(code), len);
+		sbuf[len] = '\0';
+		status = sbuf;
 	}
-	if (p)
-		memcpy(status, p, len);
-	status[len] = '\0';
+
 	logger(ifp->ctx, LOG_ERR, "%s: DHCPv6 REPLY: %s", ifp->name, status);
-	free(status);
+	free(sbuf);
 	return -1;
 }
 
@@ -1905,8 +1920,8 @@ dhcp6_findpd(struct interface *ifp, cons
 			state->expire = a->prefix_vltime;
 		i++;
 
-		p = D6_COPTION_DATA(o) + sizeof(pdp);
-		ol = (uint16_t)(ol - sizeof(pdp));
+		p = D6_COPTION_DATA(o) + sizeof(*pdp);
+		ol = (uint16_t)(ol - sizeof(*pdp));
 		ex = dhcp6_findoption(D6_OPTION_PD_EXCLUDE, p, ol);
 		a->prefix_exclude_len = 0;
 		memset(&a->prefix_exclude, 0, sizeof(a->prefix_exclude));
@@ -2173,27 +2188,52 @@ dhcp6_readlease(struct interface *ifp, i
 	struct timespec acquired;
 	time_t now;
 	int retval;
+	size_t newlen;
+	void *newnew;
 
 	state = D6_STATE(ifp);
-	if (stat(state->leasefile, &st) == -1)
-		return -1;
-	logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
-	    ifp->name, state->leasefile);
-	if (st.st_size > UINT32_MAX) {
-		errno = E2BIG;
-		return -1;
+	if (state->leasefile[0] == '\0') {
+ 		logger(ifp->ctx, LOG_DEBUG, "reading standard input");
+		fd = fileno(stdin);
+	} else {
+		logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
+		    ifp->name, state->leasefile);
+		fd = open(state->leasefile, O_RDONLY);
 	}
-	if ((fd = open(state->leasefile, O_RDONLY)) == -1)
+	if (fd == -1)
 		return -1;
-	if ((state->new = malloc((size_t)st.st_size)) == NULL)
+	state->new_len = 0;
+	if ((state->new = malloc(BUFSIZ)) == NULL)
 		return -1;
 	retval = -1;
-	state->new_len = (size_t)st.st_size;
-	bytes = read(fd, state->new, state->new_len);
+	/* DHCPv6 messages have no real maximum size.
+	 * As we could be reading from stdin, we loop like so. */
+	for (;;) {
+		bytes = read(fd, state->new + state->new_len, BUFSIZ);
+		if (bytes == -1)
+			break;
+		if (bytes < BUFSIZ) {
+			state->new_len += (size_t)bytes;
+			retval = 0;
+			break;
+		}
+		newlen = state->new_len + BUFSIZ;
+		if (newlen > UINT32_MAX || newlen < state->new_len) {
+			errno = E2BIG;
+			break;
+		}
+		if ((newnew = realloc(state->new, newlen)) == NULL)
+			break;
+		state->new = newnew;
+		state->new_len = newlen;
+	}
 	close(fd);
-	if (bytes != (ssize_t)state->new_len)
+	if (retval == -1)
 		goto ex;
 
+	if (ifp->ctx->options & DHCPCD_DUMPLEASE)
+		return 0;
+
 	/* If not validating IA's and if they have expired,
 	 * skip to the auth check. */
 	if (!validate) {
@@ -2201,10 +2241,12 @@ dhcp6_readlease(struct interface *ifp, i
 		goto auth;
 	}
 
-	if ((now = time(NULL)) == -1)
+	retval = -1;
+	if (stat(state->leasefile, &st) == -1)
 		goto ex;
-
 	clock_gettime(CLOCK_MONOTONIC, &acquired);
+	if ((now = time(NULL)) == -1)
+		goto ex;
 	acquired.tv_sec -= now - st.st_mtime;
 
 	/* Check to see if the lease is still valid */
@@ -2213,8 +2255,8 @@ dhcp6_readlease(struct interface *ifp, i
 	if (fd == -1)
 		goto ex;
 
-	if (!(ifp->ctx->options & DHCPCD_DUMPLEASE) &&
-	    state->expire != ND6_INFINITE_LIFETIME)
+	if (state->expire != ND6_INFINITE_LIFETIME &&
+	    state->leasefile[0] != '\0')
 	{
 		if ((time_t)state->expire < now - st.st_mtime) {
 			logger(ifp->ctx,
@@ -2226,7 +2268,6 @@ dhcp6_readlease(struct interface *ifp, i
 	}
 
 auth:
-
 	retval = 0;
 	/* Authenticate the message */
 	o = dhcp6_getmoption(D6_OPTION_AUTH, state->new, state->new_len);
@@ -2894,8 +2935,6 @@ dhcp6_handledata(void *arg)
 				    ifp->name, op);
 				return;
 			}
-			eloop_timeout_delete(ifp->ctx->eloop,
-			    dhcp6_startrenew, ifp);
 			dhcp6_startrenew(ifp);
 			break;
 		case DHCP6_INFORMATION_REQ:

Index: src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.9 src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.10
--- src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf:1.9	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-# $NetBSD: dhcpcd-definitions.conf,v 1.9 2015/07/09 10:15:34 roy Exp $
+# $NetBSD: dhcpcd-definitions.conf,v 1.10 2015/11/30 16:33:00 roy Exp $
 
 # Copyright (c) 2006-2015 Roy Marples
 # All rights reserved
@@ -116,7 +116,7 @@ embed		byte			rcode2
 # RFC1035 encoded.
 # The server MUST use the encoding as specified by the client as noted
 # in RFC4702 Section 2.1.
-embed		domain			fqdn
+embed		optional domain		fqdn
 
 # Option 82 is for Relay Agents and DHCP servers
 
@@ -272,7 +272,11 @@ define 210	string			path_prefix
 define 211	uint32			reboot_time
 
 # DHCP IPv6 Rapid Deployment on IPv4 Infrastructures, RFC5969
-define 212	rfc5969			sixrd
+define 212	embed			sixrd
+embed		byte			mask_len
+embed		byte			prefix_len
+embed		ip6address		prefix
+embed		array ipaddress		brip_address
 
 # DHCP Access Network Domain Name, RFC5986
 define 213	domain			access_domain
Index: src/external/bsd/dhcpcd/dist/duid.c
diff -u src/external/bsd/dhcpcd/dist/duid.c:1.9 src/external/bsd/dhcpcd/dist/duid.c:1.10
--- src/external/bsd/dhcpcd/dist/duid.c:1.9	Thu Jul  9 10:15:34 2015
+++ src/external/bsd/dhcpcd/dist/duid.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: duid.c,v 1.9 2015/07/09 10:15:34 roy Exp $");
+ __RCSID("$NetBSD: duid.c,v 1.10 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -39,6 +39,7 @@
 #include <net/if_arp.h>
 
 #include <errno.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.44 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.45
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.44	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.8.in,v 1.44 2015/08/21 10:39:00 roy Exp $
+.\"     $NetBSD: dhcpcd.8.in,v 1.45 2015/11/30 16:33: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 August 21, 2015
+.Dd November 18, 2015
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -31,7 +31,7 @@
 .Nd a DHCP client
 .Sh SYNOPSIS
 .Nm
-.Op Fl 46ABbDdEGgHJKLMpqTV
+.Op Fl 46ABbDdEGgHJKLMNpqTV
 .Op Fl C , Fl Fl nohook Ar hook
 .Op Fl c , Fl Fl script Ar script
 .Op Fl e , Fl Fl env Ar value
@@ -49,6 +49,7 @@
 .Op Fl r , Fl Fl request Ar address
 .Op Fl S , Fl Fl static Ar value
 .Op Fl s , Fl Fl inform Ar address Ns Op Ar /cidr
+.Op Fl Fl inform6
 .Op Fl t , Fl Fl timeout Ar seconds
 .Op Fl u , Fl Fl userclass Ar class
 .Op Fl v , Fl Fl vendor Ar code , Ar value
@@ -378,6 +379,22 @@ is not running, then it starts up as nor
 This may also cause
 .Xr wpa_supplicant 8
 to reload its configuration for each interface as well.
+.It Fl N , Fl Fl renew Op Ar interface
+Notifies
+.Nm
+to renew existing addresses on the specified
+.Ar interface .
+If no interface is specified then this applies to all interfaces.
+If
+.Nm
+is not running, then it starts up as normal.
+Unlike the
+.Fl n , Fl Fl rebind
+option above, the configuration for
+.Nm
+and
+.Xr wpa_supplicant 8
+is not reloaded.
 .It Fl o , Fl Fl option Ar option
 Request the DHCP
 .Ar option
@@ -420,6 +437,15 @@ If
 .Nm
 fails to contact a DHCP server then it returns a failure instead of falling
 back on IPv4LL.
+.It Fl Fl inform6
+Performs a DHCPv6 Information Request.
+No address is requested or specified, but all other DHCPv6 options are allowed.
+This is normally performed automatically when the IPv6 Router Advertises
+that the client should perform this operation.
+This option is only needed when
+.Nm
+is not processing IPv6RA messages and the need for DHCPv6 Information Request
+exists.
 .It Fl S, Fl Fl static Ar value
 Configures a static DHCP
 .Ar value .
@@ -608,8 +634,7 @@ before starting
 Dumps the last lease for the
 .Ar interface
 to stdout.
-.Ar interface
-could also be a path to a DHCP wire formatted file.
+If omitted, standard input is used to read a DHCP wire formatted message.
 Use the
 .Fl 4
 or

Index: src/external/bsd/dhcpcd/dist/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.28 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.29
--- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.28	Fri Sep  4 12:25:01 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcpcd.c,v 1.28 2015/09/04 12:25:01 roy Exp $");
+ __RCSID("$NetBSD: dhcpcd.c,v 1.29 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -456,7 +456,7 @@ configure_interface1(struct interface *i
 		ifo->options |= DHCPCD_IPV6RA_OWN;
 
 	/* We want to disable kernel interface RA as early as possible. */
-	if (ifo->options & DHCPCD_IPV6RS &&
+	if (ifo->options & DHCPCD_IPV6 &&
 	    !(ifp->ctx->options & DHCPCD_DUMPLEASE))
 	{
 		/* If not doing any DHCP, disable the RDNSS requirement. */
@@ -855,20 +855,21 @@ dhcpcd_startinterface(void *arg)
 	}
 
 	if (ifo->options & DHCPCD_IPV6) {
-		if (ifo->options & DHCPCD_IPV6RS &&
-		    !(ifo->options & DHCPCD_INFORM))
+		if (ifo->options & DHCPCD_IPV6RS)
 			ipv6nd_startrs(ifp);
 
 		if (ifo->options & DHCPCD_DHCP6)
 			dhcp6_find_delegates(ifp);
 
 		if (!(ifo->options & DHCPCD_IPV6RS) ||
-		    ifo->options & DHCPCD_IA_FORCED)
+		    ifo->options & (DHCPCD_IA_FORCED | DHCPCD_INFORM6))
 		{
 			ssize_t nolease;
 
 			if (ifo->options & DHCPCD_IA_FORCED)
 				nolease = dhcp6_start(ifp, DH6S_INIT);
+			else if (ifo->options & DHCPCD_INFORM6)
+				nolease = dhcp6_start(ifp, DH6S_INFORM);
 			else {
 				nolease = 0;
 				/* Enabling the below doesn't really make
@@ -1153,31 +1154,55 @@ reconf_reboot(struct dhcpcd_ctx *ctx, in
 }
 
 static void
-stop_all_interfaces(struct dhcpcd_ctx *ctx, int do_release)
+stop_all_interfaces(struct dhcpcd_ctx *ctx, unsigned long long opts)
 {
 	struct interface *ifp;
 
 	/* Drop the last interface first */
 	while ((ifp = TAILQ_LAST(ctx->ifaces, if_head)) != NULL) {
-		if (do_release) {
-			ifp->options->options |= DHCPCD_RELEASE;
+		ifp->options->options |= opts;
+		if (ifp->options->options & DHCPCD_RELEASE)
 			ifp->options->options &= ~DHCPCD_PERSISTENT;
-		}
 		ifp->options->options |= DHCPCD_EXITING;
 		stop_interface(ifp);
 	}
 }
 
+static void
+dhcpcd_ifrenew(struct interface *ifp)
+{
+
+#define DHCPCD_RARENEW (DHCPCD_IPV6 | DHCPCD_IPV6RS)
+	if (ifp->options->options & DHCPCD_LINK &&
+	    ifp->carrier != LINK_DOWN)
+	{
+		dhcp_renew(ifp);
+		if ((ifp->options->options & DHCPCD_RARENEW) == DHCPCD_RARENEW)
+			ipv6nd_startrs(ifp);
+		dhcp6_renew(ifp);
+	}
+}
+
+static void
+dhcpcd_renew(struct dhcpcd_ctx *ctx)
+{
+	struct interface *ifp;
+
+	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+		dhcpcd_ifrenew(ifp);
+	}
+}
+
 #ifdef USE_SIGNALS
 #define sigmsg "received %s, %s"
 static void
 signal_cb(int sig, void *arg)
 {
 	struct dhcpcd_ctx *ctx = arg;
-	struct interface *ifp;
-	int do_release, exit_code;
+	unsigned long long opts;
+	int exit_code;
 
-	do_release = 0;
+	opts = 0;
 	exit_code = EXIT_FAILURE;
 	switch (sig) {
 	case SIGINT:
@@ -1189,7 +1214,7 @@ signal_cb(int sig, void *arg)
 		break;
 	case SIGALRM:
 		logger(ctx, LOG_INFO, sigmsg, "SIGALRM", "releasing");
-		do_release = 1;
+		opts |= DHCPCD_RELEASE;
 		exit_code = EXIT_SUCCESS;
 		break;
 	case SIGHUP:
@@ -1201,10 +1226,8 @@ signal_cb(int sig, void *arg)
 		    ctx->argc - ctx->ifc);
 		return;
 	case SIGUSR1:
-		logger(ctx, LOG_INFO, sigmsg, "SIGUSR1", "reconfiguring");
-		TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-			ipv4_applyaddr(ifp);
-		}
+		logger(ctx, LOG_INFO, sigmsg, "SIGUSR1", "renewing");
+		dhcpcd_renew(ctx);
 		return;
 	case SIGUSR2:
 		logger_close(ctx);
@@ -1223,7 +1246,7 @@ signal_cb(int sig, void *arg)
 	}
 
 	if (!(ctx->options & DHCPCD_TEST))
-		stop_all_interfaces(ctx, do_release);
+		stop_all_interfaces(ctx, opts);
 	eloop_exit(ctx->eloop, exit_code);
 }
 #endif
@@ -1262,8 +1285,8 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx
     int argc, char **argv)
 {
 	struct interface *ifp;
-	int do_exit = 0, do_release = 0, do_reboot = 0;
-	int opt, oi = 0;
+	unsigned long long opts;
+	int opt, oi, do_reboot, do_renew;
 	size_t len, l;
 	char *tmp, *p;
 
@@ -1312,6 +1335,9 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx
 	free(tmp);
 
 	optind = 0;
+	oi = 0;
+	opts = 0;
+	do_reboot = do_renew = 0;
 	while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
 	{
 		switch (opt) {
@@ -1319,36 +1345,53 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx
 			/* Assumed if below not set */
 			break;
 		case 'k':
-			do_release = 1;
+			opts |= DHCPCD_RELEASE;
 			break;
 		case 'n':
 			do_reboot = 1;
 			break;
+		case 'p':
+			opts |= DHCPCD_PERSISTENT;
+			break;
 		case 'x':
-			do_exit = 1;
+			opts |= DHCPCD_EXITING;
+			break;
+		case 'N':
+			do_renew = 1;
 			break;
 		}
 	}
 
-	if (do_release || do_exit) {
+	if (opts & (DHCPCD_EXITING | DHCPCD_RELEASE)) {
 		if (optind == argc) {
-			stop_all_interfaces(ctx, do_release);
+			stop_all_interfaces(ctx, opts);
 			eloop_exit(ctx->eloop, EXIT_SUCCESS);
 			return 0;
 		}
 		for (oi = optind; oi < argc; oi++) {
 			if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
 				continue;
-			if (do_release) {
-				ifp->options->options |= DHCPCD_RELEASE;
+			ifp->options->options |= opts;
+			if (opts & DHCPCD_RELEASE)
 				ifp->options->options &= ~DHCPCD_PERSISTENT;
-			}
-			ifp->options->options |= DHCPCD_EXITING;
 			stop_interface(ifp);
 		}
 		return 0;
 	}
 
+	if (do_renew) {
+		if (optind == argc) {
+			dhcpcd_renew(ctx);
+			return 0;
+		}
+		for (oi = optind; oi < argc; oi++) {
+			if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
+				continue;
+			dhcpcd_ifrenew(ifp);
+		}
+		return 0;
+	}
+
 	reload_config(ctx);
 	/* XXX: Respect initial commandline options? */
 	reconf_reboot(ctx, do_reboot, argc, argv, optind - 1);
@@ -1440,9 +1483,18 @@ main(int argc, char **argv)
 			sig = SIGHUP;
 			siga = "HUP";
 			break;
+		case 'p':
+			/* Force going via command socket as we're
+			 * out of user definable signals. */
+			i = 4;
+			break;
 		case 'x':
 			sig = SIGTERM;
-			siga = "TERM";;
+			siga = "TERM";
+			break;
+		case 'N':
+			sig = SIGUSR1;
+			siga = "USR1";
 			break;
 #endif
 		case 'T':
@@ -1504,7 +1556,7 @@ main(int argc, char **argv)
 		goto exit_success;
 	}
 	ctx.options = ifo->options;
-	if (i != 0) {
+	if (i == 1 || i == 3) {
 		if (i == 1)
 			ctx.options |= DHCPCD_TEST;
 		else
@@ -1571,16 +1623,23 @@ main(int argc, char **argv)
 		goto exit_failure;
 	}
 
+	/* Open our persistent sockets.
+	 * This is needed early for dumping leases on valid interfaces. */
+	if (if_opensockets(&ctx) == -1) {
+		logger(&ctx, LOG_ERR, "if_opensockets: %m");
+		goto exit_failure;
+	}
+
 	if (ctx.options & DHCPCD_DUMPLEASE) {
-		if (optind != argc - 1) {
-			logger(&ctx, LOG_ERR,
-			    "dumplease requires an interface");
-			goto exit_failure;
+		if (optind != argc) {
+			/* We need to try and find the interface so we can load
+			 * the hardware address to compare automated IAID */
+			ctx.ifaces = if_discover(&ctx,
+			    argc - optind, argv + optind);
+		} else {
+			if ((ctx.ifaces = malloc(sizeof(*ctx.ifaces))) != NULL)
+				TAILQ_INIT(ctx.ifaces);
 		}
-		i = 0;
-		/* We need to try and find the interface so we can
-		 * load the hardware address to compare automated IAID */
-		ctx.ifaces = if_discover(&ctx, 1, argv + optind);
 		if (ctx.ifaces == NULL) {
 			logger(&ctx, LOG_ERR, "if_discover: %m");
 			goto exit_failure;
@@ -1592,7 +1651,9 @@ main(int argc, char **argv)
 				logger(&ctx, LOG_ERR, "%s: %m", __func__);
 				goto exit_failure;
 			}
-			strlcpy(ctx.pidfile, argv[optind], sizeof(ctx.pidfile));
+			if (optind != argc)
+				strlcpy(ctx.pidfile, argv[optind],
+				    sizeof(ctx.pidfile));
 			ifp->ctx = &ctx;
 			TAILQ_INSERT_HEAD(ctx.ifaces, ifp, next);
 			if (family == 0) {
@@ -1603,13 +1664,14 @@ main(int argc, char **argv)
 			}
 		}
 		configure_interface(ifp, ctx.argc, ctx.argv, 0);
+		i = 0;
 		if (family == 0 || family == AF_INET) {
 			if (dhcp_dump(ifp) == -1)
-				i = 1;
+				i = -1;
 		}
 		if (family == 0 || family == AF_INET6) {
 			if (dhcp6_dump(ifp) == -1)
-				i = 1;
+				i = -1;
 		}
 		if (i == -1)
 			goto exit_failure;
@@ -1618,7 +1680,7 @@ main(int argc, char **argv)
 
 #ifdef USE_SIGNALS
 	if (!(ctx.options & DHCPCD_TEST) &&
-	    (sig == 0 || ctx.ifc != 0))
+	    (sig == 0 || i == 4 || ctx.ifc != 0))
 	{
 #endif
 		if (ctx.options & DHCPCD_MASTER)
@@ -1655,14 +1717,14 @@ main(int argc, char **argv)
 			logger(&ctx, LOG_INFO, "sending signal %s to pid %d",
 			    siga, pid);
 		if (pid == 0 || kill(pid, sig) != 0) {
-			if (sig != SIGHUP && errno != EPERM)
+			if (sig != SIGHUP && sig != SIGUSR1 && errno != EPERM)
 				logger(&ctx, LOG_ERR, ""PACKAGE" not running");
 			if (pid != 0 && errno != ESRCH) {
 				logger(&ctx, LOG_ERR, "kill: %m");
 				goto exit_failure;
 			}
 			unlink(ctx.pidfile);
-			if (sig != SIGHUP)
+			if (sig != SIGHUP && sig != SIGUSR1)
 				goto exit_failure;
 		} else {
 			struct timespec ts;
@@ -1712,9 +1774,11 @@ main(int argc, char **argv)
 			/* Lock the file so that only one instance of dhcpcd
 			 * runs on an interface */
 			if (flock(ctx.pid_fd, LOCK_EX | LOCK_NB) == -1) {
-				logger(&ctx, LOG_ERR, "flock `%s': %m", ctx.pidfile);
-				close(ctx.pid_fd);
-				ctx.pid_fd = -1;
+				logger(&ctx, LOG_ERR, "flock `%s': %m",
+				    ctx.pidfile);
+				/* We don't want to unlink the pidfile as
+				 * another dhcpcd instance could be using it. */
+				ctx.pidfile[0] = '\0';
 				goto exit_failure;
 			}
 #endif
@@ -1723,8 +1787,9 @@ main(int argc, char **argv)
 			    fcntl(ctx.pid_fd, F_SETFD, opt | FD_CLOEXEC) == -1)
 			{
 				logger(&ctx, LOG_ERR, "fcntl: %m");
-				close(ctx.pid_fd);
-				ctx.pid_fd = -1;
+				/* We don't want to unlink the pidfile as
+				 * another dhcpcd instance could be using it. */
+				ctx.pidfile[0] = '\0';
 				goto exit_failure;
 			}
 #endif
@@ -1767,11 +1832,8 @@ main(int argc, char **argv)
 	if (ctx.ifc == 1 && !(ctx.options & DHCPCD_BACKGROUND))
 		ctx.options |= DHCPCD_WAITIP;
 
-	/* Open our persistent sockets. */
-	if (if_opensockets(&ctx) == -1) {
-		logger(&ctx, LOG_ERR, "if_opensockets: %m");
-		goto exit_failure;
-	}
+	/* Start handling kernel messages for interfaces, addreses and
+	 * routes. */
 	eloop_event_add(ctx.eloop, ctx.link_fd, handle_link, &ctx, NULL, NULL);
 
 	/* Start any dev listening plugin which may want to
@@ -1813,7 +1875,8 @@ main(int argc, char **argv)
 	opt = 0;
 	TAILQ_FOREACH(ifp, ctx.ifaces, next) {
 		run_preinit(ifp);
-		if (ifp->carrier != LINK_DOWN)
+		if (!(ifp->options->options & DHCPCD_LINK) ||
+		    ifp->carrier != LINK_DOWN)
 			opt = 1;
 	}
 
@@ -1888,7 +1951,6 @@ exit1:
 		close(ctx.pf_link_fd);
 #endif
 
-
 	free_options(ifo);
 	free_globals(&ctx);
 	ipv4_ctxfree(&ctx);
@@ -1898,7 +1960,8 @@ exit1:
 		logger(&ctx, LOG_ERR, "control_stop: %m:");
 	if (ctx.pid_fd != -1) {
 		close(ctx.pid_fd);
-		unlink(ctx.pidfile);
+		if (ctx.pidfile[0] != '\0')
+			unlink(ctx.pidfile);
 	}
 	eloop_free(ctx.eloop);
 

Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.23 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.24
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.23	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.conf.5.in,v 1.23 2015/08/21 10:39:00 roy Exp $
+.\"     $NetBSD: dhcpcd.conf.5.in,v 1.24 2015/11/30 16:33: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 August 1, 2015
+.Dd October 19, 2015
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -316,7 +316,7 @@ A second prefix is requested and assigne
 can be used with an empty configuration file on eth1, eth2 and eth3,
 to provide automatic
 IPv6 address configuration for the internal network.
-.Bd -literal -indent
+.Bd -literal
 noipv6rs                 # disable routing solicitation
 denyinterfaces eth2      # Don't touch eth2 at all
 interface eth0
@@ -736,6 +736,10 @@ Requests the option by default without h
 configuration
 .It Ic norequest
 This option cannot be requested, regardless of user configuration
+.It Ic optional
+This option is optional.
+Only makes sense for embedded options where like the client FQDN option where
+the FQDN string itself is optional.
 .It Ic index
 The option can appear more than once and will be indexed.
 .It Ic array
Index: src/external/bsd/dhcpcd/dist/script.c
diff -u src/external/bsd/dhcpcd/dist/script.c:1.23 src/external/bsd/dhcpcd/dist/script.c:1.24
--- src/external/bsd/dhcpcd/dist/script.c:1.23	Fri Sep  4 12:25:01 2015
+++ src/external/bsd/dhcpcd/dist/script.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: script.c,v 1.23 2015/09/04 12:25:01 roy Exp $");
+ __RCSID("$NetBSD: script.c,v 1.24 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -264,10 +264,10 @@ make_env(const struct interface *ifp, co
 			ra = 1;
 #endif
 #ifdef INET
-		else if (state->added)
-			dhcp = 1;
-		else
+		else if (istate && istate->addr.s_addr != INADDR_ANY)
 			ipv4ll = 1;
+		else
+			dhcp = 1;
 #endif
 	}
 #ifdef INET6

Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.24 src/external/bsd/dhcpcd/dist/if-bsd.c:1.25
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.24	Fri Aug 21 13:24:47 2015
+++ src/external/bsd/dhcpcd/dist/if-bsd.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.24 2015/08/21 13:24:47 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.25 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -511,8 +511,6 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct
 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;
@@ -525,6 +523,7 @@ if_route(unsigned char cmd, const struct
 	} rtm;
 	char *bp = rtm.buffer;
 	size_t l;
+	struct in_addr src_addr;
 
 #define ADDSU {								      \
 		l = RT_ROUNDUP(su.sa.sa_len);				      \
@@ -539,47 +538,36 @@ if_route(unsigned char cmd, const struct
 		ADDSU;							      \
 	}
 
-	if (cmd != RTM_DELETE) {
-		state = D_CSTATE(rt->iface);
-		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;
 	rtm.hdr.rtm_type = cmd;
 	rtm.hdr.rtm_addrs = RTA_DST;
-	if (cmd == RTM_ADD || cmd == RTM_CHANGE)
-		rtm.hdr.rtm_addrs |= RTA_GATEWAY;
 	rtm.hdr.rtm_flags = RTF_UP;
+	rtm.hdr.rtm_pid = getpid();
 #ifdef RTF_PINNED
 	if (cmd != RTM_ADD)
 		rtm.hdr.rtm_flags |= RTF_PINNED;
 #endif
 
-	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 ||
-		    rt->net.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 {
+	if (cmd == RTM_ADD || cmd == RTM_CHANGE) {
+		int subnet;
+
+		rtm.hdr.rtm_addrs |= RTA_GATEWAY | RTA_IFA | RTA_IFP;
+		/* Subnet routes are clonning or connected if supported.
+		 * All other routes are static. */
+		subnet = ipv4_srcaddr(rt, &src_addr);
+		if (subnet == 1) {
 #ifdef RTF_CLONING
 			rtm.hdr.rtm_flags |= RTF_CLONING;
 #endif
 #ifdef RTP_CONNECTED
 			rtm.hdr.rtm_priority = RTP_CONNECTED;
 #endif
-		}
+		} else
+			rtm.hdr.rtm_flags |= RTF_STATIC;
+		if (subnet == -1) /* unikely */
+			rtm.hdr.rtm_addrs &= ~RTA_IFA;
 	}
 	if (rt->net.s_addr == htonl(INADDR_BROADCAST) &&
 	    rt->gate.s_addr == htonl(INADDR_ANY))
@@ -607,19 +595,20 @@ if_route(unsigned char cmd, const struct
 		rtm.hdr.rtm_addrs |= RTA_NETMASK;
 		if (rtm.hdr.rtm_flags & RTF_STATIC)
 			rtm.hdr.rtm_flags |= RTF_GATEWAY;
+		if (rt->net.s_addr == htonl(INADDR_BROADCAST))
+			rtm.hdr.rtm_flags |= RTF_HOST;
 	}
 	if ((cmd == RTM_ADD || cmd == RTM_CHANGE) &&
 	    !(rtm.hdr.rtm_flags & RTF_GATEWAY))
-		rtm.hdr.rtm_addrs |= RTA_IFA | RTA_IFP;
+		rtm.hdr.rtm_addrs |= RTA_IFP;
 
 	ADDADDR(&rt->dest);
 	if (rtm.hdr.rtm_addrs & RTA_GATEWAY) {
-#ifdef RTF_CLONING
-		if ((rtm.hdr.rtm_flags & (RTF_HOST | RTF_CLONING) &&
-#else
 		if ((rtm.hdr.rtm_flags & RTF_HOST &&
+		    rt->gate.s_addr == htonl(INADDR_ANY)) ||
+#ifdef RTF_CLONING
+		    rtm.hdr.rtm_flags & RTF_CLONING ||
 #endif
-		    rt->gate.s_addr != htonl(INADDR_LOOPBACK)) ||
 		    !(rtm.hdr.rtm_flags & RTF_STATIC))
 		{
 			if_linkaddr(&su.sdl, rt->iface);
@@ -641,7 +630,7 @@ if_route(unsigned char cmd, const struct
 		}
 
 		if (rtm.hdr.rtm_addrs & RTA_IFA)
-			ADDADDR(istate == NULL ? &state->addr : &istate->addr);
+			ADDADDR(&src_addr);
 
 		if (rt->mtu) {
 			rtm.hdr.rtm_inits |= RTV_MTU;
@@ -936,6 +925,7 @@ if_route6(unsigned char cmd, const struc
 	rtm.hdr.rtm_seq = 1;
 	rtm.hdr.rtm_type = cmd;
 	rtm.hdr.rtm_flags = RTF_UP | (int)rt->flags;
+	rtm.hdr.rtm_pid = getpid();
 #ifdef RTF_PINNED
 	if (rtm.hdr.rtm_type != RTM_ADD)
 		rtm.hdr.rtm_flags |= RTF_PINNED;
@@ -1486,24 +1476,6 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 		int override;
 #endif
 
-#ifdef ND6_IFF_IFDISABLED
-		if (del_if_nd6_flag(s, ifp, ND6_IFF_IFDISABLED) == -1) {
-			logger(ifp->ctx, LOG_ERR,
-			    "%s: del_if_nd6_flag: ND6_IFF_IFDISABLED: %m",
-			    ifp->name);
-			return -1;
-		}
-#endif
-
-#ifdef ND6_IFF_PERFORMNUD
-		if (set_if_nd6_flag(s, ifp, ND6_IFF_PERFORMNUD) == -1) {
-			logger(ifp->ctx, LOG_ERR,
-			    "%s: set_if_nd6_flag: ND6_IFF_PERFORMNUD: %m",
-			    ifp->name);
-			return -1;
-		}
-#endif
-
 #ifdef ND6_IFF_AUTO_LINKLOCAL
 		if (own) {
 			int all;
@@ -1532,18 +1504,11 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 		}
 #endif
 
-#ifdef SIOCIFAFATTACH
-		if (af_attach(s, ifp, AF_INET6) == -1) {
-			logger(ifp->ctx, LOG_ERR,
-			    "%s: af_attach: %m", ifp->name);
-			return 1;
-		}
-#endif
-
-#ifdef SIOCGIFXFLAGS
-		if (set_ifxflags(s, ifp, own) == -1) {
+#ifdef ND6_IFF_PERFORMNUD
+		if (set_if_nd6_flag(s, ifp, ND6_IFF_PERFORMNUD) == -1) {
 			logger(ifp->ctx, LOG_ERR,
-			    "%s: set_ifxflags: %m", ifp->name);
+			    "%s: set_if_nd6_flag: ND6_IFF_PERFORMNUD: %m",
+			    ifp->name);
 			return -1;
 		}
 #endif
@@ -1587,6 +1552,38 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 		} else if (ra == 0 && !own)
 			logger(ifp->ctx, LOG_WARNING,
 			    "%s: IPv6 kernel autoconf disabled", ifp->name);
+#endif
+
+		/* Enabling IPv6 by whatever means must be the
+		 * last action undertaken to ensure kernel RS and
+		 * LLADDR auto configuration are disabled where applicable. */
+
+#ifdef SIOCIFAFATTACH
+		if (af_attach(s, ifp, AF_INET6) == -1) {
+			logger(ifp->ctx, LOG_ERR,
+			    "%s: af_attach: %m", ifp->name);
+			return 1;
+		}
+#endif
+
+#ifdef SIOCGIFXFLAGS
+		if (set_ifxflags(s, ifp, own) == -1) {
+			logger(ifp->ctx, LOG_ERR,
+			    "%s: set_ifxflags: %m", ifp->name);
+			return -1;
+		}
+#endif
+
+#ifdef ND6_IFF_IFDISABLED
+		if (del_if_nd6_flag(s, ifp, ND6_IFF_IFDISABLED) == -1) {
+			logger(ifp->ctx, LOG_ERR,
+			    "%s: del_if_nd6_flag: ND6_IFF_IFDISABLED: %m",
+			    ifp->name);
+			return -1;
+		}
+#endif
+
+#ifdef ND6_IFF_ACCEPT_RTADV
 #ifdef ND6_IFF_OVERRIDE_RTADV
 		if (override == 0 && ra)
 			return ctx->ra_global;
@@ -1602,12 +1599,12 @@ _if_checkipv6(int s, struct dhcpcd_ctx *
 	if (ra == -1)
 		/* The sysctl probably doesn't exist, but this isn't an
 		 * error as such so just log it and continue */
-		logger(ifp->ctx, errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
+		logger(ctx, errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
 		    "IPV6CTL_ACCEPT_RTADV: %m");
 	else if (ra != 0 && own) {
-		logger(ifp->ctx, LOG_DEBUG, "disabling Kernel IPv6 RA support");
+		logger(ctx, LOG_DEBUG, "disabling Kernel IPv6 RA support");
 		if (set_inet6_sysctl(IPV6CTL_ACCEPT_RTADV, 0) == -1) {
-			logger(ifp->ctx, LOG_ERR, "IPV6CTL_ACCEPT_RTADV: %m");
+			logger(ctx, LOG_ERR, "IPV6CTL_ACCEPT_RTADV: %m");
 			return ra;
 		}
 		ra = 0;

Index: src/external/bsd/dhcpcd/dist/if-options.c
diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.27 src/external/bsd/dhcpcd/dist/if-options.c:1.28
--- src/external/bsd/dhcpcd/dist/if-options.c:1.27	Fri Sep  4 12:25:01 2015
+++ src/external/bsd/dhcpcd/dist/if-options.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-options.c,v 1.27 2015/09/04 12:25:01 roy Exp $");
+ __RCSID("$NetBSD: if-options.c,v 1.28 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -105,6 +105,7 @@
 #define O_BOOTP			O_BASE + 42
 #define O_DEFINEND		O_BASE + 43
 #define O_NODELAY		O_BASE + 44
+#define O_INFORM6		O_BASE + 45
 
 const struct option cf_options[] = {
 	{"background",      no_argument,       NULL, 'b'},
@@ -125,6 +126,7 @@ const struct option cf_options[] = {
 	{"quiet",           no_argument,       NULL, 'q'},
 	{"request",         optional_argument, NULL, 'r'},
 	{"inform",          optional_argument, NULL, 's'},
+	{"inform6",         optional_argument, NULL, O_INFORM6},
 	{"timeout",         required_argument, NULL, 't'},
 	{"userclass",       required_argument, NULL, 'u'},
 	{"vendor",          required_argument, NULL, 'v'},
@@ -145,6 +147,7 @@ const struct option cf_options[] = {
 	{"nolink",          no_argument,       NULL, 'K'},
 	{"noipv4ll",        no_argument,       NULL, 'L'},
 	{"master",          no_argument,       NULL, 'M'},
+	{"renew",           no_argument,       NULL, 'N'},
 	{"nooption",        optional_argument, NULL, 'O'},
 	{"require",         required_argument, NULL, 'Q'},
 	{"static",          required_argument, NULL, 'S'},
@@ -685,6 +688,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 	case 'g': /* FALLTHROUGH */
 	case 'n': /* FALLTHROUGH */
 	case 'x': /* FALLTHROUGH */
+	case 'N': /* FALLTHROUGH */
 	case 'T': /* FALLTHROUGH */
 	case 'U': /* FALLTHROUGH */
 	case 'V': /* We need to handle non interface options */
@@ -798,12 +802,6 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		ifo->req_mask.s_addr = 0;
 		break;
 	case 's':
-		if (ifo->options & DHCPCD_IPV6 &&
-		    !(ifo->options & DHCPCD_IPV4))
-		{
-			ifo->options |= DHCPCD_INFORM;
-			break;
-		}
 		if (arg && *arg != '\0') {
 			if (parse_addr(ctx,
 			    &ifo->req_addr, &ifo->req_mask, arg) != 0)
@@ -815,6 +813,9 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		ifo->options |= DHCPCD_INFORM | DHCPCD_PERSISTENT;
 		ifo->options &= ~DHCPCD_STATIC;
 		break;
+	case O_INFORM6:
+		ifo->options |= DHCPCD_INFORM6;
+		break;
 	case 't':
 		ifo->timeout = (time_t)strtoi(arg, NULL, 0, 0, INT32_MAX, &e);
 		if (e) {
@@ -1603,6 +1604,17 @@ err_sla:
 			}
 			*fp++ = '\0';
 		}
+		if (strcasecmp(arg, "optional") == 0) {
+			t |= OPTIONAL;
+			arg = strskipwhite(fp);
+			fp = strwhite(arg);
+			if (fp == NULL) {
+				logger(ctx, LOG_ERR,
+				    "incomplete optional type");
+				return -1;
+			}
+			*fp++ = '\0';
+		}
 		if (strcasecmp(arg, "index") == 0) {
 			t |= INDEX;
 			arg = strskipwhite(fp);
@@ -1661,8 +1673,6 @@ err_sla:
 			t |= STRING | RFC3361;
 		else if (strcasecmp(arg, "rfc3442") ==0)
 			t |= STRING | RFC3442;
-		else if (strcasecmp(arg, "rfc5969") == 0)
-			t |= STRING | RFC5969;
 		else if (strcasecmp(arg, "option") == 0)
 			t |= OPTION;
 		else {

Index: src/external/bsd/dhcpcd/dist/if.c
diff -u src/external/bsd/dhcpcd/dist/if.c:1.16 src/external/bsd/dhcpcd/dist/if.c:1.17
--- src/external/bsd/dhcpcd/dist/if.c:1.16	Fri Sep  4 12:25:01 2015
+++ src/external/bsd/dhcpcd/dist/if.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if.c,v 1.16 2015/09/04 12:25:01 roy Exp $");
+ __RCSID("$NetBSD: if.c,v 1.17 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -334,9 +334,11 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 		if (ctx->ifac && i == ctx->ifac)
 			continue;
 
+#ifdef PLUGIN_DEV
 		/* Ensure that the interface name has settled */
 		if (!dev_initialized(ctx, p))
 			continue;
+#endif
 
 		/* Don't allow loopback or pointopoint unless explicit */
 		if (ifa->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) {
@@ -523,7 +525,7 @@ if_discover(struct dhcpcd_ctx *ctx, int 
 		memset(&ifr, 0, sizeof(ifr));
 		strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
 		if (ioctl(ctx->pf_inet_fd, SIOCGIFPRIORITY, &ifr) == 0)
-			ifp->metric = ifr.ifr_metric;
+			ifp->metric = (unsigned int)ifr.ifr_metric;
 #else
 		/* We reserve the 100 range for virtual interfaces, if and when
 		 * we can work them out. */
@@ -678,11 +680,11 @@ xsocket(int domain, int type, int protoc
 
 	if ((s = socket(domain, type, protocol)) == -1)
 		return -1;
-	if ((flags & O_CLOEXEC) && (xflags = fcntl(s, F_GETFD, 0)) == -1 ||
-	    fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1)
+	if ((flags & O_CLOEXEC) && ((xflags = fcntl(s, F_GETFD, 0)) == -1 ||
+	    fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1))
 		goto out;
-	if ((flags & O_NONBLOCK) && (xflags = fcntl(s, F_GETFL, 0)) == -1 ||
-	    fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1)
+	if ((flags & O_NONBLOCK) && ((xflags = fcntl(s, F_GETFL, 0)) == -1 ||
+	    fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1))
 		goto out;
 	return s;
 out:

Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.17 src/external/bsd/dhcpcd/dist/ipv4.c:1.18
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.17	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/ipv4.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.17 2015/08/21 10:39:00 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.18 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -163,6 +163,51 @@ ipv4_findaddr(struct dhcpcd_ctx *ctx, co
 }
 
 int
+ipv4_srcaddr(const struct rt *rt, struct in_addr *addr)
+{
+	const struct dhcp_state *dstate;
+	const struct ipv4ll_state *istate;
+
+	if (rt->iface == NULL) {
+		errno = ENOENT;
+		return -1;
+	}
+
+	/* Prefer DHCP source address if matching */
+	dstate = D_CSTATE(rt->iface);
+	if (dstate &&
+	    rt->net.s_addr == dstate->net.s_addr &&
+	    rt->dest.s_addr == (dstate->addr.s_addr & dstate->net.s_addr))
+	{
+		*addr = dstate->addr;
+		return 1;
+	}
+
+	/* Then IPv4LL source address if matching */
+	istate = IPV4LL_CSTATE(rt->iface);
+	if (istate &&
+	    rt->net.s_addr == inaddr_llmask.s_addr &&
+	    rt->dest.s_addr == (istate->addr.s_addr & inaddr_llmask.s_addr))
+	{
+		*addr = istate->addr;
+		return 1;
+	}
+
+	/* If neither match, return DHCP then IPv4LL */
+	if (dstate) {
+		*addr = dstate->addr;
+		return 0;
+	}
+	if (istate) {
+		*addr = istate->addr;
+		return 0;
+	}
+
+	errno = ESRCH;
+	return -1;
+}
+
+int
 ipv4_hasaddr(const struct interface *ifp)
 {
 	const struct dhcp_state *dstate;
@@ -437,16 +482,21 @@ nc_route(struct rt *ort, struct rt *nrt)
 #endif
 
 	if (change) {
-		if (if_route(RTM_CHANGE, nrt) == 0)
+		if (if_route(RTM_CHANGE, nrt) != -1)
 			return 0;
 		if (errno != ESRCH)
 			logger(nrt->iface->ctx, LOG_ERR, "if_route (CHG): %m");
 	}
 
+	/* If the old route does not have an interface, give it the
+	 * interface of the new route for context. */
+	if (ort && ort->iface == NULL)
+		ort->iface = nrt->iface;
+
 #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) != -1) {
 		if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
 			logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
 		return 0;
@@ -462,7 +512,7 @@ nc_route(struct rt *ort, struct rt *nrt)
 	 * adding the new one. */
 	if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH)
 		logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m");
-	if (if_route(RTM_ADD, nrt) == 0)
+	if (if_route(RTM_ADD, nrt) != -1)
 		return 0;
 #ifdef HAVE_ROUTE_METRIC
 logerr:
@@ -477,8 +527,8 @@ d_route(struct rt *rt)
 	int retval;
 
 	desc_route("deleting", rt);
-	retval = if_route(RTM_DELETE, rt);
-	if (retval != 0 && errno != ENOENT && errno != ESRCH)
+	retval = if_route(RTM_DELETE, rt) == -1 ? -1 : 0;
+	if (retval == -1 && errno != ENOENT && errno != ESRCH)
 		logger(rt->iface->ctx, LOG_ERR,
 		    "%s: if_delroute: %m", rt->iface->name);
 	return retval;
@@ -705,11 +755,11 @@ ipv4_doroute(struct rt *rt, struct rt_he
 		if (or->state & STATE_FAKE ||
 		    or->iface != rt->iface ||
 #ifdef HAVE_ROUTE_METRIC
-		    rt->metric != or->metric ||
+		    or->metric != rt->metric ||
 #endif
-		    rt->src.s_addr != or->src.s_addr ||
-		    rt->gate.s_addr != or->gate.s_addr ||
-		    rt->mtu != or->mtu)
+		    or->src.s_addr != rt->src.s_addr ||
+		    or->gate.s_addr != rt->gate.s_addr ||
+		    or->mtu != rt->mtu)
 		{
 			if (c_route(or, rt) != 0)
 				return 0;
@@ -1119,9 +1169,10 @@ ipv4_applyaddr(void *arg)
 	 * notification right now via our link socket. */
 	if_initrt(ifp);
 	ipv4_buildroutes(ifp->ctx);
-	script_runreason(ifp, state->reason);
-
-	dhcpcd_daemonise(ifp->ctx);
+	if (state->state == DHS_BOUND) {
+		script_runreason(ifp, state->reason);
+		dhcpcd_daemonise(ifp->ctx);
+	}
 }
 
 void
@@ -1175,8 +1226,8 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx,
 		}
 	}
 
-	dhcp_handleifa(cmd, ifp, addr, net, dst, flags);
 	arp_handleifa(cmd, ifp, addr, flags);
+	dhcp_handleifa(cmd, ifp, addr, net, dst, flags);
 }
 
 void

Index: src/external/bsd/dhcpcd/dist/ipv4.h
diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.13 src/external/bsd/dhcpcd/dist/ipv4.h:1.14
--- src/external/bsd/dhcpcd/dist/ipv4.h:1.13	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/ipv4.h	Mon Nov 30 16:33:00 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv4.h,v 1.13 2015/08/21 10:39:00 roy Exp $ */
+/* $NetBSD: ipv4.h,v 1.14 2015/11/30 16:33:00 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -123,6 +123,7 @@ struct ipv4_addr *ipv4_iffindaddr(struct
     const struct in_addr *, const struct in_addr *);
 struct ipv4_addr *ipv4_iffindlladdr(struct interface *);
 struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
+int ipv4_srcaddr(const struct rt *, 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 *,
     int);

Index: src/external/bsd/dhcpcd/dist/ipv4ll.c
diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.12 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.13
--- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.12	Fri Aug 21 10:39:00 2015
+++ src/external/bsd/dhcpcd/dist/ipv4ll.c	Mon Nov 30 16:33:00 2015
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4ll.c,v 1.12 2015/08/21 10:39:00 roy Exp $");
+ __RCSID("$NetBSD: ipv4ll.c,v 1.13 2015/11/30 16:33:00 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -179,9 +179,12 @@ ipv4ll_probed(struct arp_state *astate)
 #endif
 		logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s",
 		  ifp->name, inet_ntoa(astate->addr));
-	if (ia == NULL)
+	if (ia == NULL) {
+		if (ifp->ctx->options & DHCPCD_TEST)
+			goto test;
 		ia = ipv4_addaddr(ifp, &astate->addr,
 		    &inaddr_llmask, &inaddr_llbcast);
+	}
 	if (ia == NULL)
 		return;
 #ifdef IN_IFF_NOTREADY
@@ -190,7 +193,13 @@ ipv4ll_probed(struct arp_state *astate)
 	logger(ifp->ctx, LOG_DEBUG, "%s: DAD completed for %s",
 	    ifp->name, inet_ntoa(astate->addr));
 #endif
+test:
 	state->addr = astate->addr;
+	if (ifp->ctx->options & DHCPCD_TEST) {
+		script_runreason(ifp, "TEST");
+		eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
+		return;
+	}
 	timespecclear(&state->defend);
 	if_initrt(ifp);
 	ipv4_buildroutes(ifp->ctx);

Index: src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf
diff -u src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf:1.6 src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf:1.7
--- src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf:1.6	Fri Nov  7 20:51:03 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd-hooks/50-ntp.conf	Mon Nov 30 16:33:00 2015
@@ -1,34 +1,57 @@
-# $NetBSD: 50-ntp.conf,v 1.6 2014/11/07 20:51:03 roy Exp $
+# $NetBSD: 50-ntp.conf,v 1.7 2015/11/30 16:33:00 roy Exp $
+
+# Sample dhcpcd hook script for NTP
+# It will configure either one of NTP, OpenNTP or Chrony (in that order)
+# and will default to NTP if no default config is found.
 
-# Sample dhcpcd hook script for ntp
 # Like our resolv.conf hook script, we store a database of ntp.conf files
 # and merge into /etc/ntp.conf
 
-# You can set the env var NTP_CONF to another file like this
+# You can set the env var NTP_CONF to override the derived default on
+# systems with >1 NTP client installed.
+# Here is an example for OpenNTP
 #   dhcpcd -e NTP_CONF=/usr/pkg/etc/ntpd.conf
+# or by adding this to /etc/dhcpcd.conf
+#   env NTP_CONF=/usr/pkg/etc/ntpd.conf
 # or by adding this to /etc/dhcpcd.enter-hook
 #   NTP_CONF=/usr/pkg/etc/ntpd.conf
-# to use OpenNTPD instead of the default NTP.
+# To use Chrony instead, simply change ntpd.conf to chrony.conf in the
+# above examples.
+
+: ${ntp_confs:=ntp.conf ntpd.conf chrony.conf}
+: ${ntp_conf_dirs=/etc /usr/pkg/etc /usr/local/etc}
+ntp_conf_dir="$state_dir/ntp.conf"
+
+# If NTP_CONF is not set, work out a good default
+if [ -z "$NTP_CONF" ]; then
+	for d in ${ntp_conf_dirs}; do
+		for f in ${ntp_confs}; do
+			if [ -e "$d/$f" ]; then
+				NTP_CONF="$d/$f"
+				break 2
+			fi
+		done
+	done
+	[ -e "$NTP_CONF" ] || NTP_CONF=/etc/ntp.conf
+fi
 
-if type invoke-rc.d >/dev/null 2>&1; then
-	# Debian has a seperate file for DHCP config to avoid stamping on
-	# the master.
+# Derive service name from configuration
+if [ -z "$ntp_service" ]; then
+	case "$NTP_CONF" in
+	*chrony.conf)		ntp_service=chronyd;;
+	*)			ntp_service=ntpd;;
+	esac
+fi
+
+# Debian has a seperate file for DHCP config to avoid stamping on
+# the master.
+if [ "$ntp_service" = ntpd ] && type invoke-rc.d >/dev/null 2>&1; then
 	[ -e /var/lib/ntp ] || mkdir /var/lib/ntp
 	: ${ntp_service:=ntp}
 	: ${NTP_DHCP_CONF:=/var/lib/ntp/ntp.conf.dhcp}
 fi
 
-: ${ntp_service:=ntpd}
 : ${ntp_restart_cmd:=service_condcommand $ntp_service restart}
-ntp_conf_dir="$state_dir/ntp.conf"
-
-# If we have installed OpenNTPD but not NTP then prefer it
-# XXX If both exist then update both?
-if [ -z "$NTP_CONF" -a -e /etc/ntpd.conf -a ! -e /etc/ntp.conf ]; then
-	: ${NTP_CONF:=/etc/ntpd.conf}
-else
-	: ${NTP_CONF:=/etc/ntp.conf}
-fi
 
 ntp_conf=${NTP_CONF}
 NL="

Reply via email to