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="