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 */ }