This commit is contained in:
roy 2020-04-21 09:55:33 +00:00
parent 4f06a81613
commit 5e47f81657
7 changed files with 95 additions and 135 deletions

View File

@ -3494,8 +3494,9 @@ dhcp_packet(struct interface *ifp, uint8_t *data, size_t len)
__func__, ifp->name); __func__, ifp->name);
return; return;
} }
data += fl;
len -= fl; len -= fl;
/* Move the data to avoid alignment errors. */
memmove(data, data + fl, len);
} }
/* Validate filter. */ /* Validate filter. */
@ -3608,15 +3609,18 @@ dhcp_readudp(struct dhcpcd_ctx *ctx, struct interface *ifp)
.iov_base = buf, .iov_base = buf,
.iov_len = sizeof(buf), .iov_len = sizeof(buf),
}; };
union {
struct cmsghdr hdr;
#ifdef IP_RECVIF #ifdef IP_RECVIF
unsigned char ctl[CMSG_SPACE(sizeof(struct sockaddr_dl))] = { 0 }; uint8_t buf[CMSG_SPACE(sizeof(struct sockaddr_dl))];
#else #else
unsigned char ctl[CMSG_SPACE(sizeof(struct in_pktinfo))] = { 0 }; uint8_t buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
#endif #endif
} cmsgbuf = { .buf = { 0 } };
struct msghdr msg = { struct msghdr msg = {
.msg_name = &from, .msg_namelen = sizeof(from), .msg_name = &from, .msg_namelen = sizeof(from),
.msg_iov = &iov, .msg_iovlen = 1, .msg_iov = &iov, .msg_iovlen = 1,
.msg_control = ctl, .msg_controllen = sizeof(ctl), .msg_control = buf, .msg_controllen = sizeof(cmsgbuf.buf),
}; };
int s; int s;
ssize_t bytes; ssize_t bytes;

View File

