Add a #define to compile ignoring the RA without a public address.

This is set for BSD systems at present so that working systems such as Linux
work by default as designed.
Fixes [f44b3b4817].
This commit is contained in:
Roy Marples 2015-07-13 19:05:33 +00:00
parent 2862d340c7
commit 0723fb86aa
7 changed files with 36 additions and 4 deletions

View File

@ -505,6 +505,7 @@ dhcp6_delegateaddr(struct in6_addr *addr, struct interface *ifp,
return sla->prefix_len;
}
#ifdef IGNORE_RA_NOPUBLICADDR
int
dhcp6_has_public_addr(const struct interface *ifp)
{
@ -519,6 +520,7 @@ dhcp6_has_public_addr(const struct interface *ifp)
}
return 0;
}
#endif
static int
dhcp6_makemessage(struct interface *ifp)
@ -3025,7 +3027,9 @@ recv:
eloop_timeout_add_sec(ifp->ctx->eloop,
(time_t)state->expire, dhcp6_startexpire, ifp);
#ifdef IGNORE_RA_NOPUBLICADDR
ipv6nd_runignoredra(ifp);
#endif
ipv6_addaddrs(&state->addrs);
dhcp6_delegate_prefix(ifp);

View File

@ -238,7 +238,6 @@ const struct ipv6_addr *dhcp6_iffindaddr(const struct interface *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 *,
@ -249,6 +248,10 @@ void dhcp6_handleifa(struct dhcpcd_ctx *, int, const char *,
int dhcp6_dadcompleted(const struct interface *);
void dhcp6_drop(struct interface *, const char *);
int dhcp6_dump(struct interface *);
#ifdef IGNORE_RA_NOPUBLICADDR
int dhcp6_has_public_addr(const struct interface *);
#endif
#else
#define dhcp6_find_delegates(a) {}
#define dhcp6_start(a, b) (0)

View File

@ -371,9 +371,12 @@ and/or user selection rather than the kernel.
.It Ic ipv6ra_accept_nopublic
Some IPv6 routers advertise themselves as a default router without any
public prefixes or managed addresses.
Generally, this is incorrect behaviour and
On non Linux systems
.Nm dhcpcd
will ignore the advertisement unless this option is turned on.
will ignore the advertisement,
unless this option is turned on,
so that attempts to access a remote public IPv6 address without a local
public IPv6 address fail quickly.
.It Ic ipv6rs
Enables IPv6 Router Advertisment solicitation.
This is on by default, but is documented here in the case where it is disabled

2
ipv6.c
View File

@ -745,6 +745,7 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
return 0;
}
#ifdef IGNORE_RA_NOPUBLICADDR
int
ipv6_publicaddr(const struct ipv6_addr *ia)
{
@ -752,6 +753,7 @@ ipv6_publicaddr(const struct ipv6_addr *ia)
(ia->addr.s6_addr[0] & 0xfe) != 0xfc &&
!(ia->addr_flags & IN6_IFF_NOTUSEABLE));
}
#endif
int
ipv6_findaddrmatch(const struct ipv6_addr *addr, const struct in6_addr *match,

10
ipv6.h
View File

@ -104,6 +104,16 @@
#define IPV6_MANAGETEMPADDR
#endif
/* NetBSD at least will try and contact a global address if there is a default
* route but there is no global address on the interface to connect with.
* As a safety measure, we ignore RA's until a public address is found.
* This is the wrong thing todo, as Linux seems to abort early - maybe
* because there is no matching source address for the destination address.
* Until this is resolved, we have this restriction in place. */
#ifdef BSD
#define IGNORE_RA_NOPUBLICADDR
#endif
struct ipv6_addr {
TAILQ_ENTRY(ipv6_addr) next;
struct interface *iface;

View File

@ -731,6 +731,7 @@ try_script:
}
}
#ifdef IGNORE_RA_NOPUBLICADDR
static int
ipv6nd_ra_has_public_addr(const struct ra *rap)
{
@ -743,6 +744,7 @@ ipv6nd_ra_has_public_addr(const struct ra *rap)
}
return 0;
}
#endif
static void
ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
@ -1106,6 +1108,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
if (new_rap)
add_router(ifp->ctx->ipv6, rap);
#ifdef IGNORE_RA_NOPUBLICADDR
if (!ipv6nd_ra_has_public_addr(rap) &&
!(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) &&
(!(rap->flags & ND_RA_FLAG_MANAGED) ||
@ -1119,6 +1122,8 @@ ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
rap->no_public_warned = 1;
goto handle_flag;
}
#endif
if (ifp->ctx->options & DHCPCD_TEST) {
script_runreason(ifp, "TEST");
goto handle_flag;
@ -1166,6 +1171,7 @@ nodhcp6:
ipv6nd_expirera(ifp);
}
#ifdef IGNORE_RA_NOPUBLICADDR
/* Run RA's we ignored becuase they had no public addresses
* This should only be called when DHCPv6 applies a public address */
void
@ -1193,6 +1199,7 @@ ipv6nd_runignoredra(struct interface *ifp)
}
}
}
#endif
int
ipv6nd_hasra(const struct interface *ifp)

View File

@ -110,13 +110,16 @@ 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 *);
void ipv6nd_expire(struct interface *, uint32_t);
void ipv6nd_drop(struct interface *);
void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int);
#ifdef IGNORE_RA_NOPUBLICADDR
void ipv6nd_runignoredra(struct interface *);
#endif
#else
#define ipv6nd_startrs(a) {}
#define ipv6nd_free(a) {}