prefixes, don't install a default route for it.
If we did, some OS's will just stall trying to reach global addresses.
By not installing the default route, they can fall back to IPv4 faster.
This can be overridden with ipv6ra_always_default.
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 17, 2015
+.Dd April 4, 2015
.Dt DHCPCD.CONF 5
.Os
.Sh NAME
the default route only.
This allows dhcpcd to prefer an interface for outbound traffic based on metric
and/or user selection rather than the kernel.
+.It Ic ipv6ra_always_default
+Some IPv6 routers advertise themselves as a default router without any
+public prefixes.
+Generally, this is incorrect behaviour and
+.Nm dhcpcd
+will not install a default route for them unless this option is turned on.
.It Ic ipv6rs
Enables IPv6 Router Advertisment solicitation.
This is on by default, but is documented here in the case where it is disabled
#define O_IPV6RA_AUTOCONF O_BASE + 38
#define O_IPV6RA_NOAUTOCONF O_BASE + 39
#define O_REJECT O_BASE + 40
+#define O_IPV6RA_ALWAYS_DEFAULT O_BASE + 41
const struct option cf_options[] = {
{"background", no_argument, NULL, 'b'},
{"ipv6ra_fork", no_argument, NULL, O_IPV6RA_FORK},
{"ipv6ra_own", no_argument, NULL, O_IPV6RA_OWN},
{"ipv6ra_own_default", no_argument, NULL, O_IPV6RA_OWN_D},
+ {"ipv6ra_always_default", no_argument, NULL, O_IPV6RA_ALWAYS_DEFAULT},
{"ipv4only", no_argument, NULL, '4'},
{"ipv6only", no_argument, NULL, '6'},
{"ipv4", no_argument, NULL, O_IPV4},
case O_IPV6RA_OWN_D:
ifo->options |= DHCPCD_IPV6RA_OWN_DEFAULT;
break;
+ case O_IPV6RA_ALWAYS_DEFAULT:
+ ifo->options |= DHCPCD_IPV6RA_ALWAYS_DEFAULT;
+ break;
case O_IPV6RA_AUTOCONF:
ifo->options |= DHCPCD_IPV6RA_AUTOCONF;
break;
#define DHCPCD_PFXDLGMIX (1ULL << 53)
#define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54)
#define DHCPCD_ROUTER_HOST_ROUTE_WARNED (1ULL << 55)
+#define DHCPCD_IPV6RA_ALWAYS_DEFAULT (1ULL << 56)
extern const struct option cf_options[];
(IN6_ARE_ADDR_EQUAL(&((rtp)->dest), &in6addr_any) && \
IN6_ARE_ADDR_EQUAL(&((rtp)->net), &in6addr_any))
+static int
+ra_has_public_addr(const struct ra *rap)
+{
+ const struct ipv6_addr *ia;
+
+ TAILQ_FOREACH(ia, &rap->addrs, next) {
+ if (ia->prefix_pltime && (ia->addr.s6_addr[0] & 0xfe) != 0xfc)
+ return 1;
+ }
+ return 0;
+}
+
static void
ipv6_build_ra_routes(struct ipv6_ctx *ctx, struct rt6_head *dnr, int expired)
{
struct rt6 *rt;
- const struct ra *rap;
+ struct ra *rap;
const struct ipv6_addr *addr;
TAILQ_FOREACH(rap, ctx->ra_routers, next) {
if (rap->lifetime && rap->iface->options->options &
(DHCPCD_IPV6RA_OWN | DHCPCD_IPV6RA_OWN_DEFAULT))
{
- rt = make_router(rap);
- if (rt)
- TAILQ_INSERT_TAIL(dnr, rt, next);
+ if (!ra_has_public_addr(rap)) {
+ logger(rap->iface->ctx,
+ rap->no_default_warned ?
+ LOG_DEBUG : LOG_WARNING,
+ "%s: ignoring default route from %s"
+ " (no public prefix)",
+ rap->iface->name, rap->sfrom);
+ rap->no_default_warned = 1;
+ } else {
+ rt = make_router(rap);
+ if (rt)
+ TAILQ_INSERT_TAIL(dnr, rt, next);
+ }
}
}
}
uint32_t mtu;
struct ipv6_addrhead addrs;
TAILQ_HEAD(, ra_opt) options;
- int expired;
+ uint8_t expired;
+ uint8_t no_default_warned;
};
TAILQ_HEAD(ra_head, ra);