mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-24 18:44:10 +08:00
If we receieve an RA without a public prefix but with the Managed flag set,
ignore the RA until we recieve a DHCPv6 lease with a public address at which point it is applied.
This commit is contained in:
parent
6c05c9f899
commit
d40f2f7b8d
17
dhcp6.c
17
dhcp6.c
@ -487,6 +487,22 @@ dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
|
||||
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)
|
||||
{
|
||||
@ -3033,6 +3049,7 @@ recv:
|
||||
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);
|
||||
|
||||
|
1
dhcp6.h
1
dhcp6.h
@ -235,6 +235,7 @@ void dhcp6_printoptions(const struct dhcpcd_ctx *,
|
||||
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 *,
|
||||
|
33
ipv6nd.c
33
ipv6nd.c
@ -1136,8 +1136,9 @@ extra_opt:
|
||||
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,
|
||||
@ -1194,6 +1195,34 @@ nodhcp6:
|
||||
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)
|
||||
{
|
||||
|
1
ipv6nd.h
1
ipv6nd.h
@ -94,6 +94,7 @@ ssize_t ipv6nd_free(struct interface *);
|
||||
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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user