it if we just maintain the status quo.
if (state->probes == 0) {
if (arping)
- syslog(LOG_INFO, "%s: searching for %s",
+ syslog(LOG_DEBUG, "%s: searching for %s",
ifp->name, inet_ntoa(addr));
else
- syslog(LOG_INFO, "%s: checking for %s",
+ syslog(LOG_DEBUG, "%s: checking for %s",
ifp->name, inet_ntoa(addr));
}
if (++state->probes < PROBE_NUM) {
struct dhcp_state *state = D_STATE(ifp);
struct dhcp_lease *lease = &state->lease;
- syslog(LOG_INFO, "%s: renewing lease of %s",
+ syslog(LOG_DEBUG, "%s: renewing lease of %s",
ifp->name, inet_ntoa(lease->addr));
syslog(LOG_DEBUG, "%s: rebind in %u seconds, expire in %u seconds",
ifp->name, lease->rebindtime - lease->renewaltime,
struct dhcp_state *state = D_STATE(ifp);
struct dhcp_lease *lease = &state->lease;
- syslog(LOG_ERR, "%s: failed to renew, attempting to rebind",
+ syslog(LOG_WARNING, "%s: failed to renew, attempting to rebind",
ifp->name);
syslog(LOG_DEBUG, "%s: expire in %u seconds",
ifp->name, lease->leasetime - lease->rebindtime);
lease->rebindtime = lease->leasetime * T2;
else if (lease->rebindtime >= lease->leasetime) {
lease->rebindtime = lease->leasetime * T2;
- syslog(LOG_ERR,
+ syslog(LOG_WARNING,
"%s: rebind time greater than lease "
"time, forcing to %u seconds",
iface->name, lease->rebindtime);
lease->renewaltime = lease->leasetime * T1;
else if (lease->renewaltime > lease->rebindtime) {
lease->renewaltime = lease->leasetime * T1;
- syslog(LOG_ERR,
+ syslog(LOG_WARNING,
"%s: renewal time greater than rebind "
"time, forcing to %u seconds",
iface->name, lease->renewaltime);
}
- syslog(LOG_INFO,
+ syslog(lease->addr.s_addr == state->addr.s_addr ?
+ LOG_DEBUG : LOG_INFO,
"%s: leased %s for %u seconds", iface->name,
inet_ntoa(lease->addr), lease->leasetime);
}
if (type) {
if (type == DHCP_OFFER) {
- log_dhcp(LOG_INFO, "ignoring offer of",
+ log_dhcp(LOG_WARNING, "ignoring offer of",
iface, dhcp, from);
return;
}
}
if (!(ifo->options & DHCPCD_INFORM))
- log_dhcp(LOG_INFO, "acknowledged", iface, dhcp, from);
+ log_dhcp(LOG_DEBUG, "acknowledged", iface, dhcp, from);
}
/* BOOTP could have already assigned this above, so check we still
static ssize_t
get_udp_data(const uint8_t **data, const uint8_t *udp)
{
- struct udp_dhcp_packet p;
+ struct udp_dhcp_packet p;
- memcpy(&p, udp, sizeof(p));
- *data = udp + offsetof(struct udp_dhcp_packet, dhcp);
- return ntohs(p.ip.ip_len) - sizeof(p.ip) - sizeof(p.udp);
+ memcpy(&p, udp, sizeof(p));
+ *data = udp + offsetof(struct udp_dhcp_packet, dhcp);
+ return ntohs(p.ip.ip_len) - sizeof(p.ip) - sizeof(p.udp);
}
static int
return NULL;
}
-
static void
dhcp6_freedrop_addrs(struct interface *ifp, int drop)
{
ifp = arg;
eloop_timeout_delete(dhcp6_sendrenew, ifp);
state = D6_STATE(ifp);
+ if (state->state == DH6S_RENEW)
+ syslog(LOG_WARNING, "%s: failed to renew, rebinding",
+ ifp->name);
state->state = DH6S_REBIND;
state->RTC = 0;
state->MRC = 0;
ifp = arg;
state = D6_STATE(ifp);
+ if (state->state == DH6S_REBIND)
+ syslog(LOG_ERR, "%s: failed to renew, soliciting",
+ ifp->name);
state->state = DH6S_DISCOVER;
state->start_uptime = uptime();
state->RTC = 0;
return ntohs(s->status);
}
-int
-dhcp6_addrexists(const struct ipv6_addr *a)
+static struct ipv6_addr *
+dhcp6_findaddr(const struct in6_addr *a, struct interface *ifp)
{
- const struct interface *ifp;
const struct dhcp6_state *state;
- const struct ipv6_addr *ap;
+ struct ipv6_addr *ap;
- TAILQ_FOREACH(ifp, ifaces, next) {
- state = D6_CSTATE(ifp);
- if (state == NULL)
- continue;
+ state = D6_CSTATE(ifp);
+ if (state) {
TAILQ_FOREACH(ap, &state->addrs, next) {
- if (memcmp(&ap->addr, &a->addr, sizeof(a->addr)) == 0)
- return 1;
+ if (IN6_ARE_ADDR_EQUAL(&ap->addr, a))
+ return ap;
}
}
+ return NULL;
+}
+
+int
+dhcp6_addrexists(const struct ipv6_addr *a)
+{
+ struct interface *ifp;
+
+ TAILQ_FOREACH(ifp, ifaces, next) {
+ if (dhcp6_findaddr(&a->addr, ifp))
+ return 1;
+ }
return 0;
}
}
}
if (!wascompleted) {
- syslog(LOG_INFO, "%s: DHCPv6 DAD completed",
+ syslog(LOG_DEBUG, "%s: DHCPv6 DAD completed",
ifp->name);
script_runreason(ifp, state->reason);
daemonise();
struct dhcp6_state *state;
const struct dhcp6_option *o;
const uint8_t *p;
+ struct in6_addr in6;
struct ipv6_addr *a;
const struct ipv6_addr *pa;
char iabuf[INET6_ADDRSTRLEN];
ifp->name);
continue;
}
- a = calloc(1, sizeof(*a));
+ p = D6_COPTION_DATA(o);
+ memcpy(&in6.s6_addr, p, sizeof(in6.s6_addr));
+ p += sizeof(in6.s6_addr);
+ a = dhcp6_findaddr(&in6, ifp);
if (a == NULL) {
- syslog(LOG_ERR, "%s: %m", __func__);
- break;
+ a = calloc(1, sizeof(*a));
+ if (a == NULL) {
+ syslog(LOG_ERR, "%s: %m", __func__);
+ break;
+ }
+ a->iface = ifp;
+ a->new = 1;
+ a->onlink = 1; /* XXX: suprised no DHCP opt for this */
+ a->dadcallback = dhcp6_dadcallback;
+ memcpy(a->iaid, iaid, sizeof(a->iaid));
+ memcpy(&a->addr.s6_addr, &in6.s6_addr,
+ sizeof(in6.s6_addr));
}
- a->iface = ifp;
- a->new = 1;
- a->onlink = 1; /* XXX: suprised no DHCP opt for this */
- a->dadcallback = dhcp6_dadcallback;
- memcpy(a->iaid, iaid, sizeof(a->iaid));
- p = D6_COPTION_DATA(o);
- memcpy(&a->addr.s6_addr, p,
- sizeof(a->addr.s6_addr));
- p += sizeof(a->addr.s6_addr);
pa = ipv6rs_findprefix(a);
if (pa) {
memcpy(&a->prefix, &pa->prefix,
iabuf, sizeof(iabuf));
snprintf(a->saddr, sizeof(a->saddr),
"%s/%d", ia, a->prefix_len);
- TAILQ_INSERT_TAIL(&state->addrs, a, next);
+ if (a->stale)
+ a->stale = 0;
+ else
+ TAILQ_INSERT_TAIL(&state->addrs, a, next);
i++;
}
return i;
uint32_t u32, renew, rebind;
uint8_t iaid[4];
size_t ol;
+ struct ipv6_addr *ap, *nap;
ifo = ifp->options;
i = 0;
- dhcp6_freedrop_addrs(ifp, 0);
state = D6_STATE(ifp);
while ((o = dhcp6_findoption(ifo->ia_type, d, l))) {
l -= ((const uint8_t *)o - d);
return -1;
}
if (ifo->ia_type == D6_OPTION_IA_PD) {
+ dhcp6_freedrop_addrs(ifp, 0);
if (dhcp6_findpd(ifp, iaid, p, ol) == 0) {
syslog(LOG_ERR,
"%s: %s: DHCPv6 REPLY missing Prefix",
return -1;
}
} else {
+ TAILQ_FOREACH(ap, &state->addrs, next) {
+ ap->stale = 1;
+ }
if (dhcp6_findna(ifp, iaid, p, ol) == 0) {
syslog(LOG_ERR,
"%s: %s: DHCPv6 REPLY missing IA Address",
ifp->name, sfrom);
return -1;
}
+ TAILQ_FOREACH_SAFE(ap, &state->addrs, next, nap) {
+ if (ap->stale) {
+ TAILQ_REMOVE(&state->addrs, ap, next);
+ if (ap->dadcallback)
+ eloop_q_timeout_delete(0, NULL,
+ ap->dadcallback);
+ free(ap);
+ }
+ }
}
i++;
}
/* Remove any exiting address */
TAILQ_FOREACH(ap, &state->addrs, next) {
- if (memcmp(&ap->addr, &a->addr, sizeof(ap->addr)) == 0) {
+ if (IN6_ARE_ADDR_EQUAL(&ap->addr, &a->addr)) {
TAILQ_REMOVE(&state->addrs, ap, next);
free(ap);
break;
const struct dhcp_opt *opt;
const struct if_options *ifo;
const struct ipv6_addr *ap;
+ uint8_t stale;
len = recvmsg(sock, &rcvhdr, 0);
if (len == -1) {
}
recv:
- syslog(LOG_INFO, "%s: %s received from %s", ifp->name, op, sfrom);
+ stale = 1;
+ TAILQ_FOREACH(ap, &state->addrs, next) {
+ if (ap->new) {
+ stale = 0;
+ break;
+ }
+ }
+ syslog(stale ? LOG_DEBUG : LOG_INFO,
+ "%s: %s received from %s", ifp->name, op, sfrom);
state->reason = NULL;
eloop_timeout_delete(NULL, ifp);
dhcp6_delegate_prefix(ifp);
ipv6ns_probeaddrs(&state->addrs);
if (state->renew || state->rebind)
- syslog(LOG_INFO,
+ syslog(stale ? LOG_DEBUG : LOG_INFO,
"%s: renew in %u seconds, rebind in %u seconds",
ifp->name, state->renew, state->rebind);
ipv6_buildroutes();
script_runreason(ifp, state->reason);
daemonise();
} else
- syslog(LOG_INFO, "%s: waiting for DHCPv6 DAD"
- " to complete",
+ syslog(LOG_DEBUG,
+ "%s: waiting for DHCPv6 DAD to complete",
ifp->name);
}
return 0;
syslog(LOG_INFO, "%s: %s", ifp->name,
- manage ? "soliciting DHCPv6 address" :
+ manage ? "soliciting a DHCPv6 address" :
"requesting DHCPv6 information");
state->state = manage ? DH6S_INIT : DH6S_INFORM;
strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr));
if (rt->gate.s_addr == INADDR_ANY)
- syslog(LOG_DEBUG, "%s: %s route to %s/%d", ifname, cmd,
+ syslog(LOG_INFO, "%s: %s route to %s/%d", ifname, cmd,
addr, inet_ntocidr(rt->net));
else if (rt->gate.s_addr == rt->dest.s_addr &&
rt->net.s_addr == INADDR_BROADCAST)
- syslog(LOG_DEBUG, "%s: %s host route to %s", ifname, cmd,
+ syslog(LOG_INFO, "%s: %s host route to %s", ifname, cmd,
addr);
else if (rt->dest.s_addr == INADDR_ANY && rt->net.s_addr == INADDR_ANY)
- syslog(LOG_DEBUG, "%s: %s default route via %s", ifname, cmd,
+ syslog(LOG_INFO, "%s: %s default route via %s", ifname, cmd,
inet_ntoa(rt->gate));
else
- syslog(LOG_DEBUG, "%s: %s route to %s/%d via %s", ifname, cmd,
+ syslog(LOG_INFO, "%s: %s route to %s/%d via %s", ifname, cmd,
addr, inet_ntocidr(rt->net), inet_ntoa(rt->gate));
}
d6_state->state == DH6S_DELEGATED))
{
TAILQ_FOREACH(addr, &d6_state->addrs, next) {
- if (!addr->onlink)
+ if (!addr->onlink ||
+ IN6_IS_ADDR_UNSPECIFIED(&addr->addr))
continue;
rt = make_prefix(ifp, NULL, addr);
if (rt)
struct in6_addr addr;
uint8_t onlink;
uint8_t new;
+ uint8_t stale;
char saddr[INET6_ADDRSTRLEN];
uint8_t added;
uint8_t autoconf;
IN6_IS_ADDR_UNSPECIFIED(&ap->addr))
continue;
ipv6ns_probeaddr(ap);
- i++;
+ if (ap->new)
+ i++;
}
return i;
cm->cmsg_len = CMSG_LEN(sizeof(hoplimit));
memcpy(CMSG_DATA(cm), &hoplimit, sizeof(hoplimit));
- syslog(LOG_INFO, "%s: sending Router Solicitation", ifp->name);
+ syslog(LOG_DEBUG, "%s: sending Router Solicitation", ifp->name);
if (sendmsg(sock, &sndhdr, 0) == -1) {
syslog(LOG_ERR, "%s: sendmsg: %m", ifp->name);
ipv6rs_drop(ifp);
eloop_timeout_add_sec(RTR_SOLICITATION_INTERVAL,
ipv6rs_sendprobe, ifp);
else
- syslog(LOG_INFO, "%s: no IPv6 Routers available", ifp->name);
+ syslog(LOG_WARNING, "%s: no IPv6 Routers available", ifp->name);
}
static void
/* If all addresses have completed DAD run the script */
TAILQ_FOREACH(ap, &rap->addrs, next) {
if (ap->dadcompleted == 0) {
- syslog(LOG_INFO, "%s: waiting for Router Advertisement"
+ syslog(LOG_DEBUG,
+ "%s: waiting for Router Advertisement"
" DAD to complete",
rap->iface->name);
return;
}
if (wascompleted && found && rap->lifetime) {
- syslog(LOG_INFO,
+ syslog(LOG_DEBUG,
"%s: Router Advertisement DAD completed",
rap->iface->name);
ipv6rs_scriptrun(rap);
if (timercmp(&now, &expire, >)) {
valid = 0;
if (!rap->expired) {
- syslog(LOG_INFO,
+ syslog(LOG_WARNING,
"%s: %s: expired default Router",
ifp->name, rap->sfrom);
rap->expired = expired = 1;
if (timercmp(&now, &expire, >) &&
ipv6rs_findsameaddr(ap) == NULL)
{
- syslog(LOG_INFO,
+ syslog(LOG_WARNING,
"%s: %s: expired address",
ifp->name, ap->saddr);
eloop_timeout_delete(NULL, ap);
if (timercmp(&now, &rao->expire, >)) {
/* Expired prefixes are logged above */
if (rao->type != ND_OPT_PREFIX_INFORMATION)
- syslog(LOG_INFO,
+ syslog(LOG_WARNING,
"%s: %s: expired option %d",
ifp->name, rap->sfrom, rao->type);
TAILQ_REMOVE(&rap->options, rao, next);
{
struct rs_state *state;
+ syslog(LOG_INFO, "%s: soliciting an IPv6 Router", ifp->name);
if (sock == -1) {
if (ipv6rs_open() == -1) {
syslog(LOG_ERR, "%s: ipv6rs_open: %m", __func__);