@ -1585,6 +1585,7 @@ dhcp6_startdiscover(void *arg)
{ {
struct interface *ifp; struct interface *ifp;
struct dhcp6_state *state; struct dhcp6_state *state;
int llevel;
ifp = arg; ifp = arg;
state = D6_STATE(ifp); state = D6_STATE(ifp);
@ -1592,7 +1593,11 @@ dhcp6_startdiscover(void *arg)
if (state->reason == NULL || strcmp(state->reason, "TIMEOUT6") != 0) if (state->reason == NULL || strcmp(state->reason, "TIMEOUT6") != 0)
dhcp6_delete_delegates(ifp); dhcp6_delete_delegates(ifp);
#endif #endif
loginfox("%s: soliciting a DHCPv6 lease", ifp->name); if (state->new == NULL && !state->failed)
llevel = LOG_INFO;
else
llevel = LOG_DEBUG;
logmessage(llevel, "%s: soliciting a DHCPv6 lease", ifp->name);
state->state = DH6S_DISCOVER; state->state = DH6S_DISCOVER;
state->RTC = 0; state->RTC = 0;
state->IMD = SOL_MAX_DELAY; state->IMD = SOL_MAX_DELAY;
@ -1616,11 +1621,15 @@ dhcp6_startinform(void *arg)
{ {
struct interface *ifp; struct interface *ifp;
struct dhcp6_state *state; struct dhcp6_state *state;
int llevel;
ifp = arg; ifp = arg;
state = D6_STATE(ifp); state = D6_STATE(ifp);
if (state->new == NULL || ifp->options->options & DHCPCD_DEBUG) if (state->new == NULL && !state->failed)
loginfox("%s: requesting DHCPv6 information", ifp->name); llevel = LOG_INFO;
else
llevel = LOG_DEBUG;
logmessage(llevel, "%s: requesting DHCPv6 information", ifp->name);
state->state = DH6S_INFORM; state->state = DH6S_INFORM;
state->RTC = 0; state->RTC = 0;
state->IMD = INF_MAX_DELAY; state->IMD = INF_MAX_DELAY;
@ -1677,6 +1686,8 @@ dhcp6_fail(struct interface* ifp)
{ {
struct dhcp6_state *state = D6_STATE(ifp); struct dhcp6_state *state = D6_STATE(ifp);
state->failed = true;
/* RFC3315 18.1.2 says that prior addresses SHOULD be used on failure. /* RFC3315 18.1.2 says that prior addresses SHOULD be used on failure.
* RFC2131 3.2.3 says that MAY chose to use the prior address. * RFC2131 3.2.3 says that MAY chose to use the prior address.
* Because dhcpcd was written first for RFC2131, we have the LASTLEASE * Because dhcpcd was written first for RFC2131, we have the LASTLEASE
@ -1711,33 +1722,43 @@ dhcp6_fail(struct interface* ifp)
} }
} }
static int
dhcp6_failloglevel(struct interface *ifp)
{
const struct dhcp6_state *state = D6_CSTATE(ifp);
return state->failed ? LOG_DEBUG : LOG_ERR;
}
static void static void
dhcp6_failconfirm(void *arg) dhcp6_failconfirm(void *arg)
{ {
struct interface *ifp; struct interface *ifp = arg;
int llevel = dhcp6_failloglevel(ifp);
ifp = arg; logmessage(llevel, "%s: failed to confirm prior DHCPv6 address",
logerrx("%s: failed to confirm prior address", ifp->name); ifp->name);
dhcp6_fail(ifp); dhcp6_fail(ifp);
} }
static void static void
dhcp6_failrequest(void *arg) dhcp6_failrequest(void *arg)
{ {
struct interface *ifp; struct interface *ifp = arg;
int llevel = dhcp6_failloglevel(ifp);
ifp = arg; logmessage(llevel, "%s: failed to request DHCPv6 address", ifp->name);
logerrx("%s: failed to request address", ifp->name);
dhcp6_fail(ifp); dhcp6_fail(ifp);
} }
static void static void
dhcp6_failinform(void *arg) dhcp6_failinform(void *arg)
{ {
struct interface *ifp; struct interface *ifp = arg;
int llevel = dhcp6_failloglevel(ifp);
ifp = arg; logmessage(llevel, "%s: failed to request DHCPv6 information",
logerrx("%s: failed to request information", ifp->name); ifp->name);
dhcp6_fail(ifp); dhcp6_fail(ifp);
} }
@ -1745,10 +1766,9 @@ dhcp6_failinform(void *arg)
static void static void
dhcp6_failrebind(void *arg) dhcp6_failrebind(void *arg)
{ {
struct interface *ifp; struct interface *ifp = arg;
ifp = arg; logerrx("%s: failed to rebind prior DHCPv6 delegation", ifp->name);
logerrx("%s: failed to rebind prior delegation", ifp->name);
dhcp6_fail(ifp); dhcp6_fail(ifp);
} }
@ -3124,6 +3144,7 @@ dhcp6_bind(struct interface *ifp, const char *op, const char *sfrom)
state->state = DH6S_INFORMED; state->state = DH6S_INFORMED;
else else
state->state = DH6S_BOUND; state->state = DH6S_BOUND;
state->failed = false;
if (state->renew && state->renew != ND6_INFINITE_LIFETIME) if (state->renew && state->renew != ND6_INFINITE_LIFETIME)
eloop_timeout_add_sec(ifp->ctx->eloop, eloop_timeout_add_sec(ifp->ctx->eloop,
@ -3621,11 +3642,14 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
.iov_base = buf, .iov_base = buf,
.iov_len = sizeof(buf), .iov_len = sizeof(buf),
}; };
unsigned char ctl[CMSG_SPACE(sizeof(struct in6_pktinfo))] = { 0 }; union {
struct cmsghdr hdr;
uint8_t buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
} cmsgbuf = { .buf = { 0 } };
struct msghdr msg = { struct msghdr msg = {
.msg_name = &from, .msg_namelen = sizeof(from), .msg_name = &from, .msg_namelen = sizeof(from),
.msg_iov = &iov, .msg_iovlen = 1, .msg_iov = &iov, .msg_iovlen = 1,
.msg_control = ctl, .msg_controllen = sizeof(ctl), .msg_control = cmsgbuf.buf, .msg_controllen = sizeof(cmsgbuf.buf),
}; };
int s; int s;
ssize_t bytes; ssize_t bytes;
@ -3857,6 +3881,7 @@ dhcp6_start(struct interface *ifp, enum DH6S init_state)
gogogo: gogogo:
state->state = init_state; state->state = init_state;
state->lerror = 0; state->lerror = 0;
state->failed = false;
dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile), dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
AF_INET6, ifp); AF_INET6, ifp);
if (ipv6_linklocal(ifp) == NULL) { if (ipv6_linklocal(ifp) == NULL) {

View File

@ -2274,6 +2274,7 @@ printpidfile:
loglevel = ctx.options & DHCPCD_INACTIVE ? loglevel = ctx.options & DHCPCD_INACTIVE ?
LOG_DEBUG : LOG_ERR; LOG_DEBUG : LOG_ERR;
logmessage(loglevel, "no valid interfaces found"); logmessage(loglevel, "no valid interfaces found");
dhcpcd_daemonise(&ctx);
} else } else
goto exit_failure; goto exit_failure;
if (!(ctx.options & DHCPCD_LINK)) { if (!(ctx.options & DHCPCD_LINK)) {

View File

@ -1015,28 +1015,21 @@ if_ioctl6(struct dhcpcd_ctx *ctx, unsigned long req, void *data, size_t len)
int int
if_address6(unsigned char cmd, const struct ipv6_addr *ia) if_address6(unsigned char cmd, const struct ipv6_addr *ia)
{ {
struct in6_aliasreq ifa; struct in6_aliasreq ifa = { .ifra_flags = 0 };
struct in6_addr mask; struct in6_addr mask;
struct dhcpcd_ctx *ctx = ia->iface->ctx; struct dhcpcd_ctx *ctx = ia->iface->ctx;
memset(&ifa, 0, sizeof(ifa));
strlcpy(ifa.ifra_name, ia->iface->name, sizeof(ifa.ifra_name)); strlcpy(ifa.ifra_name, ia->iface->name, sizeof(ifa.ifra_name));
/*
* We should not set IN6_IFF_TENTATIVE as the kernel should be
* able to work out if it's a new address or not.
*
* We should set IN6_IFF_AUTOCONF, but the kernel won't let us.
* This is probably a safety measure, but still it's not entirely right
* either.
*/
#if 0
if (ia->autoconf)
ifa.ifra_flags |= IN6_IFF_AUTOCONF;
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) || defined(__DragonFly__)
/* This is a bug - the kernel should work this out. */
if (ia->addr_flags & IN6_IFF_TENTATIVE) if (ia->addr_flags & IN6_IFF_TENTATIVE)
ifa.ifra_flags |= IN6_IFF_TENTATIVE; ifa.ifra_flags |= IN6_IFF_TENTATIVE;
#endif #endif
// #if (defined(__NetBSD__) && __NetBSD_Version__ >= 999005700) ||
#if (defined(__OpenBSD__) && OpenBSD >= 201605)
if (ia->flags & IPV6_AF_AUTOCONF)
ifa.ifra_flags |= IN6_IFF_AUTOCONF;
#endif
#ifdef IPV6_MANAGETEMPADDR #ifdef IPV6_MANAGETEMPADDR
if (ia->flags & IPV6_AF_TEMPORARY) if (ia->flags & IPV6_AF_TEMPORARY)
ifa.ifra_flags |= IN6_IFF_TEMPORARY; ifa.ifra_flags |= IN6_IFF_TEMPORARY;
@ -1626,7 +1619,6 @@ if_machinearch(char *str, size_t len)
#ifdef INET6 #ifdef INET6
#if (defined(IPV6CTL_ACCEPT_RTADV) && !defined(ND6_IFF_ACCEPT_RTADV)) || \ #if (defined(IPV6CTL_ACCEPT_RTADV) && !defined(ND6_IFF_ACCEPT_RTADV)) || \
defined(IPV6CTL_USETEMPADDR) || defined(IPV6CTL_TEMPVLTIME) || \
defined(IPV6CTL_FORWARDING) defined(IPV6CTL_FORWARDING)
#define get_inet6_sysctl(code) inet6_sysctl(code, 0, 0) #define get_inet6_sysctl(code) inet6_sysctl(code, 0, 0)
#define set_inet6_sysctl(code, val) inet6_sysctl(code, val, 1) #define set_inet6_sysctl(code, val) inet6_sysctl(code, val, 1)
@ -1687,8 +1679,7 @@ if_applyra(const struct ra *rap)
#endif #endif
} }
#ifdef IPV6_MANAGETEMPADDR #ifndef IPV6CTL_FORWARDING
#if !defined(IPV6CTL_TEMPVLTIME) && !defined(__OpenBSD__)
#define get_inet6_sysctlbyname(code) inet6_sysctlbyname(code, 0, 0) #define get_inet6_sysctlbyname(code) inet6_sysctlbyname(code, 0, 0)
#define set_inet6_sysctlbyname(code, val) inet6_sysctlbyname(code, val, 1) #define set_inet6_sysctlbyname(code, val) inet6_sysctlbyname(code, val, 1)
static int static int
@ -1708,81 +1699,6 @@ inet6_sysctlbyname(const char *name, int val, int action)
} }
#endif #endif
#ifdef __OpenBSD__
int
ip6_use_tempaddr(const char *ifname)
{
int s, r;
struct ifreq ifr;
s = socket(PF_INET6, SOCK_DGRAM, 0); /* XXX Not efficient */
if (s == -1)
return -1;
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
r = ioctl(s, SIOCGIFXFLAGS, &ifr);
close(s);
if (r == -1)
return -1;
return ifr.ifr_flags & IFXF_INET6_NOPRIVACY ? 0 : 1;
}
int
ip6_temp_preferred_lifetime(__unused const char *ifname)
{
return TEMP_PREFERRED_LIFETIME;
}
int
ip6_temp_valid_lifetime(__unused const char *ifname)
{
return TEMP_VALID_LIFETIME;
}
#else /* __OpenBSD__ */
int
ip6_use_tempaddr(__unused const char *ifname)
{
int val;
#ifdef IPV6CTL_USETEMPADDR
val = get_inet6_sysctl(IPV6CTL_USETEMPADDR);
#else
val = get_inet6_sysctlbyname("net.inet6.ip6.use_tempaddr");
#endif
return val == -1 ? 0 : val;
}
int
ip6_temp_preferred_lifetime(__unused const char *ifname)
{
int val;
#ifdef IPV6CTL_TEMPPLTIME
val = get_inet6_sysctl(IPV6CTL_TEMPPLTIME);
#else
val = get_inet6_sysctlbyname("net.inet6.ip6.temppltime");
#endif
return val < 0 ? TEMP_PREFERRED_LIFETIME : val;
}
int
ip6_temp_valid_lifetime(__unused const char *ifname)
{
int val;
#ifdef IPV6CTL_TEMPVLTIME
val = get_inet6_sysctl(IPV6CTL_TEMPVLTIME);
#else
val = get_inet6_sysctlbyname("net.inet6.ip6.tempvltime");
#endif
return val < 0 ? TEMP_VALID_LIFETIME : val;
}
#endif /* !__OpenBSD__ */
#endif
int int
ip6_forwarding(__unused const char *ifname) ip6_forwarding(__unused const char *ifname)
{ {
@ -1946,7 +1862,7 @@ if_setup_inet6(const struct interface *ifp)
logerr("%s: set_ifxflags", ifp->name); logerr("%s: set_ifxflags", ifp->name);
#endif #endif
#if defined(IPV6CTL_ACCEPT_RTADV) || defined(ND6_IFF_ACCEPT_RTADV) #ifdef SIOCSRTRFLUSH_IN6
/* Flush the kernel knowledge of advertised routers /* Flush the kernel knowledge of advertised routers
* and prefixes so the kernel does not expire prefixes * and prefixes so the kernel does not expire prefixes
* and default routes we are trying to own. */ * and default routes we are trying to own. */
@ -1957,12 +1873,14 @@ if_setup_inet6(const struct interface *ifp)
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
if (if_ioctl6(ifp->ctx, SIOCSRTRFLUSH_IN6, if (if_ioctl6(ifp->ctx, SIOCSRTRFLUSH_IN6,
&ifr, sizeof(ifr)) == -1 && &ifr, sizeof(ifr)) == -1 &&
errno != ENOTSUP) errno != ENOTSUP && errno != ENOTTY)
logwarn("SIOCSRTRFLUSH_IN6"); logwarn("SIOCSRTRFLUSH_IN6 %d", errno);
#ifdef SIOCSPFXFLUSH_IN6
if (if_ioctl6(ifp->ctx, SIOCSPFXFLUSH_IN6, if (if_ioctl6(ifp->ctx, SIOCSPFXFLUSH_IN6,
&ifr, sizeof(ifr)) == -1 && &ifr, sizeof(ifr)) == -1 &&
errno != ENOTSUP) errno != ENOTSUP && errno != ENOTTY)
logwarn("SIOCSPFXFLUSH_IN6"); logwarn("SIOCSPFXFLUSH_IN6");
#endif
} }
#endif #endif
} }

