dhcp6_sendrenew(ifp);
}
+int
+dhcp6_dadcompleted(const struct interface *ifp)
+{
+ const struct dhcp6_state *state;
+ const struct ipv6_addr *ap;
+
+ state = D6_CSTATE(ifp);
+ TAILQ_FOREACH(ap, &state->addrs, next) {
+ if (ap->flags & IPV6_AF_ADDED &&
+ !(ap->flags & IPV6_AF_DADCOMPLETED))
+ return 0;
+ }
+ return 1;
+}
+
static void
dhcp6_dadcallback(void *arg)
{
#define D6_CSTATE(ifp) \
((const struct dhcp6_state *)(ifp)->if_data[IF_DATA_DHCP6])
#define D6_STATE_RUNNING(ifp) \
- (D6_CSTATE((ifp)) && D6_CSTATE((ifp))->new && D6_CSTATE((ifp))->reason)
+ (D6_CSTATE((ifp)) && D6_CSTATE((ifp))->new && \
+ D6_CSTATE((ifp))->reason && dhcp6_dadcompleted((ifp)))
#define D6_FIRST_OPTION(m) \
((struct dhcp6_option *) \
void dhcp6_free(struct interface *);
void dhcp6_handleifa(struct dhcpcd_ctx *, int, const char *,
const struct in6_addr *addr, int);
+int dhcp6_dadcompleted(const struct interface *);
void dhcp6_drop(struct interface *, const char *);
int dhcp6_dump(struct interface *);
#else
len++;
if (D_STATE_RUNNING(ifp))
len++;
- if (D6_STATE_RUNNING(ifp))
+ if (RS_STATE_RUNNING(ifp))
len++;
- if (ipv6nd_hasra(ifp))
+ if (D6_STATE_RUNNING(ifp))
len++;
}
if (write(fd->fd, &len, sizeof(len)) != sizeof(len))
ipv6_addaddr(ap);
}
+int
+ipv6nd_dadcompleted(const struct interface *ifp)
+{
+ const struct ra *rap;
+ const struct ipv6_addr *ap;
+
+ TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
+ if (rap->iface != ifp)
+ continue;
+ TAILQ_FOREACH(ap, &rap->addrs, next) {
+ if (ap->flags & IPV6_AF_AUTOCONF &&
+ !(ap->flags & IPV6_AF_DADCOMPLETED))
+ return 0;
+ }
+ }
+ return 1;
+}
+
static void
ipv6nd_dadcallback(void *arg)
{
};
#define RS_STATE(a) ((struct rs_state *)(ifp)->if_data[IF_DATA_IPV6ND])
+#define RS_STATE_RUNNING(a) (ipv6nd_hasra((a)) && ipv6nd_dadcompleted((a)))
#define MAX_RTR_SOLICITATION_DELAY 1 /* seconds */
#define MAX_UNICAST_SOLICIT 3 /* 3 transmissions */
int ipv6nd_hasradhcp(const struct interface *);
void ipv6nd_handleifa(struct dhcpcd_ctx *, int,
const char *, const struct in6_addr *, int);
+int ipv6nd_dadcompleted(const struct interface *);
void ipv6nd_drop(struct interface *);
#ifdef HAVE_RTM_GETNEIGH
#endif
#ifdef INET6
- if (ipv6nd_hasra(ifp)) {
+ if (RS_STATE_RUNNING(ifp)) {
if (send_interface1(fd, ifp, "ROUTERADVERT") == -1)
retval = -1;
}