Module Name: src Committed By: roy Date: Sun Oct 9 09:18:26 UTC 2016
Modified Files: src/external/bsd/dhcpcd/dist: arp.c auth.h common.c common.h config.h defs.h dhcp.c dhcp6.c dhcp6.h dhcpcd.c dhcpcd.h if-bsd.c if-options.c if.c if.h ipv4.c ipv4.h ipv4ll.c ipv4ll.h ipv6.c ipv6.h ipv6nd.c script.c Removed Files: src/external/bsd/dhcpcd/dist: dhcpcd-embedded.c dhcpcd-embedded.h Log Message: Sync To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/arp.c \ src/external/bsd/dhcpcd/dist/ipv6.c cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/auth.h cvs rdiff -u -r1.20 -r1.21 src/external/bsd/dhcpcd/dist/common.c \ src/external/bsd/dhcpcd/dist/ipv6.h cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/common.h cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/config.h cvs rdiff -u -r1.30 -r1.31 src/external/bsd/dhcpcd/dist/defs.h cvs rdiff -u -r1.46 -r1.47 src/external/bsd/dhcpcd/dist/dhcp.c cvs rdiff -u -r1.25 -r1.26 src/external/bsd/dhcpcd/dist/dhcp6.c \ src/external/bsd/dhcpcd/dist/ipv4.c cvs rdiff -u -r1.15 -r1.16 src/external/bsd/dhcpcd/dist/dhcp6.h cvs rdiff -u -r1.13 -r0 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.c cvs rdiff -u -r1.10 -r0 src/external/bsd/dhcpcd/dist/dhcpcd-embedded.h cvs rdiff -u -r1.36 -r1.37 src/external/bsd/dhcpcd/dist/dhcpcd.c cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/dhcpcd.h \ src/external/bsd/dhcpcd/dist/ipv4.h cvs rdiff -u -r1.33 -r1.34 src/external/bsd/dhcpcd/dist/if-bsd.c cvs rdiff -u -r1.35 -r1.36 src/external/bsd/dhcpcd/dist/if-options.c cvs rdiff -u -r1.23 -r1.24 src/external/bsd/dhcpcd/dist/if.c cvs rdiff -u -r1.18 -r1.19 src/external/bsd/dhcpcd/dist/if.h \ src/external/bsd/dhcpcd/dist/ipv4ll.c cvs rdiff -u -r1.12 -r1.13 src/external/bsd/dhcpcd/dist/ipv4ll.h cvs rdiff -u -r1.32 -r1.33 src/external/bsd/dhcpcd/dist/ipv6nd.c cvs rdiff -u -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/script.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/dhcpcd/dist/arp.c diff -u src/external/bsd/dhcpcd/dist/arp.c:1.21 src/external/bsd/dhcpcd/dist/arp.c:1.22 --- src/external/bsd/dhcpcd/dist/arp.c:1.21 Fri Jul 29 10:07:57 2016 +++ src/external/bsd/dhcpcd/dist/arp.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: arp.c,v 1.21 2016/07/29 10:07:57 roy Exp $"); + __RCSID("$NetBSD: arp.c,v 1.22 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -448,6 +448,8 @@ arp_handleifa(int cmd, struct ipv4_addr struct iarp_state *state; struct arp_state *astate, *asn; + /* If the address is deleted, the ARP state should be freed by the + * state owner, such as DHCP or IPv4LL. */ if (cmd != RTM_NEWADDR || (state = ARP_STATE(addr->iface)) == NULL) return; Index: src/external/bsd/dhcpcd/dist/ipv6.c diff -u src/external/bsd/dhcpcd/dist/ipv6.c:1.21 src/external/bsd/dhcpcd/dist/ipv6.c:1.22 --- src/external/bsd/dhcpcd/dist/ipv6.c:1.21 Mon Aug 15 11:04:53 2016 +++ src/external/bsd/dhcpcd/dist/ipv6.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv6.c,v 1.21 2016/08/15 11:04:53 roy Exp $"); + __RCSID("$NetBSD: ipv6.c,v 1.22 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -104,20 +104,22 @@ #if defined(HAVE_IN6_ADDR_GEN_MODE_NONE) || defined(ND6_IFF_AUTO_LINKLOCAL) || \ defined(IFF_NOLINKLOCAL) -/* If we're using a private SLAAC address on wireless, - * don't add it until we have associated as we randomise - * it based on the SSID. */ -#define CAN_ADD_LLADDR(ifp) \ - (!((ifp)->options->options & DHCPCD_SLAACPRIVATE) || \ - (ifp)->carrier != LINK_DOWN) -#elif __NetBSD__ -/* Earlier versions of NetBSD don't add duplicate LLADDR's if the interface - * is brought up and one already exists. */ -#define CAN_ADD_LLADDR(ifp) (1) +/* Only add the LL address if we have a carrier, so DaD works. */ +#define CAN_ADD_LLADDR(ifp) \ + (!((ifp)->options->options & DHCPCD_LINK) || (ifp)->carrier != LINK_DOWN) +#ifdef __sun +/* Although we can add our own LL address, we cannot drop it + * without unplumbing the if which is a lot of code. + * So just keep it for the time being. */ +#define CAN_DROP_LLADDR(ifp) (0) +#else +#define CAN_DROP_LLADDR(ifp) (1) +#endif #else /* We have no control over the OS adding the LLADDR, so just let it do it * as we cannot force our own view on it. */ -#define CAN_ADD_LLADDR(ifp) (0) +#define CAN_ADD_LLADDR(ifp) (0) +#define CAN_DROP_LLADDR(ifp) (0) #endif #ifdef IPV6_MANAGETEMPADDR @@ -163,13 +165,11 @@ ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx) ctx->sndhdr.msg_controllen = sizeof(ctx->sndbuf); ctx->rcvhdr.msg_name = &ctx->from; ctx->rcvhdr.msg_namelen = sizeof(ctx->from); - ctx->rcvhdr.msg_iov = ctx->rcviov; + ctx->rcvhdr.msg_iov = dhcpcd_ctx->iov; ctx->rcvhdr.msg_iovlen = 1; - ctx->rcvhdr.msg_control = ctx->rcvbuf; + ctx->rcvhdr.msg_control = ctx->ctlbuf; // controllen is set at recieve //ctx->rcvhdr.msg_controllen = sizeof(ctx->rcvbuf); - ctx->rcviov[0].iov_base = ctx->ansbuf; - ctx->rcviov[0].iov_len = sizeof(ctx->ansbuf); ctx->nd_fd = -1; ctx->dhcp_fd = -1; @@ -344,6 +344,11 @@ ipv6_makestableprivate(struct in6_addr * uint32_t dad; int r; + if (ifp->ctx->secret_len == 0) { + if (ipv6_readsecret(ifp->ctx) == -1) + return -1; + } + dad = (uint32_t)*dad_counter; /* For our implementation, we shall set the hardware address @@ -372,10 +377,6 @@ ipv6_makeaddr(struct in6_addr *addr, str } if (ifp->options->options & DHCPCD_SLAACPRIVATE) { - if (ifp->ctx->secret_len == 0) { - if (ipv6_readsecret(ifp->ctx) == -1) - return -1; - } dad = 0; if (ipv6_makestableprivate(addr, prefix, prefix_len, ifp, &dad) == -1) @@ -571,20 +572,25 @@ ipv6_checkaddrflags(void *arg) { struct ipv6_addr *ia; int flags; + const char *alias; ia = arg; - if ((flags = if_addrflags6(ia)) == -1) { +#ifdef ALIAS_ADDR + alias = ia->alias; +#else + alias = NULL; +#endif + if ((flags = if_addrflags6(ia->iface, &ia->addr, alias)) == -1) { logger(ia->iface->ctx, LOG_ERR, "%s: if_addrflags6: %m", ia->iface->name); return; } - ia->addr_flags = flags; if (!(ia->addr_flags & IN6_IFF_TENTATIVE)) { /* Simulate the kernel announcing the new address. */ ipv6_handleifa(ia->iface->ctx, RTM_NEWADDR, ia->iface->ctx->ifaces, ia->iface->name, - &ia->addr, ia->prefix_len); + &ia->addr, ia->prefix_len, flags); } else { /* Still tentative? Check again in a bit. */ struct timespec tv; @@ -605,8 +611,9 @@ ipv6_deleteaddr(struct ipv6_addr *ia) logger(ia->iface->ctx, LOG_INFO, "%s: deleting address %s", ia->iface->name, ia->saddr); if (if_address6(RTM_DELADDR, ia) == -1 && - errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV) - logger(ia->iface->ctx, LOG_ERR, "if_address6: :%m"); + errno != EADDRNOTAVAIL && errno != ESRCH && + errno != ENXIO && errno != ENODEV) + logger(ia->iface->ctx, LOG_ERR, "if_address6: %m"); /* NOREJECT is set if we delegated exactly the prefix to another * address. @@ -1007,8 +1014,8 @@ ipv6_freedrop_addrs(struct ipv6_addrhead (DHCPCD_EXITING | DHCPCD_PERSISTENT)) { /* Don't drop link-local addresses. */ - if (!(IN6_IS_ADDR_LINKLOCAL(&ap->addr) && - CAN_ADD_LLADDR(ap->iface))) + if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr) || + CAN_DROP_LLADDR(ap->iface)) { if (drop == 2) TAILQ_REMOVE(addrs, ap, next); @@ -1063,13 +1070,12 @@ ipv6_getstate(struct interface *ifp) void ipv6_handleifa(struct dhcpcd_ctx *ctx, int cmd, struct if_head *ifs, const char *ifname, - const struct in6_addr *addr, uint8_t prefix_len) + const struct in6_addr *addr, uint8_t prefix_len, int addrflags) { struct interface *ifp; struct ipv6_state *state; struct ipv6_addr *ia; struct ll_callback *cb; - int flags; #if 0 char dbuf[INET6_ADDRSTRLEN]; @@ -1151,14 +1157,7 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx, ia->acquired = ia->created; TAILQ_INSERT_TAIL(&state->addrs, ia, next); } - flags = if_addrflags6(ia); - if (flags == -1) { - logger(ia->iface->ctx, LOG_ERR, - "%s: %s: if_addrflags6: %m", - ia->iface->name, ia->saddr); - return; - } - ia->addr_flags = flags; + ia->addr_flags = addrflags; #ifdef IPV6_MANAGETEMPADDR if (ia->addr_flags & IN6_IFF_TEMPORARY) ia->flags |= IPV6_AF_TEMPORARY; @@ -1439,14 +1438,28 @@ nextslaacprivate: static int ipv6_tryaddlinklocal(struct interface *ifp) { + struct ipv6_addr *ia; /* We can't assign a link-locak address to this, * the ppp process has to. */ if (ifp->flags & IFF_POINTOPOINT) return 0; - if (ipv6_iffindaddr(ifp, NULL, IN6_IFF_DUPLICATED) != NULL || - !CAN_ADD_LLADDR(ifp)) + ia = ipv6_iffindaddr(ifp, NULL, IN6_IFF_DUPLICATED); + if (ia != NULL) { +#ifdef IPV6_POLLADDRFLAG + if (ia->addr_flags & IN6_IFF_TENTATIVE) { + struct timespec tv; + + ms_to_ts(&tv, RETRANS_TIMER / 2); + eloop_timeout_add_tv( + ia->iface->ctx->eloop, + &tv, ipv6_checkaddrflags, ia); + } +#endif + return 0; + } + if (!CAN_ADD_LLADDR(ifp)) return 0; return ipv6_addlinklocal(ifp); @@ -1599,6 +1612,27 @@ ipv6_startstatic(struct interface *ifp) int ipv6_start(struct interface *ifp) { +#ifdef IPV6_POLLADDRFLAG + struct ipv6_state *state; + + /* We need to update the address flags. */ + if ((state = IPV6_STATE(ifp)) != NULL) { + struct ipv6_addr *ia; + const char *alias; + int flags; + + TAILQ_FOREACH(ia, &state->addrs, next) { +#ifdef ALIAS_ADDR + alias = ia->alias; +#else + alias = NULL; +#endif + flags = if_addrflags6(ia->iface, &ia->addr, alias); + if (flags != -1) + ia->addr_flags = flags; + } + } +#endif if (ipv6_tryaddlinklocal(ifp) == -1) return -1; @@ -1612,8 +1646,6 @@ ipv6_start(struct interface *ifp) /* Load existing routes */ if_initrt6(ifp->ctx); - if (!IN6_IS_ADDR_UNSPECIFIED(&ifp->options->req_addr6)) - ipv6_buildroutes(ifp->ctx); return 0; } @@ -1629,6 +1661,12 @@ ipv6_freedrop(struct interface *ifp, int if ((state = IPV6_STATE(ifp)) == NULL) return; + /* If we got here, we can get rid of any LL callbacks. */ + while ((cb = TAILQ_FIRST(&state->ll_callbacks))) { + TAILQ_REMOVE(&state->ll_callbacks, cb, next); + free(cb); + } + ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL); if (drop) { if (ifp->ctx->ipv6 != NULL) { @@ -1638,10 +1676,6 @@ ipv6_freedrop(struct interface *ifp, int } else { /* Because we need to cache the addresses we don't control, * we only free the state on when NOT dropping addresses. */ - while ((cb = TAILQ_FIRST(&state->ll_callbacks))) { - TAILQ_REMOVE(&state->ll_callbacks, cb, next); - free(cb); - } free(state); ifp->if_data[IF_DATA_IPV6] = NULL; eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); @@ -1786,8 +1820,6 @@ ipv6_gentempifid(struct interface *ifp) state->randomseed1, sizeof(state->randomseed1)); again: - /* RFC4941 Section 3.2.1.1 - * Take the left-most 64bits and set bit 6 to zero */ MD5Init(&md5); MD5Update(&md5, seed, sizeof(seed)); MD5Final(digest, &md5); @@ -2257,8 +2289,22 @@ nc_route(struct rt6 *ort, struct rt6 *nr /* No route metrics, we need to delete the old route before * adding the new one. */ +#ifdef ROUTE_PER_GATEWAY + errno = 0; +#endif if (ort && if_route6(RTM_DELETE, ort) == -1 && errno != ESRCH) - logger(nrt->iface->ctx, LOG_ERR, "if_route6: %m"); + logger(nrt->iface->ctx, LOG_ERR, "if_route6 (DEL): %m"); +#ifdef ROUTE_PER_GATEWAY + /* The OS allows many routes to the same dest with different gateways. + * dhcpcd does not support this yet, so for the time being just keep on + * deleting the route until there is an error. */ + if (ort && errno == 0) { + for (;;) { + if (if_route6(RTM_DELETE, ort) == -1) + break; + } + } +#endif if (if_route6(RTM_ADD, nrt) != -1) return 0; #ifdef HAVE_ROUTE_METRIC Index: src/external/bsd/dhcpcd/dist/auth.h diff -u src/external/bsd/dhcpcd/dist/auth.h:1.9 src/external/bsd/dhcpcd/dist/auth.h:1.10 --- src/external/bsd/dhcpcd/dist/auth.h:1.9 Sat May 16 23:31:32 2015 +++ src/external/bsd/dhcpcd/dist/auth.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: auth.h,v 1.9 2015/05/16 23:31:32 roy Exp $ */ +/* $NetBSD: auth.h,v 1.10 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -65,12 +65,14 @@ TAILQ_HEAD(token_head, token); struct auth { int options; +#ifdef AUTH uint8_t protocol; uint8_t algorithm; uint8_t rdm; uint64_t last_replay; uint8_t last_replay_set; struct token_head tokens; +#endif }; struct authstate { Index: src/external/bsd/dhcpcd/dist/common.c diff -u src/external/bsd/dhcpcd/dist/common.c:1.20 src/external/bsd/dhcpcd/dist/common.c:1.21 --- src/external/bsd/dhcpcd/dist/common.c:1.20 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/common.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: common.c,v 1.20 2016/05/09 10:15:59 roy Exp $"); + __RCSID("$NetBSD: common.c,v 1.21 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -30,7 +30,11 @@ #include <sys/param.h> #include <sys/time.h> +#ifdef __sun +#include <sys/sysmacros.h> +#endif +#include <assert.h> #include <ctype.h> #include <err.h> #include <errno.h> @@ -56,6 +60,9 @@ # define _PATH_DEVNULL "/dev/null" #endif +/* Most route(4) messages are less than 256 bytes. */ +#define IOVEC_BUFSIZ 256 + #if USE_LOGFILE void logger_open(struct dhcpcd_ctx *ctx) @@ -377,3 +384,51 @@ read_hwaddr_aton(uint8_t **data, const c fclose(fp); return len; } + +ssize_t +recvmsg_realloc(int fd, struct msghdr *msg, int flags) +{ + struct iovec *iov; + ssize_t slen; + size_t len; + void *n; + + assert(msg != NULL); + assert(msg->msg_iov != NULL && msg->msg_iovlen > 0); + assert((flags & (MSG_PEEK | MSG_TRUNC)) == 0); + + /* Assume we are reallocing the last iovec. */ + iov = &msg->msg_iov[msg->msg_iovlen - 1]; + + for (;;) { + /* Passing MSG_TRUNC should return the actual size needed. */ + slen = recvmsg(fd, msg, flags | MSG_PEEK | MSG_TRUNC); + if (slen == -1) + return -1; + if (!(msg->msg_flags & MSG_TRUNC)) + break; + + len = (size_t)slen; + + /* Some kernels return the size of the receive buffer + * on truncation, not the actual size needed. + * So grow the buffer and try again. */ + if (iov->iov_len == len) + len++; + else if (iov->iov_len > len) + break; + len = roundup(len, IOVEC_BUFSIZ); + if ((n = realloc(iov->iov_base, len)) == NULL) + return -1; + iov->iov_base = n; + iov->iov_len = len; + } + + slen = recvmsg(fd, msg, flags); + if (slen != -1 && msg->msg_flags & MSG_TRUNC) { + /* This should not be possible ... */ + errno = ENOBUFS; + return -1; + } + return slen; +} Index: src/external/bsd/dhcpcd/dist/ipv6.h diff -u src/external/bsd/dhcpcd/dist/ipv6.h:1.20 src/external/bsd/dhcpcd/dist/ipv6.h:1.21 --- src/external/bsd/dhcpcd/dist/ipv6.h:1.20 Fri Jul 29 10:07:58 2016 +++ src/external/bsd/dhcpcd/dist/ipv6.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ipv6.h,v 1.20 2016/07/29 10:07:58 roy Exp $ */ +/* $NetBSD: ipv6.h,v 1.21 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -262,17 +262,14 @@ struct ipv6_state { #define IP6BUFLEN (CMSG_SPACE(sizeof(struct in6_pktinfo)) + \ CMSG_SPACE(sizeof(int))) - #ifdef INET6 struct ipv6_ctx { + unsigned char ctlbuf[IP6BUFLEN]; struct sockaddr_in6 from; struct msghdr sndhdr; - struct iovec sndiov[2]; + struct iovec sndiov[1]; unsigned char sndbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; struct msghdr rcvhdr; - struct iovec rcviov[2]; - unsigned char rcvbuf[IP6BUFLEN]; - unsigned char ansbuf[1500]; char ntopbuf[INET6_ADDRSTRLEN]; const char *sfrom; @@ -302,7 +299,7 @@ ssize_t ipv6_addaddrs(struct ipv6_addrhe void ipv6_freedrop_addrs(struct ipv6_addrhead *, int, const struct interface *); void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *, - const char *, const struct in6_addr *, uint8_t); + const char *, const struct in6_addr *, uint8_t, int); int ipv6_handleifa_addrs(int, struct ipv6_addrhead *, const struct ipv6_addr *); struct ipv6_addr *ipv6_iffindaddr(struct interface *, const struct in6_addr *, int); Index: src/external/bsd/dhcpcd/dist/common.h diff -u src/external/bsd/dhcpcd/dist/common.h:1.14 src/external/bsd/dhcpcd/dist/common.h:1.15 --- src/external/bsd/dhcpcd/dist/common.h:1.14 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/common.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: common.h,v 1.14 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: common.h,v 1.15 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -167,6 +167,10 @@ int get_monotonic(struct timespec *); * However, this results in a ugly output on the command line * and relies on syslogd(8) starting before dhcpcd which is not * always the case. */ +#ifdef SMALL +# undef USE_LOGFILE +# define USE_LOGFILE 0 +#endif #ifndef USE_LOGFILE # define USE_LOGFILE 1 #endif @@ -198,4 +202,6 @@ ssize_t addvard(struct dhcpcd_ctx *, char *hwaddr_ntoa(const uint8_t *, size_t, char *, size_t); size_t hwaddr_aton(uint8_t *, const char *); size_t read_hwaddr_aton(uint8_t **, const char *); + +ssize_t recvmsg_realloc(int, struct msghdr *, int); #endif Index: src/external/bsd/dhcpcd/dist/config.h diff -u src/external/bsd/dhcpcd/dist/config.h:1.11 src/external/bsd/dhcpcd/dist/config.h:1.12 --- src/external/bsd/dhcpcd/dist/config.h:1.11 Mon May 9 10:15:59 2016 +++ src/external/bsd/dhcpcd/dist/config.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: config.h,v 1.11 2016/05/09 10:15:59 roy Exp $ */ +/* $NetBSD: config.h,v 1.12 2016/10/09 09:18:26 roy Exp $ */ /* netbsd */ #define SYSCONFDIR "/etc" @@ -7,6 +7,9 @@ #define LIBEXECDIR "/libexec" #define DBDIR "/var/db" #define RUNDIR "/var/run" +#define HAVE_IFAM_PID +#define HAVE_IFAM_ADDRFLAGS +#define HAVE_IFADDRS_ADDRFLAGS #define HAVE_UTIL_H #define HAVE_SYS_QUEUE_H #define HAVE_SPAWN_H Index: src/external/bsd/dhcpcd/dist/defs.h diff -u src/external/bsd/dhcpcd/dist/defs.h:1.30 src/external/bsd/dhcpcd/dist/defs.h:1.31 --- src/external/bsd/dhcpcd/dist/defs.h:1.30 Mon Aug 15 11:04:53 2016 +++ src/external/bsd/dhcpcd/dist/defs.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: defs.h,v 1.30 2016/08/15 11:04:53 roy Exp $ */ +/* $NetBSD: defs.h,v 1.31 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -30,7 +30,7 @@ #define CONFIG_H #define PACKAGE "dhcpcd" -#define VERSION "6.11.3" +#define VERSION "6.11.4" #ifndef CONFIG # define CONFIG SYSCONFDIR "/" PACKAGE ".conf" Index: src/external/bsd/dhcpcd/dist/dhcp.c diff -u src/external/bsd/dhcpcd/dist/dhcp.c:1.46 src/external/bsd/dhcpcd/dist/dhcp.c:1.47 --- src/external/bsd/dhcpcd/dist/dhcp.c:1.46 Sun Sep 18 15:37:23 2016 +++ src/external/bsd/dhcpcd/dist/dhcp.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: dhcp.c,v 1.46 2016/09/18 15:37:23 christos Exp $"); + __RCSID("$NetBSD: dhcp.c,v 1.47 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -742,7 +742,7 @@ make_message(struct bootp **bootpm, cons const char *hostname; const struct vivco *vivco; int mtu; -#ifndef NO_AUTH +#ifdef AUTH uint8_t *auth, auth_len; #endif @@ -977,6 +977,7 @@ make_message(struct bootp **bootpm, cons p += ifo->vendor[0] + 1; } +#ifdef AUTH if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) != DHCPCD_AUTH_SENDREQUIRE) { @@ -986,6 +987,7 @@ make_message(struct bootp **bootpm, cons *p++ = 1; *p++ = AUTH_ALG_HMAC_MD5; } +#endif if (ifo->vivco_len) { AREA_CHECK(sizeof(ul)); @@ -1059,11 +1061,9 @@ make_message(struct bootp **bootpm, cons *n_params = (uint8_t)(p - n_params - 1); } -#ifndef NO_AUTH - /* silence GCC */ +#ifdef AUTH + auth = NULL; /* appease GCC */ auth_len = 0; - auth = NULL; - if (ifo->auth.options & DHCPCD_AUTH_SEND) { ssize_t alen = dhcp_auth_encode(&ifo->auth, state->auth.token, @@ -1085,6 +1085,7 @@ make_message(struct bootp **bootpm, cons } } #endif + *p++ = DHO_END; len = (size_t)(p - (uint8_t *)bootp); @@ -1097,7 +1098,7 @@ make_message(struct bootp **bootpm, cons *p++ = DHO_PAD; len++; } -#ifndef NO_AUTH +#ifdef AUTH if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0) dhcp_auth_encode(&ifo->auth, state->auth.token, (uint8_t *)bootp, len, 4, type, auth, auth_len); @@ -1138,9 +1139,9 @@ read_lease(struct interface *ifp, struct uint8_t *lease; size_t bytes; uint8_t type; -#ifndef NO_AUTH - size_t auth_len; +#ifdef AUTH const uint8_t *auth; + size_t auth_len; #endif /* Safety */ @@ -1194,7 +1195,7 @@ read_lease(struct interface *ifp, struct DHO_MESSAGETYPE) == -1) type = 0; -#ifndef NO_AUTH +#ifdef AUTH /* Authenticate the message */ auth = get_option(ifp->ctx, (struct bootp *)lease, bytes, DHO_AUTHENTICATION, &auth_len); @@ -1223,6 +1224,7 @@ read_lease(struct interface *ifp, struct return 0; } #endif + out: *bootp = (struct bootp *)lease; return bytes; @@ -1845,9 +1847,11 @@ dhcp_discover(void *arg) if (ifo->fallback) eloop_timeout_add_sec(ifp->ctx->eloop, ifo->reboot, dhcp_fallback, ifp); +#ifdef IPV4LL else if (ifo->options & DHCPCD_IPV4LL) eloop_timeout_add_sec(ifp->ctx->eloop, ifo->reboot, ipv4ll_start, ifp); +#endif if (ifo->options & DHCPCD_REQUEST) logger(ifp->ctx, LOG_INFO, "%s: soliciting a DHCP lease (requesting %s)", @@ -2510,10 +2514,12 @@ dhcp_reboot(struct interface *ifp) state->lease.server.s_addr = 0; eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); +#ifdef IPV4LL /* Need to add this before dhcp_expire and friends. */ if (!ifo->fallback && ifo->options & DHCPCD_IPV4LL) eloop_timeout_add_sec(ifp->ctx->eloop, ifo->reboot, ipv4ll_start, ifp); +#endif if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo) eloop_timeout_add_sec(ifp->ctx->eloop, @@ -2571,7 +2577,7 @@ dhcp_drop(struct interface *ifp, const c } eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); -#ifndef NO_AUTH +#ifdef AUTH dhcp_auth_reset(&state->auth); #endif dhcp_close(ifp); @@ -2698,13 +2704,13 @@ dhcp_handledhcp(struct interface *ifp, s unsigned int i; char *msg; bool bootp_copied; -#ifdef IN_IFF_DUPLICATED - struct ipv4_addr *ia; -#endif -#ifndef NO_AUTH const uint8_t *auth; +#ifdef AUTH size_t auth_len; #endif +#ifdef IN_IFF_DUPLICATED + struct ipv4_addr *ia; +#endif #define LOGDHCP0(l, m) \ log_dhcp((l), (m), ifp, bootp, bootp_len, from, 0) @@ -2741,8 +2747,8 @@ dhcp_handledhcp(struct interface *ifp, s return; } +#ifdef AUTH /* Authenticate the message */ -#ifndef NO_AUTH auth = get_option(ifp->ctx, bootp, bootp_len, DHO_AUTHENTICATION, &auth_len); if (auth) { @@ -2769,7 +2775,10 @@ dhcp_handledhcp(struct interface *ifp, s } LOGDHCP0(LOG_WARNING, "no authentication"); } +#else + auth = NULL; #endif + /* RFC 3203 */ if (type == DHCP_FORCERENEW) { if (from->s_addr == INADDR_ANY || @@ -2778,13 +2787,11 @@ dhcp_handledhcp(struct interface *ifp, s LOGDHCP(LOG_ERR, "discarding Force Renew"); return; } -#ifndef NO_AUTH if (auth == NULL) { LOGDHCP(LOG_ERR, "unauthenticated Force Renew"); if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) return; } -#endif if (state->state != DHS_BOUND && state->state != DHS_INFORM) { LOGDHCP(LOG_DEBUG, "not bound, ignoring Force Renew"); return; @@ -2906,6 +2913,7 @@ dhcp_handledhcp(struct interface *ifp, s "%s: message: %s", ifp->name, msg); free(msg); } +#ifdef IPV4LL if (state->state == DHS_DISCOVER && get_option_uint8(ifp->ctx, &tmp, bootp, bootp_len, DHO_AUTOCONFIGURE) == 0) @@ -2930,6 +2938,7 @@ dhcp_handledhcp(struct interface *ifp, s eloop_timeout_add_sec(ifp->ctx->eloop, DHCP_MAX, dhcp_discover, ifp); } +#endif return; } @@ -3580,11 +3589,13 @@ dhcp_start1(void *arg) } } +#ifdef IPV4LL if (!(ifo->options & DHCPCD_DHCP)) { if (ifo->options & DHCPCD_IPV4LL) ipv4ll_start(ifp); return; } +#endif if (state->offer == NULL || !IS_DHCP(state->offer)) dhcp_discover(ifp); @@ -3671,9 +3682,12 @@ dhcp_handleifa(int cmd, struct ipv4_addr return; if (cmd == RTM_DELADDR) { - if (IPV4_BRD_EQ(state->addr, ia)) { + if (state->addr == ia) { logger(ifp->ctx, LOG_INFO, "%s: deleted IP address %s", ifp->name, ia->saddr); + state->addr = NULL; + /* Don't clear the added state as we need + * to drop the lease. */ dhcp_drop(ifp, "EXPIRE"); } return; Index: src/external/bsd/dhcpcd/dist/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/dhcp6.c:1.25 src/external/bsd/dhcpcd/dist/dhcp6.c:1.26 --- src/external/bsd/dhcpcd/dist/dhcp6.c:1.25 Sun Sep 18 15:37:23 2016 +++ src/external/bsd/dhcpcd/dist/dhcp6.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: dhcp6.c,v 1.25 2016/09/18 15:37:23 christos Exp $"); + __RCSID("$NetBSD: dhcp6.c,v 1.26 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -75,6 +75,7 @@ #define IPV6_RECVPKTINFO IPV6_PKTINFO #endif +#ifdef DHCP6 struct dhcp6_op { uint16_t type; const char *name; @@ -360,6 +361,7 @@ dhcp6_newxid(const struct interface *ifp m->xid[2] = xid & 0xff; } +#ifndef SMALL static const struct if_sla * dhcp6_findselfsla(struct interface *ifp, const uint8_t *iaid) { @@ -492,31 +494,36 @@ dhcp6_delegateaddr(struct in6_addr *addr return sla->prefix_len; } +#endif static int dhcp6_makemessage(struct interface *ifp) { struct dhcp6_state *state; struct dhcp6_message *m; - struct dhcp6_option *o, *so, *eo; + struct dhcp6_option *o, *so; const struct dhcp6_option *si, *unicast; size_t l, n, len, ml; - uint8_t u8, type; + uint8_t type; uint16_t u16, n_options; struct if_options *ifo; const struct dhcp_opt *opt, *opt2; uint8_t IA, *p; - const uint8_t *pp; uint32_t u32; const struct ipv6_addr *ap; char hbuf[HOSTNAME_MAX_LEN + 1]; const char *hostname; int fqdn; struct dhcp6_ia_addr *iap; - struct dhcp6_pd_addr *pdp; -#ifndef NO_AUTH +#ifdef AUTH uint16_t auth_len; #endif +#ifndef SMALL + struct dhcp6_option *eo; + struct dhcp6_pd_addr *pdp; + uint8_t u8; + const uint8_t *pp; +#endif state = D6_STATE(ifp); if (state->send) { @@ -564,6 +571,7 @@ dhcp6_makemessage(struct interface *ifp) len += sizeof(u16); } } +#ifndef SMALL for (l = 0, opt = ifo->dhcp6_override; l < ifo->dhcp6_override_len; l++, opt++) @@ -580,6 +588,7 @@ dhcp6_makemessage(struct interface *ifp) n_options++; len += sizeof(u16); } +#endif if (len) len += sizeof(*o); @@ -633,6 +642,7 @@ dhcp6_makemessage(struct interface *ifp) !(ap->flags & IPV6_AF_REQUEST)) continue; if (ap->ia_type == D6_OPTION_IA_PD) { +#ifndef SMALL len += sizeof(*o) + sizeof(u8) + sizeof(u32) + sizeof(u32) + sizeof(ap->prefix); @@ -640,6 +650,7 @@ dhcp6_makemessage(struct interface *ifp) len += sizeof(*o) + 1 + (uint8_t)((ap->prefix_exclude_len - ap->prefix_len - 1) / NBBY) + 1; +#endif } else len += sizeof(*o) + sizeof(ap->addr) + sizeof(u32) + sizeof(u32); @@ -695,7 +706,7 @@ dhcp6_makemessage(struct interface *ifp) return -1; } -#ifndef NO_AUTH +#ifdef AUTH auth_len = 0; if (ifo->auth.options & DHCPCD_AUTH_SEND) { ssize_t alen = dhcp_auth_encode(&ifo->auth, @@ -776,6 +787,7 @@ dhcp6_makemessage(struct interface *ifp) continue; so = D6_NEXT_OPTION(o); if (ap->ia_type == D6_OPTION_IA_PD) { +#ifndef SMALL so->code = htons(D6_OPTION_IAPREFIX); so->len = htons(sizeof(ap->prefix) + sizeof(u32) + sizeof(u32) + sizeof(u8)); @@ -814,6 +826,7 @@ dhcp6_makemessage(struct interface *ifp) u16 = (uint16_t)(ntohs(o->len) + sizeof(*so) + ntohs(so->len)); o->len = htons(u16); +#endif } else { so->code = htons(D6_OPTION_IA_ADDR); so->len = sizeof(ap->addr) + @@ -870,6 +883,7 @@ dhcp6_makemessage(struct interface *ifp) l < ifp->ctx->dhcp6_opts_len; l++, opt++) { +#ifndef SMALL for (n = 0, opt2 = ifo->dhcp6_override; n < ifo->dhcp6_override_len; n++, opt2++) @@ -879,6 +893,7 @@ dhcp6_makemessage(struct interface *ifp) } if (n < ifo->dhcp6_override_len) continue; +#endif if (!(opt->type & OT_NOREQ) && (opt->type & OT_REQUEST || has_option_mask(ifo->requestmask6, @@ -890,6 +905,7 @@ dhcp6_makemessage(struct interface *ifp) o->len = (uint16_t)(o->len+sizeof(u16)); } } +#ifndef SMALL for (l = 0, opt = ifo->dhcp6_override; l < ifo->dhcp6_override_len; l++, opt++) @@ -910,12 +926,13 @@ dhcp6_makemessage(struct interface *ifp) memcpy(p, &u16, sizeof(u16)); o->len = (uint16_t)(o->len + sizeof(u16)); } +#endif o->len = htons(o->len); } } +#ifdef AUTH /* This has to be the last option */ -#ifndef NO_AUTH if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0) { o = D6_NEXT_OPTION(o); o->code = htons(D6_OPTION_AUTH); @@ -952,6 +969,7 @@ dhcp6_freedrop_addrs(struct interface *i } } +#ifndef SMALL static void dhcp6_delete_delegates(struct interface *ifp) { struct interface *ifp0; @@ -963,8 +981,9 @@ static void dhcp6_delete_delegates(struc } } } +#endif -#ifndef NO_AUTH +#ifdef AUTH static ssize_t dhcp6_update_auth(struct interface *ifp, struct dhcp6_message *m, size_t len) { @@ -1124,7 +1143,7 @@ logsend: /* Update the elapsed time */ dhcp6_updateelapsed(ifp, state->send, state->send_len); -#ifndef NO_AUTH +#ifdef AUTH if (ifp->options->auth.options & DHCPCD_AUTH_SEND && dhcp6_update_auth(ifp, state->send, state->send_len) == -1) { @@ -1385,7 +1404,9 @@ dhcp6_startdiscover(void *arg) struct dhcp6_state *state; ifp = arg; +#ifndef SMALL dhcp6_delete_delegates(ifp); +#endif logger(ifp->ctx, LOG_INFO, "%s: soliciting a DHCPv6 lease", ifp->name); state = D6_STATE(ifp); state->state = DH6S_DISCOVER; @@ -1440,6 +1461,9 @@ dhcp6_failrequest(void *arg) dhcp6_startdiscover(ifp); } +#ifdef SMALL +#define dhcp6_hasprefixdelegation(a) (0) +#else static void dhcp6_failrebind(void *arg) { @@ -1455,7 +1479,6 @@ dhcp6_failrebind(void *arg) dhcp6_startdiscover(ifp); } - static int dhcp6_hasprefixdelegation(struct interface *ifp) { @@ -1473,13 +1496,16 @@ dhcp6_hasprefixdelegation(struct interfa } return t == D6_OPTION_IA_PD ? 1 : 0; } +#endif static void dhcp6_startrebind(void *arg) { struct interface *ifp; struct dhcp6_state *state; +#ifndef SMALL int pd; +#endif ifp = arg; eloop_timeout_delete(ifp->ctx->eloop, dhcp6_sendrenew, ifp); @@ -1494,13 +1520,16 @@ dhcp6_startrebind(void *arg) state->RTC = 0; state->MRC = 0; +#ifndef SMALL /* RFC 3633 section 12.1 */ pd = dhcp6_hasprefixdelegation(ifp); if (pd) { state->IMD = CNF_MAX_DELAY; state->IRT = CNF_TIMEOUT; state->MRT = CNF_MAX_RT; - } else { + } else +#endif + { state->IRT = REB_TIMEOUT; state->MRT = REB_MAX_RT; } @@ -1511,10 +1540,12 @@ dhcp6_startrebind(void *arg) else dhcp6_sendrebind(ifp); +#ifndef SMALL /* RFC 3633 section 12.1 */ if (pd) eloop_timeout_add_sec(ifp->ctx->eloop, CNF_MAX_RD, dhcp6_failrebind, ifp); +#endif } @@ -1601,7 +1632,9 @@ dhcp6_startexpire(void *arg) logger(ifp->ctx, LOG_ERR, "%s: DHCPv6 lease expired", ifp->name); dhcp6_freedrop_addrs(ifp, 1, NULL); +#ifndef SMALL dhcp6_delete_delegates(ifp); +#endif script_runreason(ifp, "EXPIRE6"); if (ipv6nd_hasradhcp(ifp) || dhcp6_hasprefixdelegation(ifp)) dhcp6_startdiscover(ifp); @@ -1837,6 +1870,7 @@ dhcp6_findna(struct interface *ifp, uint return i; } +#ifndef SMALL static int dhcp6_findpd(struct interface *ifp, const uint8_t *iaid, const uint8_t *d, size_t l, const struct timespec *acquired) @@ -1979,6 +2013,7 @@ dhcp6_findpd(struct interface *ifp, cons } return i; } +#endif static int dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l, @@ -2091,12 +2126,14 @@ dhcp6_findia(struct interface *ifp, cons continue; } if (code == D6_OPTION_IA_PD) { +#ifndef SMALL if (dhcp6_findpd(ifp, iaid, p, ol, acquired) == 0) { logger(ifp->ctx, LOG_WARNING, "%s: %s: DHCPv6 REPLY missing Prefix", ifp->name, sfrom); continue; } +#endif } else { if (dhcp6_findna(ifp, code, iaid, p, ol, acquired) == 0) { @@ -2138,7 +2175,7 @@ dhcp6_validatelease(struct interface *if const char *sfrom, const struct timespec *acquired) { struct dhcp6_state *state; - int nia; + int ok, nia; struct timespec aq; if (len <= sizeof(*m)) { @@ -2148,7 +2185,7 @@ dhcp6_validatelease(struct interface *if } state = D6_STATE(ifp); - if (dhcp6_checkstatusok(ifp, m, NULL, len) == -1) + if ((ok = dhcp6_checkstatusok(ifp, m, NULL, len)) == -1) return -1; state->renew = state->rebind = state->expire = 0; @@ -2159,9 +2196,19 @@ dhcp6_validatelease(struct interface *if } nia = dhcp6_findia(ifp, m, len, sfrom, acquired); if (nia == 0) { - logger(ifp->ctx, LOG_ERR, - "%s: no useable IA found in lease", ifp->name); - return -1; + if (state->state != DH6S_CONFIRM && ok != 1) { + logger(ifp->ctx, LOG_ERR, + "%s: no useable IA found in lease", ifp->name); + return -1; + } + + /* We are confirming and have an OK, + * so look for ia's in our old lease. + * IA's must have existed here otherwise we would + * have rejected it earlier. */ + assert(state->new != NULL && state->new_len != 0); + nia = dhcp6_findia(ifp, state->new, state->new_len, + sfrom, acquired); } return nia; } @@ -2198,7 +2245,7 @@ dhcp6_readlease(struct interface *ifp, i time_t now; int retval; bool fd_opened; -#ifndef NO_AUTH +#ifdef AUTH const struct dhcp6_option *o; #endif @@ -2264,7 +2311,7 @@ dhcp6_readlease(struct interface *ifp, i auth: retval = 0; -#ifndef NO_AUTH +#ifdef AUTH /* Authenticate the message */ o = dhcp6_getmoption(D6_OPTION_AUTH, state->new, state->new_len); if (o) { @@ -2293,6 +2340,7 @@ auth: goto ex; } #endif + return fd; ex: @@ -2343,9 +2391,11 @@ dhcp6_startinit(struct interface *ifp) ifp->name, state->leasefile); } else if (r != 0) { /* RFC 3633 section 12.1 */ +#ifndef SMALL if (dhcp6_hasprefixdelegation(ifp)) dhcp6_startrebind(ifp); else +#endif dhcp6_startconfirm(ifp); return; } @@ -2353,6 +2403,7 @@ dhcp6_startinit(struct interface *ifp) dhcp6_startdiscover(ifp); } +#ifndef SMALL static struct ipv6_addr * dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix, const struct if_sla *sla, struct if_ia *if_ia) @@ -2446,6 +2497,7 @@ dhcp6_ifdelegateaddr(struct interface *i return ia; } +#endif static void dhcp6_script_try_run(struct interface *ifp, int delegated) @@ -2482,6 +2534,14 @@ dhcp6_script_try_run(struct interface *i "%s: waiting for DHCPv6 DAD to complete", ifp->name); } +#ifdef SMALL +size_t +dhcp6_find_delegates(__unused struct interface *ifp) +{ + + return 0; +} +#else static void dhcp6_delegate_prefix(struct interface *ifp) { @@ -2638,6 +2698,7 @@ dhcp6_find_delegates(struct interface *i } return k; } +#endif /* ARGSUSED */ static void @@ -2653,21 +2714,17 @@ dhcp6_handledata(void *arg) const char *op; struct dhcp6_message *r; struct dhcp6_state *state; - const struct dhcp6_option *o; + const struct dhcp6_option *o, *auth; const struct dhcp_opt *opt; const struct if_options *ifo; struct ipv6_addr *ap; - uint8_t has_new; - int error; + bool valid_op, has_new; uint32_t u32; -#ifndef NO_AUTH - const struct dhcp6_option *auth; -#endif dctx = arg; ctx = dctx->ipv6; ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); - bytes = recvmsg(ctx->dhcp_fd, &ctx->rcvhdr, 0); + bytes = recvmsg_realloc(ctx->dhcp_fd, &ctx->rcvhdr, 0); if (bytes == -1) { logger(dctx, LOG_ERR, "%s: recvmsg: %m", __func__); close(ctx->dhcp_fd); @@ -2788,7 +2845,8 @@ dhcp6_handledata(void *arg) return; } } -#ifndef NO_AUTH + +#ifdef AUTH /* Authenticate the message */ auth = dhcp6_getmoption(D6_OPTION_AUTH, r, len); if (auth) { @@ -2819,9 +2877,12 @@ dhcp6_handledata(void *arg) logger(ifp->ctx, LOG_WARNING, "%s: no authentication from %s", ifp->name, ctx->sfrom); } +#else + auth = NULL; #endif op = dhcp6_get_op(r->type); + valid_op = op != NULL; switch(r->type) { case DHCP6_REPLY: switch(state->state) { @@ -2841,14 +2902,7 @@ dhcp6_handledata(void *arg) } break; case DH6S_CONFIRM: - error = dhcp6_checkstatusok(ifp, r, NULL, len); - /* If we got an OK status the chances are that we - * didn't get the IA's returned, so preserve them - * from our saved response */ - if (error == 1) - goto recv; - if (error == -1 || - dhcp6_validatelease(ifp, r, len, + if (dhcp6_validatelease(ifp, r, len, ctx->sfrom, NULL) == -1) { dhcp6_startdiscover(ifp); @@ -2856,12 +2910,16 @@ dhcp6_handledata(void *arg) } break; case DH6S_DISCOVER: - if (has_option_mask(ifo->requestmask6, - D6_OPTION_RAPID_COMMIT) && - dhcp6_getmoption(D6_OPTION_RAPID_COMMIT, r, len)) - state->state = DH6S_REQUEST; - else - op = NULL; + /* Only accept REPLY in DISCOVER for RAPID_COMMIT. + * Normally we get an ADVERTISE for a DISCOVER. */ + if (!has_option_mask(ifo->requestmask6, + D6_OPTION_RAPID_COMMIT) || + !dhcp6_getmoption(D6_OPTION_RAPID_COMMIT, r, len)) + { + valid_op = false; + break; + } + /* Validate lease before setting state to REQUEST. */ /* FALLTHROUGH */ case DH6S_REQUEST: /* FALLTHROUGH */ case DH6S_RENEW: /* FALLTHROUGH */ @@ -2869,21 +2927,27 @@ dhcp6_handledata(void *arg) if (dhcp6_validatelease(ifp, r, len, ctx->sfrom, NULL) == -1) { +#ifndef SMALL /* PD doesn't use CONFIRM, so REBIND could * throw up an invalid prefix if we * changed link */ - if (dhcp6_hasprefixdelegation(ifp)) + if (state->state == DH6S_REBIND && + dhcp6_hasprefixdelegation(ifp)) dhcp6_startdiscover(ifp); +#endif return; } + if (state->state == DH6S_DISCOVER) + state->state = DH6S_REQUEST; break; default: - op = NULL; + valid_op = false; + break; } break; case DHCP6_ADVERTISE: if (state->state != DH6S_DISCOVER) { - op = NULL; + valid_op = false; break; } /* RFC7083 */ @@ -2920,7 +2984,6 @@ dhcp6_handledata(void *arg) return; break; case DHCP6_RECONFIGURE: -#ifndef NO_AUTH if (auth == NULL) { logger(ifp->ctx, LOG_ERR, "%s: unauthenticated %s from %s", @@ -2928,7 +2991,6 @@ dhcp6_handledata(void *arg) if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) return; } -#endif logger(ifp->ctx, LOG_INFO, "%s: %s from %s", ifp->name, op, ctx->sfrom); o = dhcp6_getmoption(D6_OPTION_RECONF_MSG, r, len); @@ -2976,7 +3038,7 @@ dhcp6_handledata(void *arg) ifp->name, op, r->type); return; } - if (op == NULL) { + if (!valid_op) { logger(ifp->ctx, LOG_WARNING, "%s: invalid state for DHCP6 type %s (%d)", ifp->name, op, r->type); @@ -3013,11 +3075,10 @@ dhcp6_handledata(void *arg) return; } -recv: - has_new = 0; + has_new = false; TAILQ_FOREACH(ap, &state->addrs, next) { if (ap->flags & IPV6_AF_NEW) { - has_new = 1; + has_new = true; break; } } @@ -3081,18 +3142,10 @@ recv: state->renew = state->rebind = 0; } } - if (state->renew == 0) { - if (state->expire == ND6_INFINITE_LIFETIME) - state->renew = ND6_INFINITE_LIFETIME; - else if (state->lowpl != ND6_INFINITE_LIFETIME) - state->renew = (uint32_t)(state->lowpl * 0.5); - } - if (state->rebind == 0) { - if (state->expire == ND6_INFINITE_LIFETIME) - state->rebind = ND6_INFINITE_LIFETIME; - else if (state->lowpl != ND6_INFINITE_LIFETIME) - state->rebind = (uint32_t)(state->lowpl * 0.8); - } + if (state->renew == 0 && state->lowpl != ND6_INFINITE_LIFETIME) + state->renew = (uint32_t)(state->lowpl * 0.5); + if (state->rebind == 0 && state->lowpl != ND6_INFINITE_LIFETIME) + state->rebind = (uint32_t)(state->lowpl * 0.8); break; default: state->reason = "UNKNOWN6"; @@ -3147,7 +3200,9 @@ recv: if_initrt6(ifp->ctx); ipv6_buildroutes(ifp->ctx); dhcp6_writelease(ifp); +#ifndef SMALL dhcp6_delegate_prefix(ifp); +#endif dhcp6_script_try_run(ifp, 0); } @@ -3230,6 +3285,7 @@ errexit: return -1; } +#ifndef SMALL static void dhcp6_activateinterfaces(struct interface *ifp) { @@ -3259,6 +3315,7 @@ dhcp6_activateinterfaces(struct interfac } } } +#endif static void dhcp6_start1(void *arg) @@ -3290,9 +3347,11 @@ dhcp6_start1(void *arg) add_option_mask(ifo->requestmask6, D6_OPTION_FQDN); } +#ifndef SMALL /* Rapid commit won't work with Prefix Delegation Exclusion */ if (dhcp6_findselfsla(ifp, NULL)) del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT); +#endif if (state->state == DH6S_INFORM) { add_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME); @@ -3302,7 +3361,9 @@ dhcp6_start1(void *arg) dhcp6_startinit(ifp); } +#ifndef SMALL dhcp6_activateinterfaces(ifp); +#endif } int @@ -3329,7 +3390,9 @@ dhcp6_start(struct interface *ifp, enum } /* We're already running DHCP6 */ /* XXX: What if the managed flag vanishes from all RA? */ +#ifndef SMALL dhcp6_activateinterfaces(ifp); +#endif return 0; } @@ -3388,7 +3451,9 @@ dhcp6_freedrop(struct interface *ifp, in struct dhcp6_state *state; struct dhcpcd_ctx *ctx; unsigned long long options; +#ifndef SMALL int dropdele; +#endif /* * As the interface is going away from dhcpcd we need to @@ -3410,14 +3475,18 @@ dhcp6_freedrop(struct interface *ifp, in options = ifp->options->options; else options = ifp->ctx->options; +#ifndef SMALL dropdele = (options & (DHCPCD_STOPPING | DHCPCD_RELEASE) && (options & DHCPCD_NODROP) != DHCPCD_NODROP); +#endif if (ifp->ctx->eloop) eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); +#ifndef SMALL if (dropdele) dhcp6_delete_delegates(ifp); +#endif state = D6_STATE(ifp); if (state) { @@ -3491,8 +3560,10 @@ dhcp6_free(struct interface *ifp) dhcp6_freedrop(ifp, 0, NULL); } -void dhcp6_dropnondelegates(struct interface *ifp) +void +dhcp6_dropnondelegates(struct interface *ifp) { +#ifndef SMALL struct dhcp6_state *state; struct ipv6_addr *ia; @@ -3502,6 +3573,7 @@ void dhcp6_dropnondelegates(struct inter if (ia->flags & (IPV6_AF_DELEGATED | IPV6_AF_DELEGATEDPFX)) return; } +#endif dhcp6_drop(ifp, "EXPIRE6"); } @@ -3680,3 +3752,4 @@ dhcp6_dump(struct interface *ifp) state->reason = "DUMP6"; return script_runreason(ifp, state->reason); } +#endif Index: src/external/bsd/dhcpcd/dist/ipv4.c diff -u src/external/bsd/dhcpcd/dist/ipv4.c:1.25 src/external/bsd/dhcpcd/dist/ipv4.c:1.26 --- src/external/bsd/dhcpcd/dist/ipv4.c:1.25 Mon Aug 15 11:04:53 2016 +++ src/external/bsd/dhcpcd/dist/ipv4.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv4.c,v 1.25 2016/08/15 11:04:53 roy Exp $"); + __RCSID("$NetBSD: ipv4.c,v 1.26 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -40,6 +40,7 @@ #include <assert.h> #include <ctype.h> #include <errno.h> +#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -198,14 +199,14 @@ int ipv4_hasaddr(const struct interface *ifp) { const struct dhcp_state *dstate; - const struct ipv4ll_state *istate; + + if (IPV4LL_STATE_RUNNING(ifp)) + return 1; dstate = D_CSTATE(ifp); - istate = IPV4LL_CSTATE(ifp); - return ((dstate && + return (dstate && dstate->added == STATE_ADDED && - dstate->addr != NULL) || - (istate && istate->addr)); + dstate->addr != NULL); } void @@ -395,6 +396,19 @@ ipv4_handlert(struct dhcpcd_ctx *ctx, in return flags ? 0 : ipv4ll_handlert(ctx, cmd, rt); } +static void +d_kroute(struct rt *rt) +{ + struct dhcpcd_ctx *ctx; + + ctx = rt->iface->ctx; + rt = ipv4_findrt(ctx, rt, 1); + if (rt != NULL) { + TAILQ_REMOVE(ctx->ipv4_kroutes, rt, next); + free(rt); + } +} + #define n_route(a) nc_route(NULL, a) #define c_route(a, b) nc_route(a, b) static int @@ -472,8 +486,26 @@ nc_route(struct rt *ort, struct rt *nrt) /* No route metrics, we need to delete the old route before * adding the new one. */ - if (ort && if_route(RTM_DELETE, ort) == -1 && errno != ESRCH) - logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m"); +#ifdef ROUTE_PER_GATEWAY + errno = 0; +#endif + if (ort) { + if (if_route(RTM_DELETE, ort) == -1 && errno != ESRCH) + logger(nrt->iface->ctx, LOG_ERR, "if_route (DEL): %m"); + else + d_kroute(ort); + } +#ifdef ROUTE_PER_GATEWAY + /* The OS allows many routes to the same dest with different gateways. + * dhcpcd does not support this yet, so for the time being just keep on + * deleting the route until there is an error. */ + if (ort && errno == 0) { + for (;;) { + if (if_route(RTM_DELETE, ort) == -1) + break; + } + } +#endif if (if_route(RTM_ADD, nrt) != -1) return 0; #ifdef HAVE_ROUTE_METRIC @@ -493,6 +525,10 @@ d_route(struct rt *rt) if (retval == -1 && errno != ENOENT && errno != ESRCH) logger(rt->iface->ctx, LOG_ERR, "%s: if_delroute: %m", rt->iface->name); + /* Remove the route from our kernel table so we can add a + * IPv4LL default route if possible. */ + else + d_kroute(rt); return retval; } @@ -643,7 +679,8 @@ add_router_host_route(struct rt_head *rt return rt; TAILQ_FOREACH(rtp, rt, next) { - if (rtp->dest.s_addr != INADDR_ANY) + if (rtp->dest.s_addr != INADDR_ANY || + rtp->gate.s_addr == INADDR_ANY) continue; /* Scan for a route to match */ TAILQ_FOREACH(rtn, rt, next) { @@ -838,7 +875,7 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx) /* Remove old routes we used to manage */ if (ctx->ipv4_routes) { - TAILQ_FOREACH(rt, ctx->ipv4_routes, next) { + TAILQ_FOREACH_REVERSE(rt, ctx->ipv4_routes, rt_head, next) { if (find_route(nrs, rt, NULL) == NULL && (rt->iface->options->options & (DHCPCD_EXITING | DHCPCD_PERSISTENT)) != @@ -862,8 +899,9 @@ ipv4_deladdr(struct ipv4_addr *addr, int "%s: deleting IP address %s", addr->iface->name, addr->saddr); r = if_address(RTM_DELADDR, addr); - if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO && - errno != ENODEV) + if (r == -1 && + errno != EADDRNOTAVAIL && errno != ESRCH && + errno != ENXIO && errno != ENODEV) logger(addr->iface->ctx, LOG_ERR, "%s: %s: %m", addr->iface->name, __func__); @@ -899,7 +937,10 @@ delete_address(struct interface *ifp) state = D_STATE(ifp); ifo = ifp->options; - if (ifo->options & DHCPCD_INFORM || + /* The lease could have been added, but the address deleted + * by a 3rd party. */ + if (state->addr == NULL || + ifo->options & DHCPCD_INFORM || (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0)) return 0; r = ipv4_deladdr(state->addr, 0); @@ -1235,12 +1276,12 @@ void ipv4_handleifa(struct dhcpcd_ctx *ctx, int cmd, struct if_head *ifs, const char *ifname, const struct in_addr *addr, const struct in_addr *mask, - const struct in_addr *brd) + const struct in_addr *brd, const int addrflags) { struct interface *ifp; struct ipv4_state *state; struct ipv4_addr *ia; - int flags; + bool ia_is_new; if (ifs == NULL) ifs = ctx->ifaces; @@ -1265,28 +1306,28 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx, } ia->iface = ifp; ia->addr = *addr; + ia->mask = *mask; + ia_is_new = true; #ifdef ALIAS_ADDR strlcpy(ia->alias, ifname, sizeof(ia->alias)); #endif TAILQ_INSERT_TAIL(&state->addrs, ia, next); - } + } else + ia_is_new = false; /* Mask could have changed */ - ia->mask = *mask; - snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d", - inet_ntoa(*addr), inet_ntocidr(*mask)); + if (ia_is_new || + (mask->s_addr != INADDR_ANY && + mask->s_addr != ia->mask.s_addr)) + { + ia->mask = *mask; + snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d", + inet_ntoa(*addr), inet_ntocidr(*mask)); + } if (brd != NULL) ia->brd = *brd; else ia->brd.s_addr = INADDR_ANY; - - flags = if_addrflags(ia); - if (flags == -1) { - logger(ia->iface->ctx, LOG_ERR, - "%s: %s: if_addrflags: %m", - ia->iface->name, ia->saddr); - return; - } - ia->addr_flags = flags; + ia->addr_flags = addrflags; break; case RTM_DELADDR: if (ia == NULL) Index: src/external/bsd/dhcpcd/dist/dhcp6.h diff -u src/external/bsd/dhcpcd/dist/dhcp6.h:1.15 src/external/bsd/dhcpcd/dist/dhcp6.h:1.16 --- src/external/bsd/dhcpcd/dist/dhcp6.h:1.15 Fri Jul 29 10:07:57 2016 +++ src/external/bsd/dhcpcd/dist/dhcp6.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: dhcp6.h,v 1.15 2016/07/29 10:07:57 roy Exp $ */ +/* $NetBSD: dhcp6.h,v 1.16 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -232,7 +232,7 @@ struct dhcp6_state { #define D6_COPTION_DATA(o) \ ((const uint8_t *)(o) + sizeof(struct dhcp6_option)) -#ifdef INET6 +#ifdef DHCP6 void dhcp6_printoptions(const struct dhcpcd_ctx *, const struct dhcp_opt *, size_t); const struct ipv6_addr *dhcp6_iffindaddr(const struct interface *ifp, @@ -252,14 +252,19 @@ void dhcp6_drop(struct interface *, cons void dhcp6_dropnondelegates(struct interface *ifp); int dhcp6_dump(struct interface *); #else +#define dhcp6_printoptions(a, b, c) {} +#define dhcp6_iffindaddr(a, b, c) (NULL) +#define dhcp6_findaddr(a, b, c) (NULL) #define dhcp6_find_delegates(a) {} #define dhcp6_start(a, b) (0) #define dhcp6_reboot(a) {} #define dhcp6_renew(a) {} -#define dhcp6_env(a, b, c, d, e) {} +#define dhcp6_env(a, b, c, d, e) (0) #define dhcp6_free(a) {} +#define dhcp6_handleifa(a, b) {} #define dhcp6_dadcompleted(a) (0) #define dhcp6_drop(a, b) {} +#define dhcp6_dropnondelegates(a) {} #define dhcp6_dump(a) (-1) #endif Index: src/external/bsd/dhcpcd/dist/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/dhcpcd.c:1.36 src/external/bsd/dhcpcd/dist/dhcpcd.c:1.37 --- src/external/bsd/dhcpcd/dist/dhcpcd.c:1.36 Fri Jul 29 10:07:57 2016 +++ src/external/bsd/dhcpcd/dist/dhcpcd.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: dhcpcd.c,v 1.36 2016/07/29 10:07:57 roy Exp $"); + __RCSID("$NetBSD: dhcpcd.c,v 1.37 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -382,9 +382,6 @@ stop_interface(struct interface *ifp) struct dhcpcd_ctx *ctx; ctx = ifp->ctx; - if (!ifp->active) - goto stop; - logger(ctx, LOG_INFO, "%s: removing interface", ifp->name); ifp->options->options |= DHCPCD_STOPPING; @@ -403,7 +400,6 @@ stop_interface(struct interface *ifp) /* Set the link state to unknown as we're no longer tracking it. */ ifp->carrier = LINK_UNKNOWN; -stop: if (!(ctx->options & (DHCPCD_MASTER | DHCPCD_TEST))) eloop_exit(ctx->eloop, EXIT_FAILURE); } @@ -603,8 +599,11 @@ configure_interface(struct interface *if old = ifp->options ? ifp->options->mtime : 0; dhcpcd_selectprofile(ifp, NULL); - if (ifp->options == NULL) + if (ifp->options == NULL) { + /* dhcpcd cannot continue with this interface. */ + ifp->active = IF_INACTIVE; return; + } add_options(ifp->ctx, ifp->name, ifp->options, argc, argv); ifp->options->options |= options; configure_interface1(ifp); @@ -661,15 +660,6 @@ dhcpcd_initstate2(struct interface *ifp, logger(ifp->ctx, LOG_ERR, "ipv6_init: %m"); ifo->options &= ~DHCPCD_IPV6RS; } - - /* Add our link-local address before upping the interface - * so our RFC7217 address beats the hwaddr based one. - * This needs to happen before PREINIT incase a hook script - * inadvertently ups the interface. */ - if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) { - logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name); - ifo->options &= ~DHCPCD_IPV6; - } } static void @@ -678,7 +668,8 @@ dhcpcd_initstate1(struct interface *ifp, { configure_interface(ifp, argc, argv, options); - dhcpcd_initstate2(ifp, 0); + if (ifp->active) + dhcpcd_initstate2(ifp, 0); } static void @@ -812,20 +803,6 @@ warn_iaid_conflict(struct interface *ifp ifp->name, ifn->name); } -static void -pre_start(struct interface *ifp) -{ - - /* Add our link-local address before upping the interface - * so our RFC7217 address beats the hwaddr based one. - * This is also a safety check incase it was ripped out - * from under us. */ - if (ifp->options->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) { - logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name); - ifp->options->options &= ~DHCPCD_IPV6; - } -} - void dhcpcd_startinterface(void *arg) { @@ -890,6 +867,10 @@ dhcpcd_startinterface(void *arg) } } + if (ifo->options & DHCPCD_IPV6 && ipv6_start(ifp) == -1) { + logger(ifp->ctx, LOG_ERR, "%s: ipv6_start: %m", ifp->name); + ifo->options &= ~DHCPCD_IPV6; + } if (ifo->options & DHCPCD_IPV6) { ipv6_startstatic(ifp); @@ -944,7 +925,6 @@ dhcpcd_prestartinterface(void *arg) { struct interface *ifp = arg; - pre_start(ifp); if ((!(ifp->ctx->options & DHCPCD_MASTER) || ifp->options->options & DHCPCD_IF_UP) && if_up(ifp) == -1) @@ -972,7 +952,6 @@ static void run_preinit(struct interface *ifp) { - pre_start(ifp); if (ifp->ctx->options & DHCPCD_TEST) return; @@ -990,9 +969,13 @@ dhcpcd_activateinterface(struct interfac if (!ifp->active) { ifp->active = IF_ACTIVE; dhcpcd_initstate2(ifp, options); - configure_interface1(ifp); - run_preinit(ifp); - dhcpcd_prestartinterface(ifp); + /* It's possible we might not have been able to load + * a config. */ + if (ifp->active) { + configure_interface1(ifp); + run_preinit(ifp); + dhcpcd_prestartinterface(ifp); + } } } @@ -1142,7 +1125,8 @@ reload_config(struct dhcpcd_ctx *ctx) struct if_options *ifo; free_globals(ctx); - ifo = read_config(ctx, NULL, NULL, NULL); + if ((ifo = read_config(ctx, NULL, NULL, NULL)) == NULL) + return; add_options(ctx, NULL, ifo, ctx->argc, ctx->argv); /* We need to preserve these two options. */ if (ctx->options & DHCPCD_MASTER) @@ -1188,13 +1172,13 @@ stop_all_interfaces(struct dhcpcd_ctx *c ctx->options |= DHCPCD_EXITING; /* Drop the last interface first */ TAILQ_FOREACH_REVERSE(ifp, ctx->ifaces, if_head, next) { - if (ifp->options) { + if (ifp->active) { ifp->options->options |= opts; if (ifp->options->options & DHCPCD_RELEASE) ifp->options->options &= ~DHCPCD_PERSISTENT; ifp->options->options |= DHCPCD_EXITING; + stop_interface(ifp); } - stop_interface(ifp); } } @@ -1407,6 +1391,8 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx for (oi = optind; oi < argc; oi++) { if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL) continue; + if (!ifp->active) + continue; ifp->options->options |= opts; if (opts & DHCPCD_RELEASE) ifp->options->options &= ~DHCPCD_PERSISTENT; @@ -1459,6 +1445,23 @@ main(int argc, char **argv) return EXIT_SUCCESS; } else if (strcmp(argv[1], "--version") == 0) { printf(""PACKAGE" "VERSION"\n%s\n", dhcpcd_copyright); + printf("Compiled in features:" +#ifdef INET + " INET" +#endif +#ifdef IPV4LL + " IPv4LL" +#endif +#ifdef INET6 + " INET6" +#endif +#ifdef DHCP6 + " DHCPv6" +#endif +#ifdef AUTH + " AUTH" +#endif + "\n"); return EXIT_SUCCESS; } } @@ -1974,6 +1977,7 @@ exit1: if (control_stop(&ctx) == -1) logger(&ctx, LOG_ERR, "control_stop: %m:"); eloop_free(ctx.eloop); + free(ctx.iov[0].iov_base); if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) logger(&ctx, LOG_INFO, PACKAGE " exited"); Index: src/external/bsd/dhcpcd/dist/dhcpcd.h diff -u src/external/bsd/dhcpcd/dist/dhcpcd.h:1.19 src/external/bsd/dhcpcd/dist/dhcpcd.h:1.20 --- src/external/bsd/dhcpcd/dist/dhcpcd.h:1.19 Fri Jul 29 10:07:58 2016 +++ src/external/bsd/dhcpcd/dist/dhcpcd.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: dhcpcd.h,v 1.19 2016/07/29 10:07:58 roy Exp $ */ +/* $NetBSD: dhcpcd.h,v 1.20 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -123,6 +123,7 @@ struct dhcpcd_ctx { int link_fd; int seq; /* route message sequence no */ int sseq; /* successful seq no sent */ + struct iovec iov[1]; /* generic iovec buffer */ #ifdef USE_SIGNALS sigset_t sigset; Index: src/external/bsd/dhcpcd/dist/ipv4.h diff -u src/external/bsd/dhcpcd/dist/ipv4.h:1.19 src/external/bsd/dhcpcd/dist/ipv4.h:1.20 --- src/external/bsd/dhcpcd/dist/ipv4.h:1.19 Fri Jul 29 10:07:58 2016 +++ src/external/bsd/dhcpcd/dist/ipv4.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ipv4.h,v 1.19 2016/07/29 10:07:58 roy Exp $ */ +/* $NetBSD: ipv4.h,v 1.20 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -154,7 +154,8 @@ struct ipv4_addr *ipv4_findaddr(struct d struct ipv4_addr *ipv4_findmaskaddr(struct dhcpcd_ctx *, const struct in_addr *); void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *, - const struct in_addr *, const struct in_addr *, const struct in_addr *); + const struct in_addr *, const struct in_addr *, const struct in_addr *, + int); void ipv4_freeroutes(struct rt_head *); Index: src/external/bsd/dhcpcd/dist/if-bsd.c diff -u src/external/bsd/dhcpcd/dist/if-bsd.c:1.33 src/external/bsd/dhcpcd/dist/if-bsd.c:1.34 --- src/external/bsd/dhcpcd/dist/if-bsd.c:1.33 Mon Aug 15 11:04:53 2016 +++ src/external/bsd/dhcpcd/dist/if-bsd.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: if-bsd.c,v 1.33 2016/08/15 11:04:53 roy Exp $"); + __RCSID("$NetBSD: if-bsd.c,v 1.34 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -740,7 +740,7 @@ if_route(unsigned char cmd, const struct #endif addrs = 0; - flags = 0; + flags = (int)rt->flags; if (cmd == RTM_ADD || cmd == RTM_CHANGE) { addrs |= RTA_GATEWAY | RTA_IFP; @@ -852,26 +852,30 @@ if_initrt(struct dhcpcd_ctx *ctx) return 0; } +#if !(defined(HAVE_IFADDRS_ADDRFLAGS) && defined(HAVE_IFAM_ADDRFLAGS)) int -if_addrflags(const struct ipv4_addr *ia) +if_addrflags(const struct interface *ifp, const struct in_addr *addr, + __unused const char *alias) { #ifdef SIOCGIFAFLAG_IN struct ifreq ifr; struct sockaddr_in *sin; memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ia->iface->name, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); sin = (void *)&ifr.ifr_addr; sin->sin_family = AF_INET; - sin->sin_addr = ia->addr; - if (ioctl(ia->iface->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1) + sin->sin_addr = *addr; + if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1) return -1; return ifr.ifr_addrflags; #else - UNUSED(ia); + UNUSED(ifp); + UNUSED(addr); return 0; #endif } +#endif #endif /* INET */ #ifdef INET6 @@ -970,11 +974,13 @@ if_address6(unsigned char cmd, const str * This issue is discussed on the NetBSD mailing lists here: * http://mail-index.netbsd.org/tech-net/2016/08/05/msg006044.html * - * NOT fixed in NetBSD - patch under development + * Fixed in NetBSD-7.99.36 * NOT fixed in FreeBSD - bug 195197 * Fixed in OpenBSD-5.9 */ -#if !(defined(OpenBSD) && OpenBSD >= 201605) + +#if !((defined(__NetBSD_Version__) && __NetBSD_Version__ >= 799003600) || \ + (defined(__OpenBSD__))) if (cmd == RTM_NEWADDR && !(ia->flags & IPV6_AF_ADDED)) { ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; @@ -982,8 +988,22 @@ if_address6(unsigned char cmd, const str } #endif +#if defined(__OpenBSD__) + /* BUT OpenBSD does not reset the address lifetime + * for subsequent calls... + * Luckily dhcpcd will remove the lease when it expires so + * just set an infinite lifetime, unless a temporary address. */ + if (ifa.ifra_flags & IN6_IFF_PRIVACY) { + ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime; + ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime; + } else { + ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; + ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; + } +#else ifa.ifra_lifetime.ia6t_vltime = ia->prefix_vltime; ifa.ifra_lifetime.ia6t_pltime = ia->prefix_pltime; +#endif return ioctl(priv->pf_inet6_fd, cmd == RTM_DELADDR ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa); @@ -1200,25 +1220,28 @@ if_initrt6(struct dhcpcd_ctx *ctx) return 0; } +#if !(defined(HAVE_IFADDRS_ADDRFLAGS) && defined(HAVE_IFAM_ADDRFLAGS)) int -if_addrflags6(const struct ipv6_addr *ia) +if_addrflags6(const struct interface *ifp, const struct in6_addr *addr, + __unused const char *alias) { int flags; struct in6_ifreq ifr6; struct priv *priv; memset(&ifr6, 0, sizeof(ifr6)); - strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name)); + strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name)); ifr6.ifr_addr.sin6_family = AF_INET6; - ifr6.ifr_addr.sin6_addr = ia->addr; - ifa_scope(&ifr6.ifr_addr, ia->iface->index); - priv = (struct priv *)ia->iface->ctx->priv; + ifr6.ifr_addr.sin6_addr = *addr; + ifa_scope(&ifr6.ifr_addr, ifp->index); + priv = (struct priv *)ifp->ctx->priv; if (ioctl(priv->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1) flags = ifr6.ifr_ifru.ifru_flags6; else flags = -1; return flags; } +#endif int if_getlifetime6(struct ipv6_addr *ia) @@ -1275,55 +1298,67 @@ static void if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm) { struct interface *ifp; - int state; + int link_state; if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL) return; switch (ifm->ifm_data.ifi_link_state) { case LINK_STATE_DOWN: - state = LINK_DOWN; + link_state = LINK_DOWN; break; case LINK_STATE_UP: - state = LINK_UP; + /* dhcpcd considers the link down if IFF_UP is not set. */ + link_state = ifm->ifm_flags & IFF_UP ? LINK_UP : LINK_DOWN; break; default: /* handle_carrier will re-load the interface flags and check for * IFF_RUNNING as some drivers that don't handle link state also * don't set IFF_RUNNING when this routing message is generated. * As such, it is a race ...*/ - state = LINK_UNKNOWN; + link_state = LINK_UNKNOWN; break; } - dhcpcd_handlecarrier(ctx, state, + dhcpcd_handlecarrier(ctx, link_state, (unsigned int)ifm->ifm_flags, ifp->name); } -static void -if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) +static int +if_ownmsgpid(struct dhcpcd_ctx *ctx, pid_t pid, int seq) { - const struct sockaddr *sa; /* Ignore messages generated by us */ - if (rtm->rtm_pid == getpid()) { + if (getpid() == pid) { ctx->options &= ~DHCPCD_RTM_PPID; - return; + return 1; } /* Ignore messages sent by the parent after forking */ if ((ctx->options & (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) == (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) && - rtm->rtm_pid == ctx->ppid) + ctx->ppid == pid) { /* If this is the last successful message sent, * clear the check flag as it's possible another * process could re-use the same pid and also - * manipulate therouting table. */ - if (rtm->rtm_seq == ctx->pseq) + * manipulate the routing table. */ + if (ctx->pseq == seq) ctx->options &= ~DHCPCD_RTM_PPID; - return; + return 1; } + /* Not a message we made. */ + return 0; +} + +static void +if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) +{ + const struct sockaddr *sa; + + if (if_ownmsgpid(ctx, rtm->rtm_pid, rtm->rtm_seq)) + return; + sa = (const void *)(rtm + 1); switch (sa->sa_family) { #ifdef INET @@ -1380,15 +1415,21 @@ if_ifa(struct dhcpcd_ctx *ctx, const str { struct interface *ifp; const struct sockaddr *rti_info[RTAX_MAX]; + int addrflags; + +#ifdef HAVE_IFAM_PID + if (if_ownmsgpid(ctx, ifam->ifam_pid, 0)) + return; +#endif - /* XXX We have no way of knowing who generated these - * messages wich truely sucks because we want to - * avoid listening to our own delete messages. */ if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL) return; get_addrs(ifam->ifam_addrs, ifam + 1, rti_info); if (rti_info[RTAX_IFA] == NULL) return; +#ifdef HAVE_IFAM_ADDRFLAGS + addrflags = ifam->ifam_addrflags; +#endif switch (rti_info[RTAX_IFA]->sa_family) { case AF_LINK: { @@ -1421,8 +1462,45 @@ if_ifa(struct dhcpcd_ctx *ctx, const str sin = (const void *)rti_info[RTAX_BRD]; bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ? sin->sin_addr.s_addr : INADDR_ANY; + +#if defined(__FreeBSD__) || defined(__DragonFly__) + /* FreeBSD sends RTM_DELADDR for each assigned address + * to an interface just brought down. + * This is wrong, because the address still exists. + * So we need to ignore it. + * Oddly enough this only happens for INET addresses. */ + if (ifam->ifam_type == RTM_DELADDR) { + struct ifreq ifr; + struct sockaddr_in *ifr_sin; + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); + ifr_sin = (void *)&ifr.ifr_addr; + ifr_sin->sin_family = AF_INET; + ifr_sin->sin_addr = addr; + if (ioctl(ctx->pf_inet_fd, SIOCGIFADDR, &ifr) == 0) { + logger(ctx, LOG_WARNING, + "%s: ignored false RTM_DELADDR for %s", + ifp->name, inet_ntoa(addr)); + break; + } + } +#endif + +#ifndef HAVE_IFAM_ADDRFLAGS + if (ifam->ifam_type == RTM_DELADDR || + (addrflags = if_addrflags(ifp, &addr, NULL)) == -1) + { + if (ifam->ifam_type != RTM_DELADDR || errno != EEXIST) + logger(ctx, LOG_ERR, + "%s: if_addrflags: %s: %m", + ifp->name, inet_ntoa(addr)); + addrflags = 0; + } +#endif + ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name, - &addr, &mask, &bcast); + &addr, &mask, &bcast, addrflags); break; } #endif @@ -1438,8 +1516,21 @@ if_ifa(struct dhcpcd_ctx *ctx, const str sin6 = (const void *)rti_info[RTAX_NETMASK]; mask6 = sin6->sin6_addr; DESCOPE(&mask6); + +#ifndef HAVE_IFAM_ADDRFLAGS + if (ifam->ifam_type == RTM_DELADDR || + (addrflags = if_addrflags6(ifp, &addr6, NULL)) == -1) + { + if (ifam->ifam_type != RTM_DELADDR || errno != EEXIST) + logger(ctx, LOG_ERR, + "%s: if_addrflags: %m", + ifp->name); + addrflags = 0; + } +#endif + ipv6_handleifa(ctx, ifam->ifam_type, NULL, - ifp->name, &addr6, ipv6_prefixlen(&mask6)); + ifp->name, &addr6, ipv6_prefixlen(&mask6), addrflags); break; } #endif @@ -1450,6 +1541,9 @@ static void if_dispatch(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) { + if (rtm->rtm_version != RTM_VERSION) + return; + switch(rtm->rtm_type) { #ifdef RTM_IFANNOUNCE case RTM_IFANNOUNCE: @@ -1477,21 +1571,17 @@ if_dispatch(struct dhcpcd_ctx *ctx, cons int if_handlelink(struct dhcpcd_ctx *ctx) { - /* route and ifwatchd like a msg buf size of 2048 */ - char buf[2048]; - const char *p, *e; - size_t msglen; - ssize_t bytes; - const struct rt_msghdr *rtm; + struct msghdr msg; + ssize_t len; - if ((bytes = read(ctx->link_fd, buf, sizeof(buf))) == -1) + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = ctx->iov; + msg.msg_iovlen = 1; + + if ((len = recvmsg_realloc(ctx->link_fd, &msg, 0)) == -1) return -1; - e = buf + bytes; - for (p = buf; p < e; p += msglen) { - rtm = (const void *)p; - msglen = rtm->rtm_msglen; - if_dispatch(ctx, rtm); - } + if (len != 0) + if_dispatch(ctx, ctx->iov[0].iov_base); return 0; } @@ -1688,10 +1778,6 @@ _if_checkipv6(int s, struct dhcpcd_ctx * int ra; if (ifp) { -#ifdef ND6_IFF_OVERRIDE_RTADV - int override; -#endif - #ifdef ND6_IFF_AUTO_LINKLOCAL if (own) { int all; @@ -1729,24 +1815,6 @@ _if_checkipv6(int s, struct dhcpcd_ctx * } #endif -#ifdef ND6_IFF_OVERRIDE_RTADV - override = get_if_nd6_flag(s, ifp, ND6_IFF_OVERRIDE_RTADV); - if (override == -1) - logger(ifp->ctx, LOG_ERR, - "%s: get_if_nd6_flag: ND6_IFF_OVERRIDE_RTADV: %m", - ifp->name); - else if (override == 0 && own) { - if (set_if_nd6_flag(s, ifp, ND6_IFF_OVERRIDE_RTADV) - == -1) - logger(ifp->ctx, LOG_ERR, - "%s: set_if_nd6_flag: " - "ND6_IFF_OVERRIDE_RTADV: %m", - ifp->name); - else - override = 1; - } -#endif - #ifdef ND6_IFF_ACCEPT_RTADV ra = get_if_nd6_flag(s, ifp, ND6_IFF_ACCEPT_RTADV); if (ra == -1) @@ -1800,10 +1868,6 @@ _if_checkipv6(int s, struct dhcpcd_ctx * #endif #ifdef ND6_IFF_ACCEPT_RTADV -#ifdef ND6_IFF_OVERRIDE_RTADV - if (override == 0 && ra) - return ctx->ra_global; -#endif return ra; #else return ctx->ra_global; Index: src/external/bsd/dhcpcd/dist/if-options.c diff -u src/external/bsd/dhcpcd/dist/if-options.c:1.35 src/external/bsd/dhcpcd/dist/if-options.c:1.36 --- src/external/bsd/dhcpcd/dist/if-options.c:1.35 Fri Jul 29 10:07:58 2016 +++ src/external/bsd/dhcpcd/dist/if-options.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: if-options.c,v 1.35 2016/07/29 10:07:58 roy Exp $"); + __RCSID("$NetBSD: if-options.c,v 1.36 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -290,7 +290,7 @@ parse_string_hwaddr(char *sbuf, size_t s size_t l; const char *p; int i, punt_last = 0; - char c[4]; + char c[4], cmd; /* If surrounded by quotes then it's a string */ if (*str == '"') { @@ -328,28 +328,25 @@ parse_string_hwaddr(char *sbuf, size_t s } if (*str == '\\') { str++; - switch(*str) { + switch((cmd = *str++)) { case '\0': + str--; break; case 'b': if (sbuf) *sbuf++ = '\b'; - str++; break; case 'n': if (sbuf) *sbuf++ = '\n'; - str++; break; case 'r': if (sbuf) *sbuf++ = '\r'; - str++; break; case 't': if (sbuf) *sbuf++ = '\t'; - str++; break; case 'x': /* Grab a hex code */ @@ -383,8 +380,7 @@ parse_string_hwaddr(char *sbuf, size_t s break; default: if (sbuf) - *sbuf++ = *str; - str++; + *sbuf++ = cmd; break; } } else { @@ -434,12 +430,14 @@ parse_iaid(uint8_t *iaid, const char *ar return parse_iaid1(iaid, arg, len, 1); } +#ifdef AUTH static int parse_uint32(uint32_t *i, const char *arg) { return parse_iaid1((uint8_t *)i, arg, sizeof(uint32_t), 0); } +#endif static char ** splitv(struct dhcpcd_ctx *ctx, int *argc, char **argv, const char *arg) @@ -629,6 +627,7 @@ strskipwhite(const char *s) return UNCONST(s); } +#ifdef AUTH /* Find the end pointer of a string. */ static char * strend(const char *s) @@ -650,6 +649,7 @@ strend(const char *s) } return UNCONST(++s); } +#endif static int parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, @@ -668,12 +668,14 @@ parse_option(struct dhcpcd_ctx *ctx, con struct dhcp_opt **dop, *ndop; size_t *dop_len, dl, odl; struct vivco *vivco; - struct token *token; struct group *grp; +#ifdef AUTH + struct token *token; +#endif #ifdef _REENTRANT struct group grpbuf; #endif -#ifdef INET6 +#ifdef DHCP6 size_t sl; struct if_ia *ia; uint8_t iaid[4]; @@ -1329,7 +1331,7 @@ parse_option(struct dhcpcd_ctx *ctx, con case O_NOALIAS: ifo->options |= DHCPCD_NOALIAS; break; -#ifdef INET6 +#ifdef DHCP6 case O_IA_NA: i = D6_OPTION_IA_NA; /* FALLTHROUGH */ @@ -1903,6 +1905,7 @@ err_sla: break; case O_AUTHPROTOCOL: ARG_REQUIRED; +#ifdef AUTH fp = strwhite(arg); if (fp) *fp++ = '\0'; @@ -1951,8 +1954,13 @@ err_sla: } ifo->auth.options |= DHCPCD_AUTH_SEND; break; +#else + logger(ctx, LOG_ERR, "no authentication support"); + return -1; +#endif case O_AUTHTOKEN: ARG_REQUIRED; +#ifdef AUTH fp = strwhite(arg); if (fp == NULL) { logger(ctx, LOG_ERR, "authtoken requires a realm"); @@ -2045,6 +2053,10 @@ err_sla: token->key = malloc(token->key_len); parse_string((char *)token->key, token->key_len, arg); TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next); +#else + logger(ctx, LOG_ERR, "no authentication support"); + return -1; +#endif break; case O_AUTHNOTREQUIRED: ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; @@ -2251,7 +2263,9 @@ default_config(struct dhcpcd_ctx *ctx) ifo->reboot = DEFAULT_REBOOT; ifo->metric = -1; ifo->auth.options |= DHCPCD_AUTH_REQUIRE; +#ifdef AUTH TAILQ_INIT(&ifo->auth.tokens); +#endif /* Inherit some global defaults */ if (ctx->options & DHCPCD_PERSISTENT) @@ -2571,7 +2585,9 @@ free_options(struct if_options *ifo) size_t i; struct dhcp_opt *opt; struct vivco *vo; +#ifdef AUTH struct token *token; +#endif if (ifo) { if (ifo->environ) { @@ -2624,6 +2640,7 @@ free_options(struct if_options *ifo) #endif free(ifo->ia); +#ifdef AUTH while ((token = TAILQ_FIRST(&ifo->auth.tokens))) { TAILQ_REMOVE(&ifo->auth.tokens, token, next); if (token->realm_len) @@ -2631,6 +2648,7 @@ free_options(struct if_options *ifo) free(token->key); free(token); } +#endif free(ifo); } } Index: src/external/bsd/dhcpcd/dist/if.c diff -u src/external/bsd/dhcpcd/dist/if.c:1.23 src/external/bsd/dhcpcd/dist/if.c:1.24 --- src/external/bsd/dhcpcd/dist/if.c:1.23 Fri Jul 29 10:07:58 2016 +++ src/external/bsd/dhcpcd/dist/if.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: if.c,v 1.23 2016/07/29 10:07:58 roy Exp $"); + __RCSID("$NetBSD: if.c,v 1.24 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -201,12 +201,16 @@ static void if_learnaddrs(struct dhcpcd_ #ifdef INET6 struct sockaddr_in6 *sin6, *net6; #endif + int addrflags; for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) continue; if ((ifp = if_find(ifs, ifa->ifa_name)) == NULL) continue; +#ifdef HAVE_IFADDRS_ADDRFLAGS + addrflags = (int)ifa->ifa_addrflags; +#endif switch(ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: @@ -216,9 +220,21 @@ static void if_learnaddrs(struct dhcpcd_ brd = (void *)ifa->ifa_dstaddr; else brd = (void *)ifa->ifa_broadaddr; +#ifndef HAVE_IFADDRS_ADDRFLAGS + addrflags = if_addrflags(ifp, &addr->sin_addr, + ifa->ifa_name); + if (addrflags == -1) { + if (errno != EEXIST) + logger(ctx, LOG_ERR, + "%s: if_addrflags: %s: %m", + __func__, + inet_ntoa(addr->sin_addr)); + continue; + } +#endif ipv4_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name, &addr->sin_addr, &net->sin_addr, - brd ? &brd->sin_addr : NULL); + brd ? &brd->sin_addr : NULL, addrflags); break; #endif #ifdef INET6 @@ -231,9 +247,19 @@ static void if_learnaddrs(struct dhcpcd_ sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = '\0'; #endif +#ifndef HAVE_IFADDRS_ADDRFLAGS + addrflags = if_addrflags6(ifp, &sin6->sin6_addr, + ifa->ifa_name); + if (addrflags == -1) { + if (errno != EEXIST) + logger(ctx, LOG_ERR, + "%s: if_addrflags6: %m", __func__); + continue; + } +#endif ipv6_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name, &sin6->sin6_addr, - ipv6_prefixlen(&net6->sin6_addr)); + ipv6_prefixlen(&net6->sin6_addr), addrflags); break; #endif } Index: src/external/bsd/dhcpcd/dist/if.h diff -u src/external/bsd/dhcpcd/dist/if.h:1.18 src/external/bsd/dhcpcd/dist/if.h:1.19 --- src/external/bsd/dhcpcd/dist/if.h:1.18 Fri Jul 29 10:07:58 2016 +++ src/external/bsd/dhcpcd/dist/if.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: if.h,v 1.18 2016/07/29 10:07:58 roy Exp $ */ +/* $NetBSD: if.h,v 1.19 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -45,6 +45,12 @@ # endif #endif +#if defined(__OpenBSD) || defined (__sun) +# define ROUTE_PER_GATEWAY +/* XXX dhcpcd doesn't really support this yet. + * But that's generally OK if only dhcpcd is managing routes. */ +#endif + /* Some systems have in-built IPv4 DAD. * However, we need them to do DAD at carrier up as well. */ #ifdef IN_IFF_TENTATIVE @@ -181,7 +187,8 @@ ssize_t if_readraw(struct interface *, i void if_closeraw(struct interface *, int); int if_address(unsigned char, const struct ipv4_addr *); -int if_addrflags(const struct ipv4_addr *); +int if_addrflags(const struct interface *, const struct in_addr *, + const char *); int if_route(unsigned char, const struct rt *rt); int if_initrt(struct dhcpcd_ctx *); @@ -198,7 +205,8 @@ int ip6_temp_valid_lifetime(const char * #endif int if_address6(unsigned char, const struct ipv6_addr *); -int if_addrflags6(const struct ipv6_addr *); +int if_addrflags6(const struct interface *, const struct in6_addr *, + const char *); int if_getlifetime6(struct ipv6_addr *); int if_route6(unsigned char, const struct rt6 *rt); Index: src/external/bsd/dhcpcd/dist/ipv4ll.c diff -u src/external/bsd/dhcpcd/dist/ipv4ll.c:1.18 src/external/bsd/dhcpcd/dist/ipv4ll.c:1.19 --- src/external/bsd/dhcpcd/dist/ipv4ll.c:1.18 Fri Jul 29 10:07:58 2016 +++ src/external/bsd/dhcpcd/dist/ipv4ll.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv4ll.c,v 1.18 2016/07/29 10:07:58 roy Exp $"); + __RCSID("$NetBSD: ipv4ll.c,v 1.19 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -48,6 +48,7 @@ #include "ipv4ll.h" #include "script.h" +#ifdef IPV4LL static const struct in_addr inaddr_llmask = { .s_addr = HTONL(LINKLOCAL_MASK) }; @@ -493,3 +494,4 @@ ipv4ll_handlert(struct dhcpcd_ctx *ctx, return 0; } #endif +#endif Index: src/external/bsd/dhcpcd/dist/ipv4ll.h diff -u src/external/bsd/dhcpcd/dist/ipv4ll.h:1.12 src/external/bsd/dhcpcd/dist/ipv4ll.h:1.13 --- src/external/bsd/dhcpcd/dist/ipv4ll.h:1.12 Fri Jun 17 19:42:32 2016 +++ src/external/bsd/dhcpcd/dist/ipv4ll.h Sun Oct 9 09:18:26 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ipv4ll.h,v 1.12 2016/06/17 19:42:32 roy Exp $ */ +/* $NetBSD: ipv4ll.h,v 1.13 2016/10/09 09:18:26 roy Exp $ */ /* * dhcpcd - DHCP client daemon @@ -30,17 +30,17 @@ #ifndef IPV4LL_H #define IPV4LL_H -#ifdef INET -#include "arp.h" - -#define LINKLOCAL_ADDR 0xa9fe0000 -#define LINKLOCAL_MASK IN_CLASSB_NET -#define LINKLOCAL_BCAST (LINKLOCAL_ADDR | ~LINKLOCAL_MASK) +#define LINKLOCAL_ADDR 0xa9fe0000 +#define LINKLOCAL_MASK IN_CLASSB_NET +#define LINKLOCAL_BCAST (LINKLOCAL_ADDR | ~LINKLOCAL_MASK) #ifndef IN_LINKLOCAL # define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR) #endif +#ifdef IPV4LL +#include "arp.h" + struct ipv4ll_state { struct ipv4_addr *addr; struct arp_state *arp; @@ -50,11 +50,11 @@ struct ipv4ll_state { uint8_t down; }; -#define IPV4LL_STATE(ifp) \ +#define IPV4LL_STATE(ifp) \ ((struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL]) -#define IPV4LL_CSTATE(ifp) \ +#define IPV4LL_CSTATE(ifp) \ ((const struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL]) -#define IPV4LL_STATE_RUNNING(ifp) \ +#define IPV4LL_STATE_RUNNING(ifp) \ (IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \ (IPV4LL_CSTATE((ifp))->addr != NULL)) @@ -67,16 +67,19 @@ void ipv4ll_handle_failure(void *); #ifdef HAVE_ROUTE_METRIC int ipv4ll_handlert(struct dhcpcd_ctx *, int, const struct rt *); #else -#define ipv4ll_handlert(a, b, c) (0) +#define ipv4ll_handlert(a, b, c) (0) #endif -#define ipv4ll_free(ifp) ipv4ll_freedrop((ifp), 0); -#define ipv4ll_drop(ifp) ipv4ll_freedrop((ifp), 1); +#define ipv4ll_free(ifp) ipv4ll_freedrop((ifp), 0); +#define ipv4ll_drop(ifp) ipv4ll_freedrop((ifp), 1); void ipv4ll_freedrop(struct interface *, int); #else -#define IPV4LL_STATE_RUNNING(ifp) (0) -#define ipv4ll_free(a) {} -#define ipv4ll_drop(a) {} +#define IPV4LL_STATE_RUNNING(ifp) (0) +#define ipv4ll_subnet_route(ifp) (NULL) +#define ipv4ll_default_route(ifp) (NULL) +#define ipv4ll_handlert(a, b, c) (0) +#define ipv4ll_free(a) {} +#define ipv4ll_drop(a) {} #endif #endif Index: src/external/bsd/dhcpcd/dist/ipv6nd.c diff -u src/external/bsd/dhcpcd/dist/ipv6nd.c:1.32 src/external/bsd/dhcpcd/dist/ipv6nd.c:1.33 --- src/external/bsd/dhcpcd/dist/ipv6nd.c:1.32 Mon Aug 15 11:04:53 2016 +++ src/external/bsd/dhcpcd/dist/ipv6nd.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: ipv6nd.c,v 1.32 2016/08/15 11:04:53 roy Exp $"); + __RCSID("$NetBSD: ipv6nd.c,v 1.33 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -715,6 +715,19 @@ try_script: } } +#ifndef DHCP6 +/* If DHCPv6 is compiled out, supply a shim to provide an error message + * if IPv6RA requests DHCPv6. */ +#undef dhcp6_start +static int +dhcp6_start(__unused struct interface *ifp, __unused enum DH6S init_state) +{ + + errno = ENOTSUP; + return -1; +} +#endif + static void ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp, struct icmp6_hdr *icp, size_t len, int hoplimit) @@ -1105,13 +1118,19 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, handle_flag: if (!(ifp->options->options & DHCPCD_DHCP6)) goto nodhcp6; +/* Only log a DHCPv6 start error if compiled in or debugging is enabled. */ +#ifdef DHCP6 +#define LOG_DHCP6 LOG_ERR +#else +#define LOG_DHCP6 LOG_DEBUG +#endif if (rap->flags & ND_RA_FLAG_MANAGED) { if (new_data && dhcp6_start(ifp, DH6S_INIT) == -1) - logger(ifp->ctx, LOG_ERR, + logger(ifp->ctx, LOG_DHCP6, "dhcp6_start: %s: %m", ifp->name); } else if (rap->flags & ND_RA_FLAG_OTHER) { if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1) - logger(ifp->ctx, LOG_ERR, + logger(ifp->ctx, LOG_DHCP6, "dhcp6_start: %s: %m", ifp->name); } else { if (new_data) @@ -1554,7 +1573,7 @@ ipv6nd_handledata(void *arg) ctx = dctx->ipv6; ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int)); - len = recvmsg(ctx->nd_fd, &ctx->rcvhdr, 0); + len = recvmsg_realloc(ctx->nd_fd, &ctx->rcvhdr, 0); if (len == -1) { logger(dctx, LOG_ERR, "recvmsg: %m"); eloop_event_delete(dctx->eloop, ctx->nd_fd); Index: src/external/bsd/dhcpcd/dist/script.c diff -u src/external/bsd/dhcpcd/dist/script.c:1.27 src/external/bsd/dhcpcd/dist/script.c:1.28 --- src/external/bsd/dhcpcd/dist/script.c:1.27 Fri Jun 17 19:42:32 2016 +++ src/external/bsd/dhcpcd/dist/script.c Sun Oct 9 09:18:26 2016 @@ -1,5 +1,5 @@ #include <sys/cdefs.h> - __RCSID("$NetBSD: script.c,v 1.27 2016/06/17 19:42:32 roy Exp $"); + __RCSID("$NetBSD: script.c,v 1.28 2016/10/09 09:18:26 roy Exp $"); /* * dhcpcd - DHCP client daemon @@ -239,8 +239,10 @@ make_env(const struct interface *ifp, co #ifdef INET int dhcp, ipv4ll; const struct dhcp_state *state; +#ifdef IPV4LL const struct ipv4ll_state *istate; #endif +#endif #ifdef INET6 const struct dhcp6_state *d6_state; int static6, dhcp6, ra; @@ -249,8 +251,10 @@ make_env(const struct interface *ifp, co #ifdef INET dhcp = ipv4ll = 0; state = D_STATE(ifp); +#ifdef IPV4LL istate = IPV4LL_CSTATE(ifp); #endif +#endif #ifdef INET6 static6 = dhcp6 = ra = 0; d6_state = D6_CSTATE(ifp); @@ -264,8 +268,10 @@ make_env(const struct interface *ifp, co ra = 1; #endif #ifdef INET +#ifdef IPV4LL else if (istate && istate->addr != NULL) ipv4ll = 1; +#endif else dhcp = 1; #endif @@ -288,8 +294,10 @@ make_env(const struct interface *ifp, co /* This space left intentionally blank */ } #ifdef INET +#ifdef IPV4LL else if (strcmp(reason, "IPV4LL") == 0) ipv4ll = 1; +#endif else dhcp = 1; #endif @@ -362,8 +370,10 @@ make_env(const struct interface *ifp, co } else if (1 == 2 /* appease ifdefs */ #ifdef INET || (dhcp && state && state->new) +#ifdef IPV4LL || (ipv4ll && IPV4LL_STATE_RUNNING(ifp)) #endif +#endif #ifdef INET6 || (static6 && IPV6_STATE_RUNNING(ifp)) || (dhcp6 && d6_state && d6_state->new) @@ -465,6 +475,7 @@ make_env(const struct interface *ifp, co dumplease: #ifdef INET +#ifdef IPV4LL if (ipv4ll) { n = ipv4ll_env(NULL, NULL, ifp); if (n > 0) { @@ -479,6 +490,7 @@ dumplease: elen += (size_t)n; } } +#endif if (dhcp && state && state->new) { n = dhcp_env(NULL, NULL, state->new, state->new_len, ifp); if (n > 0) { @@ -634,11 +646,13 @@ send_interface(struct fd_list *fd, const if (send_interface1(fd, ifp, d->reason) == -1) retval = -1; } +#ifdef IPV4LL if (IPV4LL_STATE_RUNNING(ifp)) { if (send_interface1(fd, ifp, "IPV4LL") == -1) retval = -1; } #endif +#endif #ifdef INET6 if (IPV6_STATE_RUNNING(ifp)) {