Module Name: src Committed By: roy Date: Mon Apr 13 15:46:26 UTC 2020
Modified Files: src/external/bsd/dhcpcd/dist/src: dhcp.c dhcp6.c dhcpcd.c if-bsd.c if-options.c ipv6.c ipv6.h ipv6nd.c script.c Removed Files: src/external/bsd/dhcpcd/dist/hooks: 00-linux 02-dump Log Message: Sync To generate a diff of this commit: cvs rdiff -u -r1.1.1.1 -r0 src/external/bsd/dhcpcd/dist/hooks/00-linux \ src/external/bsd/dhcpcd/dist/hooks/02-dump cvs rdiff -u -r1.34 -r1.35 src/external/bsd/dhcpcd/dist/src/dhcp.c cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/src/dhcp6.c cvs rdiff -u -r1.32 -r1.33 src/external/bsd/dhcpcd/dist/src/dhcpcd.c cvs rdiff -u -r1.17 -r1.18 src/external/bsd/dhcpcd/dist/src/if-bsd.c \ src/external/bsd/dhcpcd/dist/src/ipv6nd.c cvs rdiff -u -r1.21 -r1.22 src/external/bsd/dhcpcd/dist/src/if-options.c cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/src/ipv6.c \ src/external/bsd/dhcpcd/dist/src/ipv6.h cvs rdiff -u -r1.4 -r1.5 src/external/bsd/dhcpcd/dist/src/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/src/dhcp.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.34 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.35 --- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.34 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/dhcp.c Mon Apr 13 15:46:26 2020 @@ -2301,7 +2301,7 @@ dhcp_bind(struct interface *ifp) if (!state->lease.frominfo && !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))) if (write_lease(ifp, state->new, state->new_len) == -1) - logerr(__func__); + logerr("write_lease: %s", state->leasefile); /* Close the BPF filter as we can now receive DHCP messages * on a UDP socket. */ @@ -3370,7 +3370,7 @@ is_packet_udp_bootp(void *packet, size_t memcpy(&udp, (char *)ip + ip_hlen, sizeof(udp)); if (ntohs(udp.uh_ulen) < sizeof(udp)) return false; - if (ip_hlen + (size_t)ntohs(udp.uh_ulen) > plen) + if (ip_hlen + ntohs(udp.uh_ulen) > plen) return false; /* Check it's to and from the right ports. */ Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.16 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.17 --- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.16 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Mon Apr 13 15:46:26 2020 @@ -2503,10 +2503,8 @@ dhcp6_writelease(const struct interface logdebugx("%s: writing lease `%s'", ifp->name, state->leasefile); fd = open(state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - logerr(__func__); + if (fd == -1) return -1; - } bytes = write(fd, state->new, state->new_len); close(fd); return bytes; @@ -2710,7 +2708,7 @@ dhcp6_ifdelegateaddr(struct interface *i vl |= sla->suffix; be64enc(daddr.s6_addr + 8, vl); } else { - dadcounter = ipv6_makeaddr(&daddr, ifp, &addr, pfxlen); + dadcounter = ipv6_makeaddr(&daddr, ifp, &addr, pfxlen, 0); if (dadcounter == -1) { logerrx("%s: error adding slaac to prefix_len %d", ifp->name, pfxlen); @@ -3162,7 +3160,8 @@ dhcp6_bind(struct interface *ifp, const ifp->name, state->expire); rt_build(ifp->ctx, AF_INET6); if (!confirmed && !timedout) - dhcp6_writelease(ifp); + if (dhcp6_writelease(ifp) == -1) + logerr("dhcp6_writelease: %s",state->leasefile); #ifndef SMALL dhcp6_delegate_prefix(ifp); #endif Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.32 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.33 --- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.32 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Mon Apr 13 15:46:26 2020 @@ -781,8 +781,10 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx * * maybe on a new network. */ ipv6nd_startexpire(ifp); #endif +#ifdef IPV6_MANAGETEMPADDR /* RFC4941 Section 3.5 */ - ipv6_gentempifid(ifp); + ipv6_regentempaddrs(ifp); +#endif #endif dhcpcd_startinterface(ifp); } @@ -1552,26 +1554,39 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx ctx->options |= DHCPCD_DUMPLEASE; size_t nifaces = 0; - for (oi = optind; oi < argc; oi++) { - if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL) - continue; + TAILQ_FOREACH(ifp, ctx->ifaces, next) { if (!ifp->active) continue; - opt = send_interface(NULL, ifp, af); - if (opt != -1) + for (oi = optind; oi < argc; oi++) { + if (strcmp(ifp->name, argv[oi]) == 0) + break; + } + if (optind == argc || oi < argc) { + opt = send_interface(NULL, ifp, af); + if (opt == -1) + goto dumperr; nifaces += (size_t)opt; + } } if (write(fd->fd, &nifaces, sizeof(nifaces)) != sizeof(nifaces)) - return -1; - for (oi = optind; oi < argc; oi++) { - if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL) - continue; + goto dumperr; + TAILQ_FOREACH(ifp, ctx->ifaces, next) { if (!ifp->active) continue; - send_interface(fd, ifp, af); + for (oi = optind; oi < argc; oi++) { + if (strcmp(ifp->name, argv[oi]) == 0) + break; + } + if (optind == argc || oi < argc) { + if (send_interface(fd, ifp, af) == -1) + goto dumperr; + } } ctx->options &= ~DHCPCD_DUMPLEASE; return 0; +dumperr: + ctx->options &= ~DHCPCD_DUMPLEASE; + return -1; } /* Only privileged users can control dhcpcd via the socket. */ @@ -1618,14 +1633,20 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx return 0; } +static const char *dumpskip[] = { + "PATH=", + "pid=", + "chroot=", +}; + static int dhcpcd_readdump(struct dhcpcd_ctx *ctx) { int error = 0; - size_t nifaces, buflen = 0, dlen; + size_t nifaces, buflen = 0, dlen, i; ssize_t len; char *buf = NULL, *dp, *de; - bool print; + const char *skip; again1: len = read(ctx->control_fd, &nifaces, sizeof(nifaces)); @@ -1660,6 +1681,11 @@ again2: buf = nbuf; buflen = dlen; } + if (dlen == 0) { + errno = EINVAL; + error = -1; + goto out; + } again3: if (read(ctx->control_fd, buf, dlen) != (ssize_t)dlen) { if (errno == EAGAIN) @@ -1669,28 +1695,23 @@ again3: } dp = buf; de = dp + dlen; + if (*(dp - 1) != '\0') { + errno = EINVAL; + error = -1; + goto out; + } while (dp < de) { - if (dp + 6 >= de) /* _new and = something */ - break; - if (dp[0] == 'n' && dp[3] == '_') { - if (dp[1] == 'e' && dp[2] == 'w') { - print = true; + for (i = 0; i < __arraycount(dumpskip); i++) { + skip = dumpskip[i]; + if (strncmp(dp, skip, strlen(skip)) == 0) + break; + } + if (i == __arraycount(dumpskip)) { + if (strncmp(dp, "new_", 4) == 0) dp += 4; - } else if (dp[1] == 'd' && - isdigit((unsigned char)dp[2])) - print = true; - else - print = false; - } else - print = false; - while (dp < de && *dp != '\0') { - if (print) - putchar(*dp); - dp++; + printf("%s\n", dp); } - if (print) - putchar('\n'); - dp++; + dp += strlen(dp) + 1; } fflush(stdout); if (nifaces != 1) @@ -2107,16 +2128,11 @@ printpidfile: } #endif - logdebugx(PACKAGE "-" VERSION " starting"); + loginfox(PACKAGE "-" VERSION " starting"); freopen(_PATH_DEVNULL, "r", stdin); #ifdef PRIVSEP - if (ps_init(&ctx) == -1) { - if (errno != 0) { - logerr("ps_init"); - goto exit_failure; - } - } else + if (ps_init(&ctx) == 0) script_runchroot(&ctx, ifo->script); #endif @@ -2169,7 +2185,7 @@ printpidfile: } #endif -#ifdef BSD +#if defined(BSD) && defined(INET6) /* Disable the kernel RTADV sysctl as early as possible. */ if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS) if_disable_rtadv(); Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.17 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.18 --- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.17 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/if-bsd.c Mon Apr 13 15:46:26 2020 @@ -1037,7 +1037,7 @@ if_address6(unsigned char cmd, const str if (ia->addr_flags & IN6_IFF_TENTATIVE) ifa.ifra_flags |= IN6_IFF_TENTATIVE; #endif -#ifdef IPV6_MANGETEMPADDR +#ifdef IPV6_MANAGETEMPADDR if (ia->flags & IPV6_AF_TEMPORARY) ifa.ifra_flags |= IN6_IFF_TEMPORARY; #endif @@ -1524,6 +1524,8 @@ if_missfilter0(struct dhcpcd_ctx *ctx, s #ifdef INET6 if (sa->sa_family == AF_INET6) ifa_setscope(satosin6(sa), ifp->index); +#else + UNUSED(ifp); #endif cp = ctx->rt_missfilter + ctx->rt_missfilterlen; @@ -1728,14 +1730,14 @@ int ip6_temp_preferred_lifetime(__unused const char *ifname) { - return ND6_PRIV_PREFERRED_LIFETIME; + return TEMP_PREFERRED_LIFETIME; } int ip6_temp_valid_lifetime(__unused const char *ifname) { - return ND6_PRIV_VALID_LIFETIME; + return TEMP_VALID_LIFETIME; } #else /* __OpenBSD__ */ Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.17 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.18 --- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.17 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c Mon Apr 13 15:46:26 2020 @@ -101,13 +101,6 @@ __CTASSERT(sizeof(struct nd_opt_rdnss) = #define ND_RA_FLAG_RTPREF_RSV 0x10 #endif -/* RTPREF_MEDIUM has to be 0! */ -#define RTPREF_HIGH 1 -#define RTPREF_MEDIUM 0 -#define RTPREF_LOW (-1) -#define RTPREF_RESERVED (-2) -#define RTPREF_INVALID (-3) /* internal */ - #define EXPIRED_MAX 5 /* Remember 5 expired routers to avoid logspam. */ @@ -580,7 +573,7 @@ ipv6nd_startexpire(struct interface *ifp RTR_CARRIER_EXPIRE, ipv6nd_expire, ifp); } -static int +int ipv6nd_rtpref(struct ra *rap) { Index: src/external/bsd/dhcpcd/dist/src/if-options.c diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.21 src/external/bsd/dhcpcd/dist/src/if-options.c:1.22 --- src/external/bsd/dhcpcd/dist/src/if-options.c:1.21 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/if-options.c Mon Apr 13 15:46:26 2020 @@ -573,6 +573,8 @@ set_option_space(struct dhcpcd_ctx *ctx, return; } #endif +#else + UNUSED(arg); #endif #ifdef INET @@ -1275,6 +1277,7 @@ parse_option(struct dhcpcd_ctx *ctx, con memset(ifo->nomask6, 0xff, sizeof(ifo->nomask6)); /* Allow the bare minimum through */ +#ifdef INET del_option_mask(ifo->nomask, DHO_SUBNETMASK); del_option_mask(ifo->nomask, DHO_CSR); del_option_mask(ifo->nomask, DHO_ROUTER); @@ -1286,11 +1289,14 @@ parse_option(struct dhcpcd_ctx *ctx, con del_option_mask(ifo->nomask, DHO_RENEWALTIME); del_option_mask(ifo->nomask, DHO_REBINDTIME); del_option_mask(ifo->nomask, DHO_DNSSEARCH); +#endif +#ifdef INET6 del_option_mask(ifo->nomask6, D6_OPTION_DNS_SERVERS); del_option_mask(ifo->nomask6, D6_OPTION_DOMAIN_LIST); del_option_mask(ifo->nomask6, D6_OPTION_SOL_MAX_RT); del_option_mask(ifo->nomask6, D6_OPTION_INF_MAX_RT); +#endif break; #ifdef INET Index: src/external/bsd/dhcpcd/dist/src/ipv6.c diff -u src/external/bsd/dhcpcd/dist/src/ipv6.c:1.9 src/external/bsd/dhcpcd/dist/src/ipv6.c:1.10 --- src/external/bsd/dhcpcd/dist/src/ipv6.c:1.9 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/ipv6.c Mon Apr 13 15:46:26 2020 @@ -121,10 +121,7 @@ #endif #ifdef IPV6_MANAGETEMPADDR -static void ipv6_regentempifid(void *); static void ipv6_regentempaddr(void *); -#else -#define ipv6_regentempifid(a) {} #endif int @@ -181,7 +178,7 @@ ipv6_readsecret(struct dhcpcd_ctx *ctx) } /* Ensure that only the dhcpcd user can read the secret. - * Write permission is also denied as chaning it would remove + * Write permission is also denied as changing it would remove * it's stability. */ if ((fp = fopen(SECRET, "w")) == NULL || chmod(SECRET, S_IRUSR) == -1) @@ -217,7 +214,7 @@ static const struct reslowhigh { { 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }; -static int +static bool ipv6_reserved(const struct in6_addr *addr) { uint64_t id, low, high; @@ -227,37 +224,42 @@ ipv6_reserved(const struct in6_addr *add id = be64dec(addr->s6_addr + sizeof(id)); if (id == 0) /* RFC4291 */ return 1; - for (i = 0; i < sizeof(reslowhigh) / sizeof(reslowhigh[0]); i++) { + for (i = 0; i < __arraycount(reslowhigh); i++) { r = &reslowhigh[i]; low = be64dec(r->low); high = be64dec(r->high); if (id >= low && id <= high) - return 1; + return true; } - return 0; + return false; } /* RFC7217 */ static int -ipv6_makestableprivate1(struct in6_addr *addr, - const struct in6_addr *prefix, int prefix_len, +ipv6_makestableprivate1(struct dhcpcd_ctx *ctx, + struct in6_addr *addr, const struct in6_addr *prefix, int prefix_len, const unsigned char *netiface, size_t netiface_len, const unsigned char *netid, size_t netid_len, unsigned short vlanid, - uint32_t *dad_counter, - const unsigned char *secret, size_t secret_len) + uint32_t *dad_counter) { unsigned char buf[2048], *p, digest[SHA256_DIGEST_LENGTH]; size_t len, l; - SHA256_CTX ctx; + SHA256_CTX sha_ctx; if (prefix_len < 0 || prefix_len > 120) { errno = EINVAL; return -1; } + if (ctx->secret_len == 0) { + if (ipv6_readsecret(ctx) == -1) + return -1; + } + l = (size_t)(ROUNDUP8(prefix_len) / NBBY); - len = l + netiface_len + netid_len + sizeof(*dad_counter) + secret_len; + len = l + netiface_len + netid_len + sizeof(*dad_counter) + + ctx->secret_len; if (vlanid != 0) len += sizeof(vlanid); if (len > sizeof(buf)) { @@ -282,15 +284,15 @@ ipv6_makestableprivate1(struct in6_addr } memcpy(p, dad_counter, sizeof(*dad_counter)); p += sizeof(*dad_counter); - memcpy(p, secret, secret_len); + memcpy(p, ctx->secret, ctx->secret_len); /* Make an address using the digest of the above. * RFC7217 Section 5.1 states that we shouldn't use MD5. * Pity as we use that for HMAC-MD5 which is still deemed OK. * SHA-256 is recommended */ - SHA256_Init(&ctx); - SHA256_Update(&ctx, buf, len); - SHA256_Final(digest, &ctx); + SHA256_Init(&sha_ctx); + SHA256_Update(&sha_ctx, buf, len); + SHA256_Final(digest, &sha_ctx); p = addr->s6_addr; memcpy(p, prefix, l); @@ -320,29 +322,52 @@ 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 * as the interface identifier */ - r = ipv6_makestableprivate1(addr, prefix, prefix_len, + r = ipv6_makestableprivate1(ifp->ctx, addr, prefix, prefix_len, ifp->hwaddr, ifp->hwlen, ifp->ssid, ifp->ssid_len, - ifp->vlanid, &dad, - ifp->ctx->secret, ifp->ctx->secret_len); + ifp->vlanid, &dad); if (r == 0) *dad_counter = (int)dad; return r; } +#ifdef IPV6_AF_TEMPORARY +static int +ipv6_maketemporaryaddress(struct in6_addr *addr, + const struct in6_addr *prefix, int prefix_len, + const struct interface *ifp) +{ + struct in6_addr mask; + struct interface *ifpn; + + if (ipv6_mask(&mask, prefix_len) == -1) + return -1; + *addr = *prefix; + +again: + addr->s6_addr32[2] |= (arc4random() & ~mask.s6_addr32[2]); + addr->s6_addr32[3] |= (arc4random() & ~mask.s6_addr32[3]); + + TAILQ_FOREACH(ifpn, ifp->ctx->ifaces, next) { + if (ipv6_iffindaddr(ifpn, addr, 0) != NULL) + break; + } + if (ifpn != NULL) + goto again; + if (ipv6_reserved(addr)) + goto again; + return 0; +} +#endif + int ipv6_makeaddr(struct in6_addr *addr, struct interface *ifp, - const struct in6_addr *prefix, int prefix_len) + const struct in6_addr *prefix, int prefix_len, unsigned int flags) { const struct ipv6_addr *ap; int dad; @@ -352,6 +377,13 @@ ipv6_makeaddr(struct in6_addr *addr, str return -1; } +#ifdef IPV6_AF_TEMPORARY + if (flags & IPV6_AF_TEMPORARY) + return ipv6_maketemporaryaddress(addr, prefix, prefix_len, ifp); +#else + UNUSED(flags); +#endif + if (ifp->options->options & DHCPCD_SLAACPRIVATE) { dad = 0; if (ipv6_makestableprivate(addr, @@ -1052,11 +1084,6 @@ ipv6_getstate(struct interface *ifp) } TAILQ_INIT(&state->addrs); TAILQ_INIT(&state->ll_callbacks); - - /* Regenerate new ids */ - if (ifp->options && - ip6_use_tempaddr(ifp->name)) - ipv6_regentempifid(ifp); } return state; } @@ -1523,7 +1550,9 @@ ipv6_newaddr(struct interface *ifp, cons /* If adding a new DHCP / RA derived address, check current flags * from an existing address. */ - if (flags & IPV6_AF_AUTOCONF) + if (tempaddr) + iaf = NULL; + else if (flags & IPV6_AF_AUTOCONF) iaf = ipv6nd_iffindprefix(ifp, addr, prefix_len); else iaf = ipv6_iffindaddr(ifp, addr, 0); @@ -1551,14 +1580,15 @@ ipv6_newaddr(struct interface *ifp, cons if (prefix_len == 128) goto makepfx; - else if (ia->flags & IPV6_AF_AUTOCONF && !tempaddr) { + else if (ia->flags & IPV6_AF_AUTOCONF) { ia->prefix = *addr; if (iaf != NULL) memcpy(&ia->addr, &iaf->addr, sizeof(ia->addr)); else { ia->dadcounter = ipv6_makeaddr(&ia->addr, ifp, &ia->prefix, - ia->prefix_len); + ia->prefix_len, + ia->flags); if (ia->dadcounter == -1) goto err; } @@ -1736,12 +1766,6 @@ ipv6_start(struct interface *ifp) if (ipv6_tryaddlinklocal(ifp) == -1) return -1; - if (IPV6_CSTATE(ifp)) { - /* Regenerate new ids */ - if (ip6_use_tempaddr(ifp->name)) - ipv6_regentempifid(ifp); - } - return 0; } @@ -1838,31 +1862,8 @@ ipv6_handleifa_addrs(int cmd, } #ifdef IPV6_MANAGETEMPADDR -static const struct ipv6_addr * -ipv6_findaddrid(struct dhcpcd_ctx *ctx, uint8_t *addr) -{ - const struct interface *ifp; - const struct ipv6_state *state; - const struct ipv6_addr *ia; - - TAILQ_FOREACH(ifp, ctx->ifaces, next) { - if ((state = IPV6_CSTATE(ifp))) { - TAILQ_FOREACH(ia, &state->addrs, next) { - if (memcmp(&ia->addr.s6_addr[8], addr, 8) == 0) - return ia; - } - } - } - return NULL; -} - -static const uint8_t nullid[8]; -static const uint8_t anycastid[8] = { - 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 }; -static const uint8_t isatapid[4] = { 0x00, 0x00, 0x5e, 0xfe }; - static void -ipv6_regen_desync(struct interface *ifp, int force) +ipv6_regen_desync(struct interface *ifp, bool force) { struct ipv6_state *state; unsigned int max, pref; @@ -1871,7 +1872,7 @@ ipv6_regen_desync(struct interface *ifp, /* RFC4941 Section 5 states that DESYNC_FACTOR must never be * greater than TEMP_VALID_LIFETIME - REGEN_ADVANCE. - * I believe this is an error and it should be never be greateter than + * I believe this is an error and it should be never be greater than * TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE. */ pref = (unsigned int)ip6_temp_preferred_lifetime(ifp->name); max = pref - REGEN_ADVANCE; @@ -1881,63 +1882,7 @@ ipv6_regen_desync(struct interface *ifp, state->desync_factor = arc4random_uniform(MIN(MAX_DESYNC_FACTOR, max)); max = pref - state->desync_factor - REGEN_ADVANCE; - eloop_timeout_add_sec(ifp->ctx->eloop, max, ipv6_regentempifid, ifp); -} - -void -ipv6_gentempifid(struct interface *ifp) -{ - struct ipv6_state *state; - MD5_CTX md5; - uint8_t seed[16], digest[16]; - int retry; - - if ((state = IPV6_STATE(ifp)) == NULL) - return; - - retry = 0; - if (memcmp(nullid, state->randomseed0, sizeof(nullid)) == 0) { - uint32_t r; - - r = arc4random(); - memcpy(seed, &r, sizeof(r)); - r = arc4random(); - memcpy(seed + sizeof(r), &r, sizeof(r)); - } else - memcpy(seed, state->randomseed0, sizeof(state->randomseed0)); - - memcpy(seed + sizeof(state->randomseed0), - state->randomseed1, sizeof(state->randomseed1)); - -again: - MD5Init(&md5); - MD5Update(&md5, seed, sizeof(seed)); - MD5Final(digest, &md5); - - /* RFC4941 Section 3.2.1.1 - * Take the left-most 64bits and set bit 6 to zero */ - memcpy(state->randomid, digest, sizeof(state->randomid)); - state->randomid[0] = (uint8_t)(state->randomid[0] & ~EUI64_UBIT); - - /* RFC4941 Section 3.2.1.4 - * Reject reserved or existing id's */ - if (memcmp(nullid, state->randomid, sizeof(nullid)) == 0 || - (memcmp(anycastid, state->randomid, 7) == 0 && - (anycastid[7] & state->randomid[7]) == anycastid[7]) || - memcmp(isatapid, state->randomid, sizeof(isatapid)) == 0 || - ipv6_findaddrid(ifp->ctx, state->randomid)) - { - if (++retry < GEN_TEMPID_RETRY_MAX) { - memcpy(seed, digest + 8, 8); - goto again; - } - memset(state->randomid, 0, sizeof(state->randomid)); - } - - /* RFC4941 Section 3.2.1.6 - * Save the right-most 64bits of the digest */ - memcpy(state->randomseed0, digest + 8, - sizeof(state->randomseed0)); + eloop_timeout_add_sec(ifp->ctx->eloop, max, ipv6_regentempaddrs, ifp); } /* RFC4941 Section 3.3.7 */ @@ -1970,75 +1915,27 @@ struct ipv6_addr * ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timespec *now) { struct ipv6_state *state; - const struct ipv6_state *cstate; - int genid; - struct in6_addr addr, mask; - uint32_t randid[2]; - const struct interface *ifp; - const struct ipv6_addr *ap; + struct interface *ifp = ia0->iface; struct ipv6_addr *ia; - uint32_t i, trylimit; + uint32_t i; - trylimit = TEMP_IDGEN_RETRIES; - state = IPV6_STATE(ia0->iface); - genid = 0; - - addr = ia0->addr; - ipv6_mask(&mask, ia0->prefix_len); - /* clear the old ifid */ - for (i = 0; i < 4; i++) - addr.s6_addr32[i] &= mask.s6_addr32[i]; - -again: - if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0) - genid = 1; - if (genid) { - memcpy(state->randomseed1, &ia0->addr.s6_addr[8], - sizeof(state->randomseed1)); - ipv6_gentempifid(ia0->iface); - if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0) { - errno = EFAULT; - return NULL; - } - } - memcpy(&randid[0], state->randomid, sizeof(randid[0])); - memcpy(&randid[1], state->randomid + sizeof(randid[1]), - sizeof(randid[2])); - addr.s6_addr32[2] |= randid[0] & ~mask.s6_addr32[2]; - addr.s6_addr32[3] |= randid[1] & ~mask.s6_addr32[3]; - - /* Ensure we don't already have it */ - TAILQ_FOREACH(ifp, ia0->iface->ctx->ifaces, next) { - cstate = IPV6_CSTATE(ifp); - if (cstate) { - TAILQ_FOREACH(ap, &cstate->addrs, next) { - if (IN6_ARE_ADDR_EQUAL(&ap->addr, &addr)) { - if (--trylimit == 0) { - errno = EEXIST; - return NULL; - } - genid = 1; - goto again; - } - } - } - } - - ia = ipv6_newaddr(ia0->iface, &addr, ia0->prefix_len, + ia = ipv6_newaddr(ifp, &ia0->prefix, ia0->prefix_len, IPV6_AF_AUTOCONF | IPV6_AF_TEMPORARY); - /* Must be made tentative, for our DaD to work */ - ia->addr_flags = IN6_IFF_TENTATIVE; + if (ia == NULL) + return NULL; + ia->dadcallback = ipv6_tempdadcallback; ia->created = ia->acquired = now ? *now : ia0->acquired; /* Ensure desync is still valid */ - ipv6_regen_desync(ia->iface, 0); + ipv6_regen_desync(ifp, false); /* RFC4941 Section 3.3.4 */ - i = (uint32_t)ip6_temp_preferred_lifetime(ia0->iface->name) - + state = IPV6_STATE(ia->iface); + i = (uint32_t)ip6_temp_preferred_lifetime(ifp->name) - state->desync_factor; ia->prefix_pltime = MIN(ia0->prefix_pltime, i); - i = (uint32_t)ip6_temp_valid_lifetime(ia0->iface->name); + i = (uint32_t)ip6_temp_valid_lifetime(ifp->name); ia->prefix_vltime = MIN(ia0->prefix_vltime, i); if (ia->prefix_pltime <= REGEN_ADVANCE || ia->prefix_pltime > ia0->prefix_vltime) @@ -2089,7 +1986,7 @@ ipv6_settemptime(struct ipv6_addr *ia, i } /* Ensure desync is still valid */ - ipv6_regen_desync(ap->iface, 0); + ipv6_regen_desync(ap->iface, false); /* RFC4941 Section 3.3.2 * Extend temporary times, but ensure that they @@ -2147,31 +2044,44 @@ ipv6_addtempaddrs(struct interface *ifp, } static void -ipv6_regentempaddr(void *arg) +ipv6_regentempaddr0(struct ipv6_addr *ia, struct timespec *tv) { - struct ipv6_addr *ia = arg, *ia1; - struct timespec tv; + struct ipv6_addr *ia1; logdebugx("%s: regen temp addr %s", ia->iface->name, ia->saddr); - clock_gettime(CLOCK_MONOTONIC, &tv); - ia1 = ipv6_createtempaddr(ia, &tv); + ia1 = ipv6_createtempaddr(ia, tv); if (ia1) - ipv6_addaddr(ia1, &tv); + ipv6_addaddr(ia1, tv); else logerr(__func__); } static void -ipv6_regentempifid(void *arg) +ipv6_regentempaddr(void *arg) +{ + struct timespec tv; + + clock_gettime(CLOCK_MONOTONIC, &tv); + ipv6_regentempaddr0(arg, &tv); +} + +void +ipv6_regentempaddrs(void *arg) { struct interface *ifp = arg; + struct timespec tv; struct ipv6_state *state; + struct ipv6_addr *ia; - state = IPV6_STATE(ifp); - if (memcmp(state->randomid, nullid, sizeof(state->randomid))) - ipv6_gentempifid(ifp); + ipv6_regen_desync(ifp, true); - ipv6_regen_desync(ifp, 1); + clock_gettime(CLOCK_MONOTONIC, &tv); + state = IPV6_STATE(ifp); + TAILQ_FOREACH(ia, &state->addrs, next) { + if (ia->flags & IPV6_AF_TEMPORARY && + !(ia->flags & IPV6_AF_STALE)) + ipv6_regentempaddr0(ia, &tv); + } } #endif /* IPV6_MANAGETEMPADDR */ @@ -2343,6 +2253,9 @@ inet6_raroutes(rb_tree_t *routes, struct rt = inet6_makeprefix(rap->iface, rap, addr); if (rt) { rt->rt_dflags |= RTDF_RA; +#ifdef HAVE_ROUTE_PREF + rt->rt_pref = ipv6nd_rtpref(rap); +#endif rt_proto_add(routes, rt); } } @@ -2354,6 +2267,9 @@ inet6_raroutes(rb_tree_t *routes, struct if (rt == NULL) continue; rt->rt_dflags |= RTDF_RA; +#ifdef HAVE_ROUTE_PREF + rt->rt_pref = ipv6nd_rtpref(rap); +#endif rt_proto_add(routes, rt); } return 0; Index: src/external/bsd/dhcpcd/dist/src/ipv6.h diff -u src/external/bsd/dhcpcd/dist/src/ipv6.h:1.9 src/external/bsd/dhcpcd/dist/src/ipv6.h:1.10 --- src/external/bsd/dhcpcd/dist/src/ipv6.h:1.9 Thu Apr 2 12:41:48 2020 +++ src/external/bsd/dhcpcd/dist/src/ipv6.h Mon Apr 13 15:46:26 2020 @@ -59,9 +59,7 @@ #define TEMP_PREFERRED_LIFETIME 86400 /* 1 day */ #define REGEN_ADVANCE 5 /* seconds */ #define MAX_DESYNC_FACTOR 600 /* 10 minutes */ - #define TEMP_IDGEN_RETRIES 3 -#define GEN_TEMPID_RETRY_MAX 5 /* RFC7217 constants */ #define IDGEN_RETRIES 3 @@ -245,9 +243,6 @@ struct ipv6_state { #ifdef IPV6_MANAGETEMPADDR uint32_t desync_factor; - uint8_t randomseed0[8]; /* upper 64 bits of MD5 digest */ - uint8_t randomseed1[8]; /* lower 64 bits */ - uint8_t randomid[8]; #endif }; @@ -259,11 +254,10 @@ struct ipv6_state { int ipv6_init(struct dhcpcd_ctx *); -int ipv6_makestableprivate(struct in6_addr *addr, - const struct in6_addr *prefix, int prefix_len, - const struct interface *ifp, int *dad_counter); +int ipv6_makestableprivate(struct in6_addr *, + const struct in6_addr *, int, const struct interface *, int *); int ipv6_makeaddr(struct in6_addr *, struct interface *, - const struct in6_addr *, int); + const struct in6_addr *, int, unsigned int); int ipv6_mask(struct in6_addr *, int); uint8_t ipv6_prefixlen(const struct in6_addr *); int ipv6_userprefix( const struct in6_addr *, short prefix_len, @@ -301,14 +295,11 @@ void ipv6_freedrop(struct interface *, i #define ipv6_drop(ifp) ipv6_freedrop((ifp), 2) #ifdef IPV6_MANAGETEMPADDR -void ipv6_gentempifid(struct interface *); struct ipv6_addr *ipv6_createtempaddr(struct ipv6_addr *, const struct timespec *); struct ipv6_addr *ipv6_settemptime(struct ipv6_addr *, int); void ipv6_addtempaddrs(struct interface *, const struct timespec *); -#else -#define ipv6_gentempifid(a) {} -#define ipv6_settempstale(a) {} +void ipv6_regentempaddrs(void *); #endif int ipv6_start(struct interface *); Index: src/external/bsd/dhcpcd/dist/src/script.c diff -u src/external/bsd/dhcpcd/dist/src/script.c:1.4 src/external/bsd/dhcpcd/dist/src/script.c:1.5 --- src/external/bsd/dhcpcd/dist/src/script.c:1.4 Sun Apr 5 15:41:45 2020 +++ src/external/bsd/dhcpcd/dist/src/script.c Mon Apr 13 15:46:26 2020 @@ -84,7 +84,7 @@ if_printoptions(void) } pid_t -script_exec(const struct dhcpcd_ctx *ctx, char *const *argv, char *const *env) +script_exec(char *const *argv, char *const *env) { pid_t pid = 0; posix_spawnattr_t attr; @@ -105,11 +105,10 @@ script_exec(const struct dhcpcd_ctx *ctx flags = POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF; posix_spawnattr_setflags(&attr, flags); sigemptyset(&defsigs); + posix_spawnattr_setsigmask(&attr, &defsigs); for (i = 0; i < dhcpcd_signals_len; i++) sigaddset(&defsigs, dhcpcd_signals[i]); posix_spawnattr_setsigdefault(&attr, &defsigs); - sigemptyset(&defsigs); - posix_spawnattr_setsigmask(&attr, &defsigs); #endif errno = 0; r = posix_spawn(&pid, argv[0], NULL, &attr, argv, env); @@ -658,7 +657,7 @@ script_run(struct dhcpcd_ctx *ctx, char pid_t pid; int status = 0; - pid = script_exec(ctx, argv, ctx->script_env); + pid = script_exec(argv, ctx->script_env); if (pid == -1) logerr("%s: %s", __func__, argv[0]); else if (pid != 0) {