Module Name:    src
Committed By:   roy
Date:           Wed Dec 17 20:50:09 UTC 2014

Modified Files:
        src/external/bsd/dhcpcd/dist: defs.h dhcp.c dhcp6.c dhcpcd.8.in
            dhcpcd.conf.5.in if-bsd.c if.c if.h ipv4.c ipv6.c ipv6.h ipv6nd.c
            ipv6nd.h

Log Message:
Sync


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/defs.h
cvs rdiff -u -r1.25 -r1.26 src/external/bsd/dhcpcd/dist/dhcp.c
cvs rdiff -u -r1.7 -r1.8 src/external/bsd/dhcpcd/dist/dhcp6.c \
    src/external/bsd/dhcpcd/dist/ipv6.h src/external/bsd/dhcpcd/dist/ipv6nd.h
cvs rdiff -u -r1.38 -r1.39 src/external/bsd/dhcpcd/dist/dhcpcd.8.in
cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
cvs rdiff -u -r1.15 -r1.16 src/external/bsd/dhcpcd/dist/if-bsd.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/if.c \
    src/external/bsd/dhcpcd/dist/ipv4.c
cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/if.h \
    src/external/bsd/dhcpcd/dist/ipv6.c
cvs rdiff -u -r1.18 -r1.19 src/external/bsd/dhcpcd/dist/ipv6nd.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/defs.h
diff -u src/external/bsd/dhcpcd/dist/defs.h:1.10 src/external/bsd/dhcpcd/dist/defs.h:1.11
--- src/external/bsd/dhcpcd/dist/defs.h:1.10	Tue Dec  9 20:21:05 2014
+++ src/external/bsd/dhcpcd/dist/defs.h	Wed Dec 17 20:50:08 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: defs.h,v 1.10 2014/12/09 20:21:05 roy Exp $ */
+/* $NetBSD: defs.h,v 1.11 2014/12/17 20:50:08 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -30,7 +30,7 @@
 #define CONFIG_H
 
 #define PACKAGE			"dhcpcd"
-#define VERSION			"6.6.5"
+#define VERSION			"6.6.6"
 
 #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.25 src/external/bsd/dhcpcd/dist/dhcp.c:1.26
--- src/external/bsd/dhcpcd/dist/dhcp.c:1.25	Tue Dec  9 20:21:05 2014
+++ src/external/bsd/dhcpcd/dist/dhcp.c	Wed Dec 17 20:50:08 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp.c,v 1.25 2014/12/09 20:21:05 roy Exp $");
+ __RCSID("$NetBSD: dhcp.c,v 1.26 2014/12/17 20:50:08 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -32,11 +32,6 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 
-#ifdef __linux__
-#  include <asm/types.h> /* for systems with broken headers */
-#  include <linux/rtnetlink.h>
-#endif
-
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <net/route.h>
@@ -1732,27 +1727,17 @@ dhcp_discover(void *arg)
 	struct interface *ifp = arg;
 	struct dhcp_state *state = D_STATE(ifp);
 	struct if_options *ifo = ifp->options;
-	time_t timeout = ifo->timeout;
-
-	/* If we're rebooting then we need to shorten the normal timeout
-	 * to ensure we try for a fallback or IPv4LL address. */
-	if (state->state == DHS_REBOOT) {
-		if (ifo->reboot >= timeout)
-			timeout = 2;
-		else
-			timeout = ifo->reboot;
-	}
 
 	state->state = DHS_DISCOVER;
 	state->xid = dhcp_xid(ifp);
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 	if (ifo->fallback)
 		eloop_timeout_add_sec(ifp->ctx->eloop,
-		    timeout, dhcp_fallback, ifp);
+		    ifo->reboot, dhcp_fallback, ifp);
 	else if (ifo->options & DHCPCD_IPV4LL &&
 	    !IN_LINKLOCAL(htonl(state->addr.s_addr)))
 		eloop_timeout_add_sec(ifp->ctx->eloop,
-		    timeout, ipv4ll_start, ifp);
+		    ifo->reboot, ipv4ll_start, ifp);
 	if (ifo->options & DHCPCD_REQUEST)
 		syslog(LOG_INFO, "%s: soliciting a DHCP lease (requesting %s)",
 		    ifp->name, inet_ntoa(ifo->req_addr));
@@ -2119,46 +2104,41 @@ dhcp_reboot(struct interface *ifp)
 		dhcp_static(ifp);
 		return;
 	}
-	if (ifo->reboot == 0 || state->offer == NULL) {
-		dhcp_discover(ifp);
-		return;
-	}
 	if (ifo->options & DHCPCD_INFORM) {
 		syslog(LOG_INFO, "%s: informing address of %s",
 		    ifp->name, inet_ntoa(state->lease.addr));
-	} else if (state->offer->cookie == 0) {
+		dhcp_inform(ifp);
 		return;
-	} else {
-		syslog(LOG_INFO, "%s: rebinding lease of %s",
-		    ifp->name, inet_ntoa(state->lease.addr));
 	}
+	if (ifo->reboot == 0 || state->offer == NULL) {
+		dhcp_discover(ifp);
+		return;
+	}
+	if (state->offer->cookie == 0)
+		return;
+
+	syslog(LOG_INFO, "%s: rebinding lease of %s",
+	    ifp->name, inet_ntoa(state->lease.addr));
 	state->xid = dhcp_xid(ifp);
 	state->lease.server.s_addr = 0;
 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 
 	/* Need to add this before dhcp_expire and friends. */
-	if (!ifo->fallback && ifo->reboot && ifo->options & DHCPCD_IPV4LL &&
+	if (!ifo->fallback && ifo->options & DHCPCD_IPV4LL &&
 	    !IN_LINKLOCAL(htonl(state->addr.s_addr)))
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    ifo->reboot, ipv4ll_start, ifp);
 
