summaryrefslogtreecommitdiffstats
path: root/ipv6.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2015-04-03 23:36:06 +0000
committerRoy Marples <roy@marples.name>2015-04-03 23:36:06 +0000
commita8e5259b41b43dd89af8ed66ce1dd881806cc129 (patch)
tree635f0f336cbc4d83be6945edc47ee9fd5b60ec3f /ipv6.c
parent3a35e9fe25c95f414d7cb8c75ca27ce946a2b176 (diff)
downloaddhcpcd-a8e5259b41b43dd89af8ed66ce1dd881806cc129.tar.xz
If a IPv6 router claims it's a valid router but doesn't have any public
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.
Diffstat (limited to 'ipv6.c')
-rw-r--r--ipv6.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/ipv6.c b/ipv6.c
index 966b516c..530bf45c 100644
--- a/ipv6.c
+++ b/ipv6.c
@@ -1956,11 +1956,23 @@ make_router(const struct ra *rap)
(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) {
@@ -1976,9 +1988,19 @@ ipv6_build_ra_routes(struct ipv6_ctx *ctx, struct rt6_head *dnr, int expired)
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);
+ }
}
}
}