View File

@ -2193,12 +2193,20 @@ invalid_token:
break; break;
case O_SLAAC: case O_SLAAC:
ARG_REQUIRED; ARG_REQUIRED;
np = strwhite(arg);
if (np != NULL) {
*np++ = '\0';
np = strskipwhite(np);
}
if (strcmp(arg, "private") == 0 || if (strcmp(arg, "private") == 0 ||
strcmp(arg, "stableprivate") == 0 || strcmp(arg, "stableprivate") == 0 ||
strcmp(arg, "stable") == 0) strcmp(arg, "stable") == 0)
ifo->options |= DHCPCD_SLAACPRIVATE; ifo->options |= DHCPCD_SLAACPRIVATE;
else else
ifo->options &= ~DHCPCD_SLAACPRIVATE; ifo->options &= ~DHCPCD_SLAACPRIVATE;
if (np != NULL &&
(strcmp(np, "temp") == 0 || strcmp(np, "temporary") == 0))
ifo->options |= DHCPCD_SLAACTEMP;
break; break;
case O_BOOTP: case O_BOOTP:
ifo->options |= DHCPCD_BOOTP; ifo->options |= DHCPCD_BOOTP;

View File

@ -744,7 +744,7 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
if (ia->flags & IPV6_AF_TEMPORARY && if (ia->flags & IPV6_AF_TEMPORARY &&
ia->prefix_pltime && ia->prefix_pltime &&
ia->prefix_vltime && ia->prefix_vltime &&
ip6_use_tempaddr(ifp->name)) ifp->options->options & DHCPCD_SLAACTEMP)
eloop_timeout_add_sec(ifp->ctx->eloop, eloop_timeout_add_sec(ifp->ctx->eloop,
ia->prefix_pltime - REGEN_ADVANCE, ia->prefix_pltime - REGEN_ADVANCE,
ipv6_regentempaddr, ia); ipv6_regentempaddr, ia);
@ -1866,7 +1866,7 @@ static void
ipv6_regen_desync(struct interface *ifp, bool force) ipv6_regen_desync(struct interface *ifp, bool force)
{ {
struct ipv6_state *state; struct ipv6_state *state;
unsigned int max, pref; unsigned int max;
state = IPV6_STATE(ifp); state = IPV6_STATE(ifp);
@ -1874,14 +1874,13 @@ ipv6_regen_desync(struct interface *ifp, bool force)
* greater than TEMP_VALID_LIFETIME - REGEN_ADVANCE. * greater than TEMP_VALID_LIFETIME - REGEN_ADVANCE.
* I believe this is an error and it should be never be greater than * I believe this is an error and it should be never be greater than
* TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE. */ * TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE. */
pref = (unsigned int)ip6_temp_preferred_lifetime(ifp->name); max = TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE;
max = pref - REGEN_ADVANCE;
if (state->desync_factor && !force && state->desync_factor < max) if (state->desync_factor && !force && state->desync_factor < max)
return; return;
if (state->desync_factor == 0) if (state->desync_factor == 0)
state->desync_factor = state->desync_factor =
arc4random_uniform(MIN(MAX_DESYNC_FACTOR, max)); arc4random_uniform(MIN(MAX_DESYNC_FACTOR, max));
max = pref - state->desync_factor - REGEN_ADVANCE; max = TEMP_PREFERRED_LIFETIME - state->desync_factor - REGEN_ADVANCE;
eloop_timeout_add_sec(ifp->ctx->eloop, max, ipv6_regentempaddrs, ifp); eloop_timeout_add_sec(ifp->ctx->eloop, max, ipv6_regentempaddrs, ifp);
} }
@ -1917,7 +1916,6 @@ ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timespec *now)
struct ipv6_state *state; struct ipv6_state *state;
struct interface *ifp = ia0->iface; struct interface *ifp = ia0->iface;
struct ipv6_addr *ia; struct ipv6_addr *ia;
uint32_t i;
ia = ipv6_newaddr(ifp, &ia0->prefix, ia0->prefix_len, ia = ipv6_newaddr(ifp, &ia0->prefix, ia0->prefix_len,
IPV6_AF_AUTOCONF | IPV6_AF_TEMPORARY); IPV6_AF_AUTOCONF | IPV6_AF_TEMPORARY);
@ -1932,11 +1930,9 @@ ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timespec *now)
/* RFC4941 Section 3.3.4 */ /* RFC4941 Section 3.3.4 */
state = IPV6_STATE(ia->iface); state = IPV6_STATE(ia->iface);
i = (uint32_t)ip6_temp_preferred_lifetime(ifp->name) - ia->prefix_pltime = MIN(ia0->prefix_pltime,
state->desync_factor; TEMP_PREFERRED_LIFETIME - state->desync_factor);
ia->prefix_pltime = MIN(ia0->prefix_pltime, i); ia->prefix_vltime = MIN(ia0->prefix_vltime, TEMP_VALID_LIFETIME);
i = (uint32_t)ip6_temp_valid_lifetime(ifp->name);
ia->prefix_vltime = MIN(ia0->prefix_vltime, i);
if (ia->prefix_pltime <= REGEN_ADVANCE || if (ia->prefix_pltime <= REGEN_ADVANCE ||
ia->prefix_pltime > ia0->prefix_vltime) ia->prefix_pltime > ia0->prefix_vltime)
{ {
@ -1994,7 +1990,7 @@ ipv6_settemptime(struct ipv6_addr *ia, int flags)
ext = (unsigned int)ia->acquired.tv_sec ext = (unsigned int)ia->acquired.tv_sec
+ ia->prefix_pltime; + ia->prefix_pltime;
max = (unsigned int)(ap->created.tv_sec + max = (unsigned int)(ap->created.tv_sec +
ip6_temp_preferred_lifetime(ap->iface->name) - TEMP_PREFERRED_LIFETIME -
state->desync_factor); state->desync_factor);
if (ext < max) if (ext < max)
ap->prefix_pltime = ia->prefix_pltime; ap->prefix_pltime = ia->prefix_pltime;
@ -2006,7 +2002,7 @@ valid:
ext = (unsigned int)ia->acquired.tv_sec + ext = (unsigned int)ia->acquired.tv_sec +
ia->prefix_vltime; ia->prefix_vltime;
max = (unsigned int)(ap->created.tv_sec + max = (unsigned int)(ap->created.tv_sec +
ip6_temp_valid_lifetime(ap->iface->name)); TEMP_VALID_LIFETIME);
if (ext < max) if (ext < max)
ap->prefix_vltime = ia->prefix_vltime; ap->prefix_vltime = ia->prefix_vltime;
else else
@ -2073,10 +2069,13 @@ ipv6_regentempaddrs(void *arg)
struct ipv6_state *state; struct ipv6_state *state;
struct ipv6_addr *ia; struct ipv6_addr *ia;
state = IPV6_STATE(ifp);
if (state == NULL)
return;
ipv6_regen_desync(ifp, true); ipv6_regen_desync(ifp, true);
clock_gettime(CLOCK_MONOTONIC, &tv); clock_gettime(CLOCK_MONOTONIC, &tv);
state = IPV6_STATE(ifp);
TAILQ_FOREACH(ia, &state->addrs, next) { TAILQ_FOREACH(ia, &state->addrs, next) {
if (ia->flags & IPV6_AF_TEMPORARY && if (ia->flags & IPV6_AF_TEMPORARY &&
!(ia->flags & IPV6_AF_STALE)) !(ia->flags & IPV6_AF_STALE))

View File

@ -1169,7 +1169,8 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
* much needless log spam. */ * much needless log spam. */
if (rap->willexpire) if (rap->willexpire)
new_data = true; new_data = true;
loglevel = new_data || !rap->isreachable ? LOG_INFO : LOG_DEBUG, loglevel = new_rap || rap->willexpire || !rap->isreachable ?
LOG_INFO : LOG_DEBUG,
logmessage(loglevel, "%s: Router Advertisement from %s", logmessage(loglevel, "%s: Router Advertisement from %s",
ifp->name, rap->sfrom); ifp->name, rap->sfrom);
@ -1337,7 +1338,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
#ifdef IPV6_MANAGETEMPADDR #ifdef IPV6_MANAGETEMPADDR
/* RFC4941 Section 3.3.3 */ /* RFC4941 Section 3.3.3 */
if (ia->flags & IPV6_AF_AUTOCONF && if (ia->flags & IPV6_AF_AUTOCONF &&
ip6_use_tempaddr(ia->iface->name) && ia->iface->options->options & DHCPCD_SLAACTEMP &&
IA6_CANAUTOCONF(ia)) IA6_CANAUTOCONF(ia))
{ {
if (!new_ia) { if (!new_ia) {
@ -1908,11 +1909,15 @@ ipv6nd_handledata(void *arg)
.iov_base = buf, .iov_base = buf,
.iov_len = sizeof(buf), .iov_len = sizeof(buf),
}; };
unsigned char ctl[CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int))] = { 0 }; union {
struct cmsghdr hdr;
uint8_t buf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int))];
} cmsgbuf = { .buf = { 0 } };
struct msghdr msg = { struct msghdr msg = {
.msg_name = &from, .msg_namelen = sizeof(from), .msg_name = &from, .msg_namelen = sizeof(from),
.msg_iov = &iov, .msg_iovlen = 1, .msg_iov = &iov, .msg_iovlen = 1,
.msg_control = ctl, .msg_controllen = sizeof(ctl), .msg_control = cmsgbuf.buf, .msg_controllen = sizeof(cmsgbuf.buf),
}; };
ssize_t len; ssize_t len;