-	if (ifo->fallback)
-		eloop_timeout_add_sec(ifp->ctx->eloop,
-		    ifo->reboot, dhcp_fallback, ifp);
-	else if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo)
+	if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo)
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    ifo->reboot, dhcp_timeout, ifp);
-	else if (!(ifo->options & DHCPCD_INFORM &&
-	    ifp->ctx->options & (DHCPCD_MASTER | DHCPCD_DAEMONISED)))
+	else if (!(ifo->options & DHCPCD_INFORM))
 		eloop_timeout_add_sec(ifp->ctx->eloop,
 		    ifo->reboot, dhcp_expire, ifp);
-	/* Don't bother ARP checking as the server could NAK us first. */
-	if (ifo->options & DHCPCD_INFORM)
-		dhcp_inform(ifp);
-	else {
-		/* Don't call dhcp_request as that would change the state */
-		send_request(ifp);
-	}
+
+	/* Don't bother ARP checking as the server could NAK us first.
+	 * Don't call dhcp_request as that would change the state */
+	send_request(ifp);
 }
 
 void
@@ -2525,6 +2505,8 @@ dhcp_handledhcp(struct interface *iface,
 			    iface->name, msg);
 			free(msg);
 		}
+		if (state->state == DHS_INFORM) /* INFORM should not be NAKed */
+			return;
 		if (!(iface->ctx->options & DHCPCD_TEST)) {
 			dhcp_drop(iface, "NAK");
 			unlink(state->leasefile);

Index: src/external/bsd/dhcpcd/dist/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.7 src/external/bsd/dhcpcd/dist/dhcp6.c:1.8
--- src/external/bsd/dhcpcd/dist/dhcp6.c:1.7	Wed Nov 26 13:43:06 2014
+++ src/external/bsd/dhcpcd/dist/dhcp6.c	Wed Dec 17 20:50:08 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: dhcp6.c,v 1.7 2014/11/26 13:43:06 roy Exp $");
+ __RCSID("$NetBSD: dhcp6.c,v 1.8 2014/12/17 20:50:08 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -1698,7 +1698,7 @@ dhcp6_findaddr(struct dhcpcd_ctx *ctx, c
 
 static int
 dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
-    const uint8_t *d, size_t l)
+    const uint8_t *d, size_t l, const struct timeval *acquired)
 {
 	struct dhcp6_state *state;
 	const struct dhcp6_option *o;
@@ -1760,6 +1760,7 @@ dhcp6_findna(struct interface *ifp, uint
 				a->flags |= IPV6_AF_ONLINK | IPV6_AF_NEW;
 			a->flags &= ~IPV6_AF_STALE;
 		}
+		a->acquired = *acquired;
 		a->prefix_pltime = ntohl(iap->pltime);
 		u32 = ntohl(iap->vltime);
 		if (a->prefix_vltime != u32) {
@@ -1777,7 +1778,7 @@ dhcp6_findna(struct interface *ifp, uint
 
 static int
 dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
-    const uint8_t *d, size_t l)
+    const uint8_t *d, size_t l, const struct timeval *acquired)
 {
 	struct dhcp6_state *state;
 	const struct dhcp6_option *o, *ex;
@@ -1838,6 +1839,7 @@ dhcp6_findpd(struct interface *ifp, cons
 				a->flags |= IPV6_AF_NEW;
 		}
 
+		a->acquired = *acquired;
 		a->prefix_pltime = ntohl(pdp->pltime);
 		a->prefix_vltime = ntohl(pdp->vltime);
 
@@ -1901,7 +1903,7 @@ dhcp6_findpd(struct interface *ifp, cons
 
 static int
 dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
-    const char *sfrom)
+    const char *sfrom, const struct timeval *acquired)
 {
 	struct dhcp6_state *state;
 	const struct if_options *ifo;
@@ -1995,7 +1997,7 @@ dhcp6_findia(struct interface *ifp, cons
 		}
 		if (code == D6_OPTION_IA_PD) {
 			if (!(ifo->options & DHCPCD_NOPFXDLG) &&
-			    dhcp6_findpd(ifp, iaid, p, ol) == 0)
+			    dhcp6_findpd(ifp, iaid, p, ol, acquired) == 0)
 			{
 				syslog(LOG_WARNING,
 				    "%s: %s: DHCPv6 REPLY missing Prefix",
@@ -2003,7 +2005,8 @@ dhcp6_findia(struct interface *ifp, cons
 				continue;
 			}
 		} else if (!(ifo->options & DHCPCD_PFXDLGONLY)) {
-			if (dhcp6_findna(ifp, code, iaid, p, ol) == 0) {
+			if (dhcp6_findna(ifp, code, iaid, p, ol, acquired) == 0)
+			{
 				syslog(LOG_WARNING,
 				    "%s: %s: DHCPv6 REPLY missing IA Address",
 				    ifp->name, sfrom);
@@ -2049,10 +2052,11 @@ dhcp6_findia(struct interface *ifp, cons
 static int
 dhcp6_validatelease(struct interface *ifp,
     const struct dhcp6_message *m, size_t len,
-    const char *sfrom)
+    const char *sfrom, const struct timeval *acquired)
 {
 	struct dhcp6_state *state;
 	int nia;
+	struct timeval aq;
 
 	if (len <= sizeof(*m)) {
 		syslog(LOG_ERR, "%s: DHCPv6 lease truncated", ifp->name);
@@ -2065,7 +2069,11 @@ dhcp6_validatelease(struct interface *if
 
 	state->renew = state->rebind = state->expire = 0;
 	state->lowpl = ND6_INFINITE_LIFETIME;
-	nia = dhcp6_findia(ifp, m, len, sfrom);
+	if (!acquired) {
+		get_monotonic(&aq);
+		acquired = &aq;
+	}
+	nia = dhcp6_findia(ifp, m, len, sfrom, acquired);
 	if (nia == 0) {
 		syslog(LOG_ERR, "%s: no useable IA found in lease",
 		    ifp->name);
@@ -2104,6 +2112,7 @@ dhcp6_readlease(struct interface *ifp)
 	ssize_t bytes;
 	struct timeval now;
 	const struct dhcp6_option *o;
+	struct timeval acquired;
 
 	state = D6_STATE(ifp);
 	if (stat(state->leasefile, &st) == -1) {
@@ -2137,15 +2146,19 @@ dhcp6_readlease(struct interface *ifp)
 		goto ex;
 	}
 
+	gettimeofday(&now, NULL);
+	get_monotonic(&acquired);
+	acquired.tv_sec -= now.tv_sec - st.st_mtime;
+
 	/* Check to see if the lease is still valid */
-	fd = dhcp6_validatelease(ifp, state->new, state->new_len, NULL);
+	fd = dhcp6_validatelease(ifp, state->new, state->new_len, NULL,
+	    &acquired);
 	if (fd == -1)
 		goto ex;
 
 	if (!(ifp->ctx->options & DHCPCD_DUMPLEASE) &&
 	    state->expire != ND6_INFINITE_LIFETIME)
 	{
-		gettimeofday(&now, NULL);
 		if ((time_t)state->expire < now.tv_sec - st.st_mtime) {
 			syslog(LOG_DEBUG,"%s: discarding expired lease",
 			    ifp->name);
@@ -2274,6 +2287,7 @@ dhcp6_ifdelegateaddr(struct interface *i
 	a->dadcallback = dhcp6_dadcallback;
 	a->delegating_iface = ifs;
 	memcpy(&a->iaid, &prefix->iaid, sizeof(a->iaid));
+	a->acquired = prefix->acquired;
 	a->prefix_pltime = prefix->prefix_pltime;
 	a->prefix_vltime = prefix->prefix_vltime;
 	a->prefix = addr;
@@ -2726,7 +2740,8 @@ dhcp6_handledata(void *arg)
 			if (error == 1)
 				goto recv;
 			if (error == -1 ||
-			    dhcp6_validatelease(ifp, r, len, ctx->sfrom) == -1)
+			    dhcp6_validatelease(ifp, r, len,
+			    ctx->sfrom, NULL) == -1)
 			{
 				dhcp6_startdiscover(ifp);
 				return;
@@ -2742,7 +2757,9 @@ dhcp6_handledata(void *arg)
 		case DH6S_REQUEST: /* FALLTHROUGH */
 		case DH6S_RENEW: /* FALLTHROUGH */
 		case DH6S_REBIND:
-			if (dhcp6_validatelease(ifp, r, len, ctx->sfrom) == -1){
+			if (dhcp6_validatelease(ifp, r, len,
+			    ctx->sfrom, NULL) == -1)
+			{
 				/* PD doesn't use CONFIRM, so REBIND could
 				 * throw up an invalid prefix if we
 				 * changed link */
@@ -2787,7 +2804,7 @@ dhcp6_handledata(void *arg)
 				syslog(LOG_ERR, "%s: invalid INF_MAX_RT %d",
 				    ifp->name, u32);
 		}
-		if (dhcp6_validatelease(ifp, r, len, ctx->sfrom) == -1)
+		if (dhcp6_validatelease(ifp, r, len, ctx->sfrom, NULL) == -1)
 			return;
 		break;
 	case DHCP6_RECONFIGURE:
Index: src/external/bsd/dhcpcd/dist/ipv6.h
diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.7 src/external/bsd/dhcpcd/dist/ipv6.h:1.8
--- src/external/bsd/dhcpcd/dist/ipv6.h:1.7	Fri Nov 14 12:00:54 2014
+++ src/external/bsd/dhcpcd/dist/ipv6.h	Wed Dec 17 20:50:08 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6.h,v 1.7 2014/11/14 12:00:54 roy Exp $ */
+/* $NetBSD: ipv6.h,v 1.8 2014/12/17 20:50:08 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -85,6 +85,7 @@ struct ipv6_addr {
 	uint8_t prefix_len;
 	uint32_t prefix_vltime;
 	uint32_t prefix_pltime;
+	struct timeval acquired;
 	struct in6_addr addr;
 	int addr_flags;
 	short flags;
@@ -182,7 +183,7 @@ uint8_t ipv6_prefixlen(const struct in6_
 int ipv6_userprefix( const struct in6_addr *, short prefix_len,
     uint64_t user_number, struct in6_addr *result, short result_len);
 void ipv6_checkaddrflags(void *);
-int ipv6_addaddr(struct ipv6_addr *);
+int ipv6_addaddr(struct ipv6_addr *, const struct timeval *);
 ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs);
 void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
     const struct interface *);
Index: src/external/bsd/dhcpcd/dist/ipv6nd.h
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.h:1.7 src/external/bsd/dhcpcd/dist/ipv6nd.h:1.8
--- src/external/bsd/dhcpcd/dist/ipv6nd.h:1.7	Fri Nov 14 12:00:54 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.h	Wed Dec 17 20:50:08 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipv6nd.h,v 1.7 2014/11/14 12:00:54 roy Exp $ */
+/* $NetBSD: ipv6nd.h,v 1.8 2014/12/17 20:50:08 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -99,10 +99,7 @@ void ipv6nd_handleifa(struct dhcpcd_ctx 
     const char *, const struct in6_addr *, int);
 int ipv6nd_dadcompleted(const struct interface *);
 void ipv6nd_drop(struct interface *);
-
-#ifdef HAVE_RTM_GETNEIGH
 void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int);
-#endif
 #else
 #define ipv6nd_startrs(a) {}
 #define ipv6nd_findaddr(a, b, c) (0)

Index: src/external/bsd/dhcpcd/dist/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.38 src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.39
--- src/external/bsd/dhcpcd/dist/dhcpcd.8.in:1.38	Tue Dec  9 20:21:05 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.8.in	Wed Dec 17 20:50:08 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.8.in,v 1.38 2014/12/09 20:21:05 roy Exp $
+.\"     $NetBSD: dhcpcd.8.in,v 1.39 2014/12/17 20:50:08 roy Exp $
 .\" Copyright (c) 2006-2014 Roy Marples
 .\" All rights reserved
 .\"
@@ -426,10 +426,6 @@ is working on a single interface then
 will exit when a timeout occurs, otherwise
 .Nm
 will fork into the background.
-If using IPv4LL then
-.Nm
-start the IPv4LL process after the timeout and then wait a little longer
-before really timing out.
 .It Fl u , Fl Fl userclass Ar class
 Tags the DHCPv4 message with the userclass
 .Ar class .
@@ -481,10 +477,17 @@ then waits until this process has exited
 Allow
 .Ar reboot
 seconds before moving to the discover phase if we have an old lease to use.
+Allow
+.Ar reboot
+seconds before starting fallback states from the discover phase.
+IPv4LL is started when the first
+.Ar reboot
+timeout is reached.
 The default is 5 seconds.
 A setting of 0 seconds causes
 .Nm
 to skip the reboot phase and go straight into discover.
+This has no effect on DHCPv6 other than skipping the reboot phase.
 .El
 .Ss Restricting behaviour
 .Nm

Index: src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in
diff -u src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.16 src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.17
--- src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in:1.16	Fri Nov  7 20:51:02 2014
+++ src/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in	Wed Dec 17 20:50:08 2014
@@ -1,4 +1,4 @@
-.\"     $NetBSD: dhcpcd.conf.5.in,v 1.16 2014/11/07 20:51:02 roy Exp $
+.\"     $NetBSD: dhcpcd.conf.5.in,v 1.17 2014/12/17 20:50:08 roy Exp $
 .\" Copyright (c) 2006-2014 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 October 3, 2014
+.Dd December 13, 2014
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -377,8 +377,8 @@ will supply a default metric of 200 +
 .Xr if_nametoindex 3 .
 An extra 100 will be added for wireless interfaces.
 .It Ic noalias
-IPv4 addresses added will overwrite a pre-existing address instead of working
-alongside.
+Any pre-existing IPv4 addresses existing address will be removed from the
+interface when adding a new IPv4 address.
 .It Ic noarp
 Don't send any ARP requests.
 This also disables IPv4LL.

Index: src/external/bsd/dhcpcd/dist/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.15 src/external/bsd/dhcpcd/dist/if-bsd.c:1.16
--- src/external/bsd/dhcpcd/dist/if-bsd.c:1.15	Fri Nov  7 20:51:02 2014
+++ src/external/bsd/dhcpcd/dist/if-bsd.c	Wed Dec 17 20:50:08 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if-bsd.c,v 1.15 2014/11/07 20:51:02 roy Exp $");
+ __RCSID("$NetBSD: if-bsd.c,v 1.16 2014/12/17 20:50:08 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -49,6 +49,7 @@
 #include <net/route.h>
 #include <netinet/if_ether.h>
 #include <netinet/in.h>
+#include <netinet/in_var.h>
 #include <netinet6/in6_var.h>
 #include <netinet6/nd6.h>
 #ifdef __DragonFly__
@@ -421,40 +422,32 @@ next:
 }
 
 int
-if_address(const struct interface *iface, const struct in_addr *address,
+if_address(const struct interface *ifp, const struct in_addr *address,
     const struct in_addr *netmask, const struct in_addr *broadcast,
     int action)
 {
 	int s, r;
-	struct ifaliasreq ifa;
-	union {
-		struct sockaddr *sa;
-		struct sockaddr_in *sin;
-	} _s;
+	struct in_aliasreq ifra;
 
 	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
 		return -1;
 
-	memset(&ifa, 0, sizeof(ifa));
-	strlcpy(ifa.ifra_name, iface->name, sizeof(ifa.ifra_name));
-
-#define ADDADDR(_var, _addr) {						      \
-		_s.sa = &_var;						      \
-		_s.sin->sin_family = AF_INET;				      \
-		_s.sin->sin_len = sizeof(*_s.sin);			      \
-		memcpy(&_s.sin->sin_addr, _addr, sizeof(_s.sin->sin_addr));   \
-	}
+	memset(&ifra, 0, sizeof(ifra));
+	strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name));
 
-	ADDADDR(ifa.ifra_addr, address);
-	ADDADDR(ifa.ifra_mask, netmask);
-	if (action >= 0 && broadcast) {
-		ADDADDR(ifa.ifra_broadaddr, broadcast);
-	}
+#define ADDADDR(var, addr) do {						      \
+		(var)->sin_family = AF_INET;				      \
+		(var)->sin_len = sizeof(*(var));			      \
+		(var)->sin_addr = *(addr);				      \
+	} while (/*CONSTCOND*/0)
+	ADDADDR(&ifra.ifra_addr, address);
+	ADDADDR(&ifra.ifra_mask, netmask);
+	if (action >= 0 && broadcast)
+		ADDADDR(&ifra.ifra_broadaddr, broadcast);
 #undef ADDADDR
 
 	r = ioctl(s,
-	    action < 0 ? SIOCDIFADDR :
-	    action == 2 ? SIOCSIFADDR :  SIOCAIFADDR, &ifa);
+	    action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
 	close(s);
 	return r;
 }
@@ -590,6 +583,15 @@ ifa_scope(struct sockaddr_in6 *sin, unsi
 #endif
 }
 
+#ifdef __KAME__
+#define DESCOPE(ia6) do {						      \
+	if (IN6_IS_ADDR_LINKLOCAL((ia6)))				      \
+		(ia6)->s6_addr[2] = (ia6)->s6_addr[3] = '\0';		      \
+	} while (/*CONSTCOND */0)
+#else
+#define DESCOPE(ia6)
+#endif
+
 int
 if_address6(const struct ipv6_addr *a, int action)
 {
@@ -756,11 +758,6 @@ get_addrs(int type, char *cp, struct soc
 	for (i = 0; i < RTAX_MAX; i++) {
 		if (type & (1 << i)) {
 			sa[i] = (struct sockaddr *)cp;
-#ifdef DEBUG
-			printf ("got %d %d %s\n", i, sa[i]->sa_family,
-			    inet_ntoa(((struct sockaddr_in *)sa[i])->
-				sin_addr));
-#endif
 			RT_ADVANCE(cp, sa[i]);
 		} else
 			sa[i] = NULL;
@@ -866,16 +863,20 @@ if_managelink(struct dhcpcd_ctx *ctx)
 			dhcpcd_handlecarrier(ctx, len,
 			    (unsigned int)ifm->ifm_flags, ifp->name);
 			break;
+		case RTM_ADD:
+		case RTM_CHANGE:
 		case RTM_DELETE:
-			if (~rtm->rtm_addrs &
-			    (RTA_DST | RTA_GATEWAY | RTA_NETMASK))
-				break;
 			cp = (char *)(void *)(rtm + 1);
 			sa = (struct sockaddr *)(void *)cp;
 			get_addrs(rtm->rtm_addrs, cp, rti_info);
 			switch (sa->sa_family) {
 #ifdef INET
 			case AF_INET:
+				if (rtm->rtm_type != RTM_DELETE)
+					break;
+				if (~rtm->rtm_addrs &
+				    (RTA_DST | RTA_GATEWAY | RTA_NETMASK))
+					break;
 				memset(&rt, 0, sizeof(rt));
 				rt.iface = NULL;
 				COPYOUT(rt.dest, rti_info[RTAX_DST]);
@@ -886,6 +887,37 @@ if_managelink(struct dhcpcd_ctx *ctx)
 #endif
 #ifdef INET6
 			case AF_INET6:
+				if (~rtm->rtm_addrs &
+				    (RTA_DST | RTA_GATEWAY))
+					break;
+				/*
+				 * BSD caches host routes in the
+				 * routing table.
+				 * As such, we should be notified of
+				 * reachability by its existance
+				 * with a hardware address
+				 */
+				if (rtm->rtm_flags & (RTF_HOST)) {
+					COPYOUT6(ia6, rti_info[RTAX_DST]);
+					DESCOPE(&ia6);
+					if (rti_info[RTAX_GATEWAY]->sa_family
+					    == AF_LINK)
+						memcpy(&sdl,
+						    rti_info[RTAX_GATEWAY],
+						    sizeof(sdl));
+					else
+						sdl.sdl_alen = 0;
+					ipv6nd_neighbour(ctx, &ia6,
+					    rtm->rtm_type != RTM_DELETE &&
+					    sdl.sdl_alen ?
+					    IPV6ND_REACHABLE : 0);
+					break;
+				}
+
+				if (rtm->rtm_type != RTM_DELETE)
+					break;
+				if (!(rtm->rtm_addrs & RTA_NETMASK))
+					break;
 				memset(&rt6, 0, sizeof(rt6));
 				rt6.iface = NULL;
 				COPYOUT6(rt6.dest, rti_info[RTAX_DST]);
@@ -895,6 +927,7 @@ if_managelink(struct dhcpcd_ctx *ctx)
 				break;
 #endif
 			}
+			break;
 #ifdef RTM_CHGADDR
 		case RTM_CHGADDR:	/* FALLTHROUGH */
 #endif
@@ -938,10 +971,7 @@ if_managelink(struct dhcpcd_ctx *ctx)
 				sin6 = (struct sockaddr_in6*)(void *)
 				    rti_info[RTAX_IFA];
 				ia6 = sin6->sin6_addr;
-#ifdef __KAME__
-				if (IN6_IS_ADDR_LINKLOCAL(&ia6))
-					ia6.s6_addr[2] = ia6.s6_addr[3] = '\0';
-#endif
+				DESCOPE(&ia6);
 				if (rtm->rtm_type == RTM_NEWADDR) {
 					ifa_flags = if_addrflags6(&ia6, ifp);
 					if (ifa_flags == -1)
@@ -1041,43 +1071,6 @@ eexit:
 	return error;
 }
 
-int
-if_nd6reachable(const char *ifname, struct in6_addr *addr)
-{
-	int s, flags;
-	struct in6_nbrinfo nbi;
-
-	if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0)
-		return -1;
-
-	memset(&nbi, 0, sizeof(nbi));
-	strlcpy(nbi.ifname, ifname, sizeof(nbi.ifname));
-	nbi.addr = *addr;
-	if (ioctl(s, SIOCGNBRINFO_IN6, &nbi) == -1) {
-#ifdef __FreeBSD__
-		/* FreeBSD doesn't support reachable routers? */
-		if (errno == EINVAL)
-			errno = ENOTSUP;
-#endif
-		flags = -1;
-	} else {
-		flags = 0;
-		switch(nbi.state) {
-		case ND6_LLINFO_NOSTATE:	/* just added */
-		case ND6_LLINFO_REACHABLE:
-		case ND6_LLINFO_STALE:
-		case ND6_LLINFO_DELAY:
-		case ND6_LLINFO_PROBE:
-			flags |= IPV6ND_REACHABLE;
-			break;
-		}
-		if (nbi.isrouter)
-			flags |= IPV6ND_ROUTER;
-	}
-	close(s);
-	return flags;
-}
-
 static int
 if_raflush(void)
 {

Index: src/external/bsd/dhcpcd/dist/if.c
diff -u src/external/bsd/dhcpcd/dist/if.c:1.9 src/external/bsd/dhcpcd/dist/if.c:1.10
--- src/external/bsd/dhcpcd/dist/if.c:1.9	Tue Dec  9 20:21:05 2014
+++ src/external/bsd/dhcpcd/dist/if.c	Wed Dec 17 20:50:08 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: if.c,v 1.9 2014/12/09 20:21:05 roy Exp $");
+ __RCSID("$NetBSD: if.c,v 1.10 2014/12/17 20:50:08 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -50,12 +50,7 @@
 #ifdef SIOCGIFMEDIA
 #  include <net/if_media.h>
 #endif
-
 #include <net/route.h>
-#ifdef __linux__
-#  include <asm/types.h> /* for systems with broken headers */
-#  include <linux/rtnetlink.h>
-#endif
 
 #include <ctype.h>
 #include <errno.h>
Index: src/external/bsd/dhcpcd/dist/ipv4.c
diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.9 src/external/bsd/dhcpcd/dist/ipv4.c:1.10
--- src/external/bsd/dhcpcd/dist/ipv4.c:1.9	Wed Nov 26 16:05:14 2014
+++ src/external/bsd/dhcpcd/dist/ipv4.c	Wed Dec 17 20:50:08 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv4.c,v 1.9 2014/11/26 16:05:14 roy Exp $");
+ __RCSID("$NetBSD: ipv4.c,v 1.10 2014/12/17 20:50:08 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -35,11 +35,6 @@
 #include <arpa/inet.h>
 #include <net/route.h>
 
-#ifdef __linux__
-#  include <asm/types.h> /* for systems with broken headers */
-#  include <linux/rtnetlink.h>
-#endif
-
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -737,19 +732,25 @@ ipv4_getstate(struct interface *ifp)
 }
 
 static int
-ipv4_addaddr(const struct interface *ifp, const struct dhcp_lease *lease)
+ipv4_addaddr(struct interface *ifp, const struct dhcp_lease *lease)
 {
 	int r;
 
+	if (ifp->options->options & DHCPCD_NOALIAS) {
+		struct ipv4_state *state;
+		struct ipv4_addr *ap, *apn;
+
+		state = IPV4_STATE(ifp);
+		TAILQ_FOREACH_SAFE(ap, &state->addrs, next, apn) {
+			if (ap->addr.s_addr != lease->addr.s_addr)
+				delete_address1(ifp, &ap->addr, &ap->net);
+		}
+	}
+
 	syslog(LOG_DEBUG, "%s: adding IP address %s/%d",
 	    ifp->name, inet_ntoa(lease->addr),
 	    inet_ntocidr(lease->net));
-	if (ifp->options->options & DHCPCD_NOALIAS)
-		r = if_setaddress(ifp,
-		    &lease->addr, &lease->net, &lease->brd);
-	else
-		r = if_addaddress(ifp,
-		    &lease->addr, &lease->net, &lease->brd);
+	r = if_addaddress(ifp, &lease->addr, &lease->net, &lease->brd);
 	if (r == -1 && errno != EEXIST)
 		syslog(LOG_ERR, "%s: if_addaddress: %m", __func__);
 	return r;
@@ -876,7 +877,8 @@ ipv4_applyaddr(void *arg)
 
 	/* Now delete the old address if different */
 	if (state->addr.s_addr != lease->addr.s_addr &&
-	    state->addr.s_addr != 0)
+	    state->addr.s_addr != 0 &&
+	    ipv4_iffindaddr(ifp, &lease->addr, NULL))
 		delete_address(ifp);
 
 	state->added = STATE_ADDED;

Index: src/external/bsd/dhcpcd/dist/if.h
diff -u src/external/bsd/dhcpcd/dist/if.h:1.6 src/external/bsd/dhcpcd/dist/if.h:1.7
--- src/external/bsd/dhcpcd/dist/if.h:1.6	Fri Nov  7 20:51:02 2014
+++ src/external/bsd/dhcpcd/dist/if.h	Wed Dec 17 20:50:08 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */
+/* $NetBSD: if.h,v 1.7 2014/12/17 20:50:08 roy Exp $ */
 
 /*
  * dhcpcd - DHCP client daemon
@@ -50,13 +50,6 @@
 # endif
 #endif
 
-/* Neighbour reachability and router updates */
-#ifndef HAVE_RTM_GETNEIGH
-# ifdef __linux__
-#  define HAVE_RTM_GETNEIGH
-# endif
-#endif
-
 #define EUI64_ADDR_LEN			8
 #define INFINIBAND_ADDR_LEN		20
 
@@ -120,12 +113,10 @@ ssize_t if_readrawpacket(struct interfac
 int if_address(const struct interface *,
     const struct in_addr *, const struct in_addr *,
     const struct in_addr *, int);
-#define if_addaddress(iface, addr, net, brd)				      \
-	if_address(iface, addr, net, brd, 1)
-#define if_setaddress(iface, addr, net, brd)				      \
-	if_address(iface, addr, net, brd, 2)
-#define if_deladdress(iface, addr, net)				      \
-	if_address(iface, addr, net, NULL, -1)
+#define if_addaddress(ifp, addr, net, brd)	\
+	if_address(ifp, addr, net, brd, 1)
+#define if_deladdress(ifp, addr, net)		\
+	if_address(ifp, addr, net, NULL, -1)
 
 int if_route(const struct rt *rt, int);
 #define if_addroute(rt) if_route(rt, 1)
@@ -135,11 +126,11 @@ int if_route(const struct rt *rt, int);
 
 #ifdef INET6
 int if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *, int);
-int if_nd6reachable(const char *ifname, struct in6_addr *addr);
 
 int if_address6(const struct ipv6_addr *, int);
 #define if_addaddress6(a) if_address6(a, 1)
 #define if_deladdress6(a) if_address6(a, -1)
+
 int if_addrflags6(const struct in6_addr *, const struct interface *);
 
 int if_route6(const struct rt6 *rt, int);
Index: src/external/bsd/dhcpcd/dist/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.6 src/external/bsd/dhcpcd/dist/ipv6.c:1.7
--- src/external/bsd/dhcpcd/dist/ipv6.c:1.6	Fri Nov  7 20:51:03 2014
+++ src/external/bsd/dhcpcd/dist/ipv6.c	Wed Dec 17 20:50:08 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6.c,v 1.6 2014/11/07 20:51:03 roy Exp $");
+ __RCSID("$NetBSD: ipv6.c,v 1.7 2014/12/17 20:50:08 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -39,8 +39,6 @@
 #include <netinet/if_ether.h>
 
 #ifdef __linux__
-#  include <asm/types.h> /* for systems with broken headers */
-#  include <linux/rtnetlink.h>
    /* Match Linux defines to BSD */
 #  ifdef IFA_F_OPTIMISTIC
 #    define IN6_IFF_TENTATIVE	(IFA_F_TENTATIVE | IFA_F_OPTIMISTIC)
@@ -607,11 +605,13 @@ ipv6_deleteaddr(struct ipv6_addr *addr)
 }
 
 int
-ipv6_addaddr(struct ipv6_addr *ap)
+ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
 {
 	struct interface *ifp;
 	struct ipv6_state *state;
 	struct ipv6_addr *nap;
+	struct timeval n;
+	uint32_t pltime, vltime;
 
 	/* Ensure no other interface has this address */
 	TAILQ_FOREACH(ifp, ap->iface->ctx->ifaces, next) {
@@ -628,6 +628,24 @@ ipv6_addaddr(struct ipv6_addr *ap)
 		}
 	}
 
+	/* Adjust plftime and vltime based on acquired time */
+	pltime = ap->prefix_pltime;
+	vltime = ap->prefix_vltime;
+	if (timerisset(&ap->acquired) &&
+	    (ap->prefix_pltime != ND6_INFINITE_LIFETIME ||
+	    ap->prefix_vltime != ND6_INFINITE_LIFETIME))
+	{
+		if (now == NULL) {
+			get_monotonic(&n);
+			now = &n;
+		}
+		timersub(now, &ap->acquired, &n);
+		if (ap->prefix_pltime != ND6_INFINITE_LIFETIME)
+			ap->prefix_pltime -= n.tv_sec;
+		if (ap->prefix_vltime != ND6_INFINITE_LIFETIME)
+			ap->prefix_vltime -= n.tv_sec;
+	}
+
 	syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
 	    "%s: adding address %s", ap->iface->name, ap->saddr);
 	if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
@@ -635,8 +653,15 @@ ipv6_addaddr(struct ipv6_addr *ap)
 		ap->flags |= IPV6_AF_DADCOMPLETED;
 	if (if_addaddress6(ap) == -1) {
 		syslog(LOG_ERR, "if_addaddress6: %m");
+		/* Restore real pltime and vltime */
+		ap->prefix_pltime = pltime;
+		ap->prefix_vltime = vltime;
 		return -1;
 	}
+
+	/* Restore real pltime and vltime */
+	ap->prefix_pltime = pltime;
+	ap->prefix_vltime = vltime;
 	ap->flags &= ~IPV6_AF_NEW;
 	ap->flags |= IPV6_AF_ADDED;
 	if (ap->delegating_iface)
@@ -700,8 +725,10 @@ ipv6_addaddrs(struct ipv6_addrhead *addr
 {
 	struct ipv6_addr *ap, *apn, *apf;
 	ssize_t i;
+	struct timeval now;
 
 	i = 0;
+	timerclear(&now);
 	TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
 		if (ap->prefix_vltime == 0) {
 			if (ap->flags & IPV6_AF_ADDED) {
@@ -746,7 +773,9 @@ ipv6_addaddrs(struct ipv6_addrhead *addr
 				apf->flags &= ~IPV6_AF_ADDED;
 			if (ap->flags & IPV6_AF_NEW)
 				i++;
-			ipv6_addaddr(ap);
+			if (!timerisset(&now))
+				get_monotonic(&now);
+			ipv6_addaddr(ap, &now);
 		}
 	}
 
@@ -758,7 +787,9 @@ ipv6_freedrop_addrs(struct ipv6_addrhead
     const struct interface *ifd)
 {
 	struct ipv6_addr *ap, *apn, *apf;
+	struct timeval now;
 
+	timerclear(&now);
 	TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
 		if (ifd && ap->delegating_iface != ifd)
 			continue;
@@ -777,7 +808,11 @@ ipv6_freedrop_addrs(struct ipv6_addrhead
 				ipv6_deleteaddr(ap);
 			if (!(ap->iface->options->options &
 			    DHCPCD_EXITING) && apf)
-				ipv6_addaddr(apf);
+			{
+				if (!timerisset(&now))
+					get_monotonic(&now);
+				ipv6_addaddr(apf, &now);
+			}
 		}
 		free(ap);
 	}
@@ -1083,7 +1118,7 @@ nextslaacprivate:
 
 	inet_ntop(AF_INET6, &ap->addr, ap->saddr, sizeof(ap->saddr));
 	TAILQ_INSERT_TAIL(&state->addrs, ap, next);
-	ipv6_addaddr(ap);
+	ipv6_addaddr(ap, NULL);
 	return 1;
 }
 

Index: src/external/bsd/dhcpcd/dist/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.18 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.19
--- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.18	Wed Nov 26 13:43:06 2014
+++ src/external/bsd/dhcpcd/dist/ipv6nd.c	Wed Dec 17 20:50:08 2014
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
- __RCSID("$NetBSD: ipv6nd.c,v 1.18 2014/11/26 13:43:06 roy Exp $");
+ __RCSID("$NetBSD: ipv6nd.c,v 1.19 2014/12/17 20:50:08 roy Exp $");
 
 /*
  * dhcpcd - DHCP client daemon
@@ -32,6 +32,7 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <net/if.h>
+#include <net/route.h>
 #include <netinet/in.h>
 #include <netinet/ip6.h>
 #include <netinet/icmp6.h>
@@ -118,8 +119,6 @@ struct nd_opt_dnssl {		/* DNSSL option R
 #define IPV6_ADDR_INT16_MLL     0x02ff
 #endif
 
-#define ND6REACHABLE_TIMER	1
-
 /* Debugging Neighbor Solicitations is a lot of spam, so disable it */
 //#define DEBUG_NS
 //
@@ -332,8 +331,6 @@ ipv6nd_reachable(struct ra *rap, int fla
 			script_runreason(rap->iface, "ROUTERADVERT");
 		}
 	} else {
-		/* Any error means it's really gone from the kernel
-		 * neighbour database */
 		if (rap->lifetime && !rap->expired) {
 			syslog(LOG_WARNING,
 			    "%s: %s is unreachable, expiring it",
@@ -346,7 +343,6 @@ ipv6nd_reachable(struct ra *rap, int fla
 	}
 }
 
-#ifdef HAVE_RTM_GETNEIGH
 void
 ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, int flags)
 {
@@ -362,33 +358,6 @@ ipv6nd_neighbour(struct dhcpcd_ctx *ctx,
 	}
 }
 
-#else
-
-static void
-ipv6nd_checkreachablerouters(void *arg)
-{
-	struct dhcpcd_ctx *ctx = arg;
-	struct ra *rap;
-	int flags;
-
-	TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
-		flags = if_nd6reachable(rap->iface->name, &rap->from);
-		if (flags == -1) {
-			if (errno == ENOTSUP)
-				/* Unsupported? We have to assume reachable */
-				flags = IPV6ND_REACHABLE;
-			else
-				/* An error occured, so it's unreachable */
-				flags = 0;
-		}
-		ipv6nd_reachable(rap, flags);
-	}
-
-	eloop_timeout_add_sec(ctx->eloop, ND6REACHABLE_TIMER,
-	    ipv6nd_checkreachablerouters, ctx);
-}
-#endif
-
 static void
 ipv6nd_free_opts(struct ra *rap)
 {
@@ -434,11 +403,6 @@ void ipv6nd_freedrop_ra(struct ra *rap, 
 	eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap);
 	if (!drop)
 		TAILQ_REMOVE(rap->iface->ctx->ipv6->ra_routers, rap, next);
-#ifndef HAVE_RTM_GETNEIGH
-	if (TAILQ_FIRST(rap->iface->ctx->ipv6->ra_routers) == NULL)
-		eloop_timeout_delete(rap->iface->ctx->eloop,
-		    ipv6nd_checkreachablerouters, rap->iface->ctx);
-#endif
 	ipv6_freedrop_addrs(&rap->addrs, drop, NULL);
 	ipv6nd_free_opts(rap);
 	free(rap->data);
@@ -588,7 +552,7 @@ ipv6nd_addaddr(void *arg)
 {
 	struct ipv6_addr *ap = arg;
 
-	ipv6_addaddr(ap);
+	ipv6_addaddr(ap, NULL);
 }
 
 int
@@ -935,6 +899,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, st
 			if (pi->nd_opt_pi_flags_reserved &
 			    ND_OPT_PI_FLAG_ONLINK)
 				ap->flags |= IPV6_AF_ONLINK;
+			ap->acquired = rap->received;
 			ap->prefix_vltime =
 			    ntohl(pi->nd_opt_pi_valid_time);
 			ap->prefix_pltime =
@@ -1130,12 +1095,6 @@ nodhcp6:
 
 	/* Expire should be called last as the rap object could be destroyed */
 	ipv6nd_expirera(ifp);
-
-#ifndef HAVE_RTM_GETNEIGH
-	/* Start our reachability tests now */
-	eloop_timeout_add_sec(ifp->ctx->eloop, ND6REACHABLE_TIMER,
-	    ipv6nd_checkreachablerouters, ifp->ctx);
-#endif
 }
 
 int
@@ -1423,11 +1382,8 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, st
 	struct nd_neighbor_advert *nd_na;
 	struct ra *rap;
 	int is_router, is_solicited;
-
-	if ((size_t)len < sizeof(struct nd_neighbor_advert)) {
-		syslog(LOG_ERR, "IPv6 NA packet too short from %s", ctx->sfrom);
-		return;
-	}
+	char buf[INET6_ADDRSTRLEN];
+	const char *taddr;
 
 	if (ifp == NULL) {
 #ifdef DEBUG_NS
@@ -1437,13 +1393,21 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, st
 		return;
 	}
 
+	if ((size_t)len < sizeof(struct nd_neighbor_advert)) {
+		syslog(LOG_ERR, "%s: IPv6 NA too short from %s",
+		    ifp->name, ctx->sfrom);
+		return;
+	}
+
 	nd_na = (struct nd_neighbor_advert *)icp;
 	is_router = nd_na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER;
 	is_solicited = nd_na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED;
+	taddr = inet_ntop(AF_INET6, &nd_na->nd_na_target,
+	    buf, INET6_ADDRSTRLEN);
 
 	if (IN6_IS_ADDR_MULTICAST(&nd_na->nd_na_target)) {
-		syslog(LOG_ERR, "%s: NA for multicast address from %s",
-		    ifp->name, ctx->sfrom);
+		syslog(LOG_ERR, "%s: NA multicast address %s (%s)",
+		    ifp->name, taddr, ctx->sfrom);
 		return;
 	}
 
@@ -1454,21 +1418,21 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, st
 	}
 	if (rap == NULL) {
 #ifdef DEBUG_NS
-		syslog(LOG_DEBUG, "%s: unexpected NA from s",
-		    ifp->name, ctx->sfrom);
+		syslog(LOG_DEBUG, "%s: unexpected NA from %s for %s",
+		    ifp->name, ctx->sfrom, taddr);
 #endif
 		return;
 	}
 
 #ifdef DEBUG_NS
-	syslog(LOG_DEBUG, "%s: %sNA from %s",
-	    ifp->name, is_solicited ? "solicited " : "", ctx->sfrom);
+	syslog(LOG_DEBUG, "%s: %sNA for %s from %s",
+	    ifp->name, is_solicited ? "solicited " : "", taddr, ctx->sfrom);
 #endif
 
 	/* Node is no longer a router, so remove it from consideration */
 	if (!is_router && !rap->expired) {
-		syslog(LOG_INFO, "%s: %s is no longer a router",
-		    ifp->name, ctx->sfrom);
+		syslog(LOG_INFO, "%s: %s not a router (%s)",
+		    ifp->name, taddr, ctx->sfrom);
 		rap->expired = 1;
 		ipv6_buildroutes(ifp->ctx);
 		script_runreason(ifp, "ROUTERADVERT");
@@ -1478,8 +1442,8 @@ ipv6nd_handlena(struct ipv6_ctx *ctx, st
 	if (is_solicited && is_router && rap->lifetime) {
 		if (rap->expired) {
 			rap->expired = 0;
-			syslog(LOG_INFO, "%s: %s is reachable again",
-			    ifp->name, ctx->sfrom);
+			syslog(LOG_INFO, "%s: %s reachable (%s)",
+			    ifp->name, taddr, ctx->sfrom);
 			ipv6_buildroutes(ifp->ctx);
 			script_runreason(rap->iface, "ROUTERADVERT"); /* XXX */
 		}

Reply via email to