Module Name: src Committed By: roy Date: Fri Dec 20 12:01:36 UTC 2019
Modified Files: src/external/bsd/dhcpcd/dist/hooks: dhcpcd-run-hooks.in src/external/bsd/dhcpcd/dist/src: dhcp.c dhcp6.c dhcpcd.c ipv6.c ipv6.h ipv6nd.c Log Message: Sync To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 \ src/external/bsd/dhcpcd/dist/hooks/dhcpcd-run-hooks.in cvs rdiff -u -r1.30 -r1.31 src/external/bsd/dhcpcd/dist/src/dhcp.c cvs rdiff -u -r1.14 -r1.15 src/external/bsd/dhcpcd/dist/src/dhcp6.c cvs rdiff -u -r1.29 -r1.30 src/external/bsd/dhcpcd/dist/src/dhcpcd.c cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/src/ipv6.c \ src/external/bsd/dhcpcd/dist/src/ipv6.h cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/src/ipv6nd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/dhcpcd/dist/hooks/dhcpcd-run-hooks.in diff -u src/external/bsd/dhcpcd/dist/hooks/dhcpcd-run-hooks.in:1.3 src/external/bsd/dhcpcd/dist/hooks/dhcpcd-run-hooks.in:1.4 --- src/external/bsd/dhcpcd/dist/hooks/dhcpcd-run-hooks.in:1.3 Thu Feb 7 21:37:36 2019 +++ src/external/bsd/dhcpcd/dist/hooks/dhcpcd-run-hooks.in Fri Dec 20 12:01:35 2019 @@ -212,7 +212,7 @@ valid_domainname_list() # With the advent of alternative init systems, it's possible to have # more than one installed. So we need to try and guess what one we're -# using unless overriden by configure. +# using unless overridden by configure. detect_init() { _service_exists="@SERVICEEXISTS@" Index: src/external/bsd/dhcpcd/dist/src/dhcp.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.30 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.31 --- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.30 Wed Nov 13 10:50:22 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcp.c Fri Dec 20 12:01:35 2019 @@ -176,6 +176,11 @@ get_option(struct dhcpcd_ctx *ctx, const uint8_t *op; size_t bl; + if (bootp == NULL || bootp_len < DHCP_MIN_LEN) { + errno = EINVAL; + return NULL; + } + /* Check we have the magic cookie */ if (!IS_DHCP(bootp)) { errno = ENOTSUP; @@ -484,7 +489,7 @@ print_rfc3361(FILE *fp, const uint8_t *d return -1; break; case 1: - if (dl == 0 || dl % 4 != 0) { + if (dl % 4 != 0) { errno = EINVAL; break; } @@ -1179,7 +1184,7 @@ read_lease(struct interface *ifp, struct * (it should be more, and our read packet enforces this so this * code should not be needed, but of course people could * scribble whatever in the stored lease file. */ - if (bytes < offsetof(struct bootp, vend) + 4) { + if (bytes < DHCP_MIN_LEN) { free(lease); logerrx("%s: %s: truncated lease", ifp->name, __func__); return 0; @@ -1540,7 +1545,7 @@ dhcp_close(struct interface *ifp) } static int -dhcp_openudp(struct interface *ifp) +dhcp_openudp(struct in_addr *ia) { int s; struct sockaddr_in sin; @@ -1551,29 +1556,25 @@ dhcp_openudp(struct interface *ifp) n = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) - goto eexit; + goto errexit; #ifdef IP_RECVIF if (setsockopt(s, IPPROTO_IP, IP_RECVIF, &n, sizeof(n)) == -1) - goto eexit; + goto errexit; #else if (setsockopt(s, IPPROTO_IP, IP_RECVPKTINFO, &n, sizeof(n)) == -1) - goto eexit; + goto errexit; #endif memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(BOOTPC); - if (ifp) { - const struct dhcp_state *state = D_CSTATE(ifp); - - if (state->addr) - sin.sin_addr.s_addr = state->addr->addr.s_addr; - } + if (ia != NULL) + sin.sin_addr = *ia; if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) - goto eexit; + goto errexit; return s; -eexit: +errexit: close(s); return -1; } @@ -1675,7 +1676,7 @@ dhcp_sendudp(struct interface *ifp, stru fd = state->udp_fd; if (fd == -1) { - fd = dhcp_openudp(ifp); + fd = dhcp_openudp(state->addr != NULL ?&state->addr->addr:NULL); if (fd == -1) return -1; } @@ -1734,7 +1735,9 @@ send_message(struct interface *ifp, uint goto fail; len = (size_t)r; - if (ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL) + if (!(state->added & STATE_FAKE) && + state->addr != NULL && + ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL) from.s_addr = state->lease.addr.s_addr; else from.s_addr = INADDR_ANY; @@ -1751,7 +1754,7 @@ send_message(struct interface *ifp, uint * even if they are setup to send them. * Broadcasting from UDP is only an optimisation for rebinding * and on BSD, at least, is reliant on the subnet route being - * correctly configured to recieve the unicast reply. + * correctly configured to receive the unicast reply. * As such, we always broadcast and receive the reply to it via BPF. * This also guarantees we have a DHCP server attached to the * interface we want to configure because we can't dictate the @@ -2266,10 +2269,11 @@ dhcp_bind(struct interface *ifp) return; dhcp_close(ifp); + /* If not in master mode, open an address specific socket. */ if (ctx->udp_fd != -1) return; - state->udp_fd = dhcp_openudp(ifp); + state->udp_fd = dhcp_openudp(&state->addr->addr); if (state->udp_fd == -1) { logerr(__func__); /* Address sharing without master mode is not supported. @@ -2352,6 +2356,7 @@ dhcp_arp_new(struct interface *ifp, stru #ifdef KERNEL_RFC5227 astate->announced_cb = dhcp_arp_announced; #else + astate->announced_cb = NULL; astate->defend_failed_cb = dhcp_arp_defend_failed; #endif return astate; @@ -2501,7 +2506,7 @@ dhcp_inform(struct interface *ifp) state->offer_len = dhcp_message_new(&state->offer, &ifo->req_addr, &ifo->req_mask); #ifdef ARP - if (dhcp_arp_address(ifp) == 0) + if (dhcp_arp_address(ifp) != 1) return; #endif ia = ipv4_iffindaddr(ifp, @@ -3390,7 +3395,7 @@ dhcp_handlebootp(struct interface *ifp, } static void -dhcp_handlebpf(struct interface *ifp, uint8_t *data, size_t len) +dhcp_packet(struct interface *ifp, uint8_t *data, size_t len) { struct bootp *bootp; struct in_addr from; @@ -3445,7 +3450,7 @@ dhcp_readbpf(void *arg) } break; } - dhcp_handlebpf(ifp, buf, (size_t)bytes); + dhcp_packet(ifp, buf, (size_t)bytes); /* Check we still have a state after processing. */ if ((state = D_STATE(ifp)) == NULL) break; Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.14 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.15 --- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.14 Wed Nov 13 10:50:22 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Fri Dec 20 12:01:35 2019 @@ -171,7 +171,7 @@ static const char * const dhcp6_statuses static void dhcp6_bind(struct interface *, const char *, const char *); static void dhcp6_failinform(void *); -static int dhcp6_listen(struct dhcpcd_ctx *, struct ipv6_addr *); +static int dhcp6_openudp(unsigned int, struct in6_addr *); static void dhcp6_recvaddr(void *); void @@ -2132,13 +2132,10 @@ dhcp6_findpd(struct interface *ifp, cons a->dadcallback = dhcp6_dadcallback; a->ia_type = D6_OPTION_IA_PD; memcpy(a->iaid, iaid, sizeof(a->iaid)); - TAILQ_INIT(&a->pd_pfxs); TAILQ_INSERT_TAIL(&state->addrs, a, next); } else { - if (!(a->flags & IPV6_AF_DELEGATEDPFX)) { + if (!(a->flags & IPV6_AF_DELEGATEDPFX)) a->flags |= IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX; - TAILQ_INIT(&a->pd_pfxs); - } a->flags &= ~(IPV6_AF_STALE | IPV6_AF_EXTENDED | IPV6_AF_REQUEST); @@ -2341,6 +2338,46 @@ dhcp6_findia(struct interface *ifp, stru return i; } +#ifndef SMALL +static void +dhcp6_deprecatedele(struct ipv6_addr *ia) +{ + struct ipv6_addr *da, *dan, *dda; + struct timespec now; + struct dhcp6_state *state; + + timespecclear(&now); + TAILQ_FOREACH_SAFE(da, &ia->pd_pfxs, pd_next, dan) { + if (ia->prefix_vltime == 0) { + if (da->prefix_vltime != 0) + da->prefix_vltime = 0; + else + continue; + } else if (da->prefix_pltime != 0) + da->prefix_pltime = 0; + else + continue; + + if (ipv6_doaddr(da, &now) != -1) + continue; + + /* Delegation deleted, forget it. */ + TAILQ_REMOVE(&ia->pd_pfxs, da, pd_next); + + /* Delete it from the interface. */ + state = D6_STATE(da->iface); + TAILQ_FOREACH(dda, &state->addrs, next) { + if (IN6_ARE_ADDR_EQUAL(&dda->addr, &da->addr)) + break; + } + if (dda != NULL) { + TAILQ_REMOVE(&state->addrs, dda, next); + ipv6_freeaddr(dda); + } + } +} +#endif + static void dhcp6_deprecateaddrs(struct ipv6_addrhead *addrs) { @@ -2363,24 +2400,8 @@ dhcp6_deprecateaddrs(struct ipv6_addrhea #ifndef SMALL /* If we delegated from this prefix, deprecate or remove * the delegations. */ - if (ia->flags & IPV6_AF_DELEGATEDPFX) { - struct ipv6_addr *da; - bool touched = false; - - TAILQ_FOREACH(da, &ia->pd_pfxs, pd_next) { - if (ia->prefix_vltime == 0) { - if (da->prefix_vltime != 0) { - da->prefix_vltime = 0; - touched = true; - } - } else if (da->prefix_pltime != 0) { - da->prefix_pltime = 0; - touched = true; - } - } - if (touched) - ipv6_addaddrs(&ia->pd_pfxs); - } + if (ia->flags & IPV6_AF_DELEGATEDPFX) + dhcp6_deprecatedele(ia); #endif if (ia->flags & IPV6_AF_REQUEST) { @@ -2988,8 +3009,9 @@ dhcp6_bind(struct interface *ifp, const TAILQ_FOREACH(ia, &state->addrs, next) { if (ia->flags & IPV6_AF_STALE) continue; - if (!(state->renew == ND6_INFINITE_LIFETIME && - ia->prefix_vltime == ND6_INFINITE_LIFETIME) + if (!(state->renew == ND6_INFINITE_LIFETIME + && ia->prefix_vltime == ND6_INFINITE_LIFETIME) + && ia->prefix_vltime != 0 && ia->prefix_vltime <= state->renew) logwarnx( "%s: %s will expire before renewal", @@ -3557,6 +3579,42 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, st ifp = ifp1; } +#if 0 + /* + * Handy code to inject raw DHCPv6 packets over responses + * from our server. + * This allows me to take a 3rd party wireshark trace and + * replay it in my code. + */ + static int replyn = 0; + char fname[PATH_MAX], tbuf[64 * 1024]; + int fd; + ssize_t tlen; + uint8_t *si1, *si2; + uint16_t si_len1, si_len2; + + snprintf(fname, sizeof(fname), + "/tmp/dhcp6.reply%d.raw", replyn++); + fd = open(fname, O_RDONLY, 0); + if (fd == -1) { + logerr("%s: open `%s'", __func__, fname); + return; + } + tlen = read(fd, tbuf, sizeof(tbuf)); + if (tlen == -1) + logerr("%s: read `%s'", __func__, fname); + close(fd); + + /* Copy across ServerID so we can work with our own server. */ + si1 = dhcp6_findmoption(r, len, D6_OPTION_SERVERID, &si_len1); + si2 = dhcp6_findmoption(tbuf, (size_t)tlen, + D6_OPTION_SERVERID, &si_len2); + if (si1 != NULL && si2 != NULL && si_len1 == si_len2) + memcpy(si2, si1, si_len2); + r = (struct dhcp6_message *)tbuf; + len = (size_t)tlen; +#endif + dhcp6_recvif(ifp, sfrom, r, len); } @@ -3606,7 +3664,7 @@ dhcp6_recvctx(void *arg) } static int -dhcp6_listen(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia) +dhcp6_openudp(unsigned int ifindex, struct in6_addr *ia) { struct sockaddr_in6 sa; int n, s; @@ -3629,8 +3687,8 @@ dhcp6_listen(struct dhcpcd_ctx *ctx, str #endif if (ia != NULL) { - memcpy(&sa.sin6_addr, &ia->addr, sizeof(sa.sin6_addr)); - sa.sin6_scope_id = ia->iface->index; + memcpy(&sa.sin6_addr, ia, sizeof(sa.sin6_addr)); + sa.sin6_scope_id = ifindex; } if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) @@ -3640,11 +3698,6 @@ dhcp6_listen(struct dhcpcd_ctx *ctx, str if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &n, sizeof(n)) == -1) goto errexit; - if (ia != NULL) { - ia->dhcp6_fd = s; - eloop_event_add(ctx->eloop, s, dhcp6_recvaddr, ia); - } - return s; errexit: @@ -3686,18 +3739,6 @@ dhcp6_activateinterfaces(struct interfac } #endif -static int -dhcp6_open(struct dhcpcd_ctx *ctx) -{ - - if (ctx->dhcp6_fd != -1 || - (ctx->dhcp6_fd = dhcp6_listen(ctx, NULL)) == -1) - return ctx->dhcp6_fd; - - eloop_event_add(ctx->eloop, ctx->dhcp6_fd, dhcp6_recvctx, ctx); - return ctx->dhcp6_fd; -} - static void dhcp6_start1(void *arg) { @@ -3708,9 +3749,13 @@ dhcp6_start1(void *arg) size_t i; const struct dhcp_compat *dhc; - if (ctx->options & DHCPCD_MASTER) { - if (dhcp6_open(ctx) == -1) + if (ctx->options & DHCPCD_MASTER && ctx->dhcp6_fd == -1) { + ctx->dhcp6_fd = dhcp6_openudp(0, NULL); + if (ctx->dhcp6_fd == -1) { + logerr(__func__); return; + } + eloop_event_add(ctx->eloop, ctx->dhcp6_fd, dhcp6_recvctx, ctx); } state = D6_STATE(ifp); @@ -3974,7 +4019,13 @@ dhcp6_handleifa(int cmd, struct ipv6_add !(ifp->ctx->options & DHCPCD_MASTER) && ifp->options->options & DHCPCD_DHCP6 && ia->dhcp6_fd == -1) - dhcp6_listen(ia->iface->ctx, ia); + { + ia->dhcp6_fd = dhcp6_openudp(ia->iface->index, &ia->addr); + if (ia->dhcp6_fd != -1) + eloop_event_add(ia->iface->ctx->eloop, ia->dhcp6_fd, + dhcp6_recvaddr, ia); + } + if ((state = D6_STATE(ifp)) != NULL) ipv6_handleifa_addrs(cmd, &state->addrs, ia, pid); Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.29 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.30 --- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.29 Wed Nov 13 10:50:22 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Fri Dec 20 12:01:35 2019 @@ -992,7 +992,7 @@ run_preinit(struct interface *ifp) return; script_runreason(ifp, "PREINIT"); - if (ifp->wireless) + if (ifp->wireless && ifp->carrier == LINK_UP) dhcpcd_reportssid(ifp); if (ifp->options->options & DHCPCD_LINK && ifp->carrier != LINK_UNKNOWN) script_runreason(ifp, Index: src/external/bsd/dhcpcd/dist/src/ipv6.c diff -u src/external/bsd/dhcpcd/dist/src/ipv6.c:1.6 src/external/bsd/dhcpcd/dist/src/ipv6.c:1.7 --- src/external/bsd/dhcpcd/dist/src/ipv6.c:1.6 Wed Oct 16 14:54:39 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6.c Fri Dec 20 12:01:35 2019 @@ -920,43 +920,54 @@ ipv6_findaddr(struct dhcpcd_ctx *ctx, co #endif } +int +ipv6_doaddr(struct ipv6_addr *ia, struct timespec *now) +{ + + /* A delegated prefix is not an address. */ + if (ia->flags & IPV6_AF_DELEGATEDPFX) + return 0; + + if (ia->prefix_vltime == 0) { + if (ia->flags & IPV6_AF_ADDED) + ipv6_deleteaddr(ia); + eloop_q_timeout_delete(ia->iface->ctx->eloop, + 0, NULL, ia); + if (ia->flags & IPV6_AF_REQUEST) { + ia->flags &= ~IPV6_AF_ADDED; + return 0; + } + return -1; + } + + if (ia->flags & IPV6_AF_STALE || + IN6_IS_ADDR_UNSPECIFIED(&ia->addr)) + return 0; + + if (!timespecisset(now)) + clock_gettime(CLOCK_MONOTONIC, now); + ipv6_addaddr(ia, now); + return ia->flags & IPV6_AF_NEW ? 1 : 0; +} + ssize_t -ipv6_addaddrs(struct ipv6_addrhead *addrs) +ipv6_addaddrs(struct ipv6_addrhead *iaddrs) { - struct ipv6_addr *ap, *apn; - ssize_t i; struct timespec now; + struct ipv6_addr *ia, *ian; + ssize_t i, r; i = 0; timespecclear(&now); - TAILQ_FOREACH_SAFE(ap, addrs, next, apn) { - /* A delegated prefix is not an address. */ - if (ap->flags & IPV6_AF_DELEGATEDPFX) - continue; - if (ap->prefix_vltime == 0) { - if (ap->flags & IPV6_AF_ADDED) { - ipv6_deleteaddr(ap); - i++; - } - eloop_q_timeout_delete(ap->iface->ctx->eloop, - 0, NULL, ap); - if (ap->flags & IPV6_AF_REQUEST) { - ap->flags &= ~IPV6_AF_ADDED; - } else { - TAILQ_REMOVE(addrs, ap, next); - ipv6_freeaddr(ap); - } - } else if (!(ap->flags & IPV6_AF_STALE) && - !IN6_IS_ADDR_UNSPECIFIED(&ap->addr)) - { - if (ap->flags & IPV6_AF_NEW) - i++; - if (!timespecisset(&now)) - clock_gettime(CLOCK_MONOTONIC, &now); - ipv6_addaddr(ap, &now); + TAILQ_FOREACH_SAFE(ia, iaddrs, next, ian) { + r = ipv6_doaddr(ia, &now); + if (r != 0) + i++; + if (r == -1) { + TAILQ_REMOVE(iaddrs, ia, next); + ipv6_freeaddr(ia); } } - return i; } @@ -1544,6 +1555,10 @@ ipv6_newaddr(struct interface *ifp, cons ia->prefix_len = prefix_len; ia->dhcp6_fd = -1; +#ifndef SMALL + TAILQ_INIT(&ia->pd_pfxs); +#endif + #ifdef IPV6_AF_TEMPORARY tempaddr = ia->flags & IPV6_AF_TEMPORARY; #else Index: src/external/bsd/dhcpcd/dist/src/ipv6.h diff -u src/external/bsd/dhcpcd/dist/src/ipv6.h:1.6 src/external/bsd/dhcpcd/dist/src/ipv6.h:1.7 --- src/external/bsd/dhcpcd/dist/src/ipv6.h:1.6 Fri Sep 13 11:01:50 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6.h Fri Dec 20 12:01:35 2019 @@ -262,6 +262,7 @@ void ipv6_checkaddrflags(void *); void ipv6_markaddrsstale(struct interface *, unsigned int); void ipv6_deletestaleaddrs(struct interface *); int ipv6_addaddr(struct ipv6_addr *, const struct timespec *); +int ipv6_doaddr(struct ipv6_addr *, struct timespec *); ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs); void ipv6_deleteaddr(struct ipv6_addr *); void ipv6_freedrop_addrs(struct ipv6_addrhead *, int, Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.13 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.14 --- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.13 Wed Nov 13 10:50:22 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c Fri Dec 20 12:01:36 2019 @@ -652,7 +652,7 @@ ipv6nd_neighbour(struct dhcpcd_ctx *ctx, break; } - if (rap == NULL || rap->expired || rap->reachable == reachable) + if (rap == NULL || rap->expired || rap->isreachable == reachable) return; rap->isreachable = reachable;