dhcp6_freedrop_addrs(ifp, 1, NULL);
dhcp6_delete_delegates(ifp);
script_runreason(ifp, "EXPIRE6");
- dhcp6_startdiscover(ifp);
+ if (ipv6nd_hasradhcp(ifp))
+ dhcp6_startdiscover(ifp);
+ else
+ syslog(LOG_WARNING,
+ "%s: no advertising IPv6 router wants DHCP",
+ ifp->name);
}
static void
len++;
if (D6_STATE_RUNNING(ifp))
len++;
- if (ipv6nd_has_ra(ifp))
+ if (ipv6nd_hasra(ifp))
len++;
}
if (write(fd->fd, &len, sizeof(len)) !=
len++;
if (D6_STATE_RUNNING(ifp))
len++;
- if (ipv6nd_has_ra(ifp))
+ if (ipv6nd_hasra(ifp))
len++;
}
}
}
int
-ipv6nd_has_ra(const struct interface *ifp)
+ipv6nd_hasra(const struct interface *ifp)
{
const struct ra *rap;
if (ifp->ctx->ipv6) {
TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next)
- if (rap->iface == ifp)
+ if (rap->iface == ifp && !rap->expired)
return 1;
}
return 0;
}
+int
+ipv6nd_hasradhcp(const struct interface *ifp)
+{
+ const struct ra *rap;
+
+ if (ifp->ctx->ipv6) {
+ TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
+ if (rap->iface == ifp &&
+ !rap->expired &&
+ (rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)))
+ return 1;
+ }
+ }
+ return 0;
+}
+
ssize_t
ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
{
#define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra), 1)
ssize_t ipv6nd_free(struct interface *);
void ipv6nd_expirera(void *arg);
-int ipv6nd_has_ra(const struct interface *);
+int ipv6nd_hasra(const struct interface *);
+int ipv6nd_hasradhcp(const struct interface *);
void ipv6nd_handleifa(struct dhcpcd_ctx *, int,
const char *, const struct in6_addr *, int);
void ipv6nd_drop(struct interface *);
#ifdef INET6
else if (d6_state && d6_state->new)
dhcp6 = 1;
- else if (ipv6nd_has_ra(ifp))
+ else if (ipv6nd_hasra(ifp))
ra = 1;
#endif
#ifdef INET
#endif
#ifdef INET6
|| (dhcp6 && d6_state && d6_state->new)
- || (ra && ipv6nd_has_ra(ifp))
+ || (ra && ipv6nd_hasra(ifp))
#endif
)
{
#endif
#ifdef INET6
- if (ipv6nd_has_ra(ifp)) {
+ if (ipv6nd_hasra(ifp)) {
if (send_interface1(fd, ifp, "ROUTERADVERT") == -1)
retval = -1;
}