return sla->prefix_len;
}
+int
+dhcp6_has_public_addr(const struct interface *ifp)
+{
+ const struct dhcp6_state *state = D6_CSTATE(ifp);
+ const struct ipv6_addr *ia;
+
+ if (state == NULL)
+ return 0;
+ TAILQ_FOREACH(ia, &state->addrs, next) {
+ if (ia->prefix_pltime &&
+ (ia->addr.s6_addr[0] & 0xfe) != 0xc)
+ return 1;
+ }
+ return 0;
+}
+
static int
dhcp6_makemessage(struct interface *ifp)
{
eloop_timeout_add_sec(ifp->ctx->eloop,
(time_t)state->expire, dhcp6_startexpire, ifp);
+ ipv6nd_runignoredra(ifp);
ipv6_addaddrs(&state->addrs);
dhcp6_delegate_prefix(ifp);
struct ipv6_addr *dhcp6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *,
short);
size_t dhcp6_find_delegates(struct interface *);
+int dhcp6_has_public_addr(const struct interface *);
int dhcp6_start(struct interface *, enum DH6S);
void dhcp6_reboot(struct interface *);
ssize_t dhcp6_env(char **, const char *, const struct interface *,
if (new_rap)
add_router(ifp->ctx->ipv6, rap);
if (!ipv6nd_ra_has_public_addr(rap) &&
- !(rap->flags & ND_RA_FLAG_MANAGED) &&
- !(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC))
+ !(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) &&
+ (!(rap->flags & ND_RA_FLAG_MANAGED) ||
+ !dhcp6_has_public_addr(rap->iface)))
{
logger(rap->iface->ctx,
rap->no_public_warned ? LOG_DEBUG : LOG_WARNING,
ipv6nd_expirera(ifp);
}
+/* Run RA's we ignored becuase they had no public addresses
+ * This should only be called when DHCPv6 applies a public address */
+void
+ipv6nd_runignoredra(struct interface *ifp)
+{
+ struct ra *rap;
+
+ TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
+ if (rap->iface == ifp &&
+ !rap->expired &&
+ rap->no_public_warned)
+ {
+ rap->no_public_warned = 0;
+ logger(rap->iface->ctx, LOG_INFO,
+ "%s: applying ignored RA from %s",
+ rap->iface->name, rap->sfrom);
+ if (ifp->ctx->options & DHCPCD_TEST) {
+ script_runreason(ifp, "TEST");
+ continue;
+ }
+ if (ipv6nd_scriptrun(rap))
+ return;
+ eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+ eloop_timeout_delete(ifp->ctx->eloop, NULL, rap);
+ }
+ }
+}
+
int
ipv6nd_hasra(const struct interface *ifp)
{
void ipv6nd_expirera(void *arg);
int ipv6nd_hasra(const struct interface *);
int ipv6nd_hasradhcp(const struct interface *);
+void ipv6nd_runignoredra(struct interface *);
void ipv6nd_handleifa(struct dhcpcd_ctx *, int,
const char *, const struct in6_addr *, int);
int ipv6nd_dadcompleted(const struct interface *);