From: Roy Marples Date: Tue, 11 Dec 2012 09:00:49 +0000 (+0000) Subject: Respect the ONLINK flag the prefix option of the RA X-Git-Tag: v5.99.3~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cd3612e5ca00b8df13bfce7339f5aed900813ec6;p=thirdparty%2Fdhcpcd.git Respect the ONLINK flag the prefix option of the RA --- diff --git a/dhcp6.c b/dhcp6.c index 9026d3e8..100cfe49 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -948,6 +948,7 @@ dhcp6_findia(struct interface *ifp, const uint8_t *d, size_t l) a = malloc(sizeof(*a)); if (a) { a->new = 1; + a->onlink = 1; /* XXX: suprised no DHCP opt for this */ p = D6_COPTION_DATA(o); memcpy(&a->addr.s6_addr, p, sizeof(a->addr.s6_addr)); diff --git a/ipv6.c b/ipv6.c index 198cb2d0..93d2e1cf 100644 --- a/ipv6.c +++ b/ipv6.c @@ -439,9 +439,6 @@ ipv6_removesubnet(const struct interface *ifp, struct ipv6_addr *addr) #endif { r = del_route6(rt); - /* If the subnet route didn't exist, don't - * moan about it. - * We currently do this to silence FreeBSD-7 */ if (r == -1 && errno == ESRCH) r = 0; } @@ -473,6 +470,8 @@ ipv6_buildroutes(void) d6_state = D6_CSTATE(ifp); if (d6_state && d6_state->state == DH6S_BOUND) { TAILQ_FOREACH(addr, &d6_state->addrs, next) { + if (!addr->onlink) + continue; rt = make_prefix(ifp, NULL, addr); if (rt) TAILQ_INSERT_TAIL(&dnr, rt, next); @@ -482,6 +481,8 @@ ipv6_buildroutes(void) TAILQ_FOREACH(rap, &ipv6_routers, next) { if (options & DHCPCD_IPV6RA_OWN) { TAILQ_FOREACH(addr, &rap->addrs, next) { + if (!addr->onlink) + continue; rt = make_prefix(rap->iface, rap, addr); if (rt) TAILQ_INSERT_TAIL(&dnr, rt, next); diff --git a/ipv6.h b/ipv6.h index 92a91353..e4d28221 100644 --- a/ipv6.h +++ b/ipv6.h @@ -44,7 +44,8 @@ struct ipv6_addr { uint32_t prefix_vltime; uint32_t prefix_pltime; struct in6_addr addr; - int new; + uint8_t onlink; + uint8_t new; char saddr[INET6_ADDRSTRLEN]; }; TAILQ_HEAD(ipv6_addrhead, ipv6_addr); diff --git a/ipv6rs.c b/ipv6rs.c index d04663ff..d09c09e2 100644 --- a/ipv6rs.c +++ b/ipv6rs.c @@ -295,6 +295,7 @@ ipv6rs_freedrop_addrs(struct ra *rap, int drop) * This is safe because the RA is removed from the list * before we are called. */ if (drop && (options & DHCPCD_IPV6RA_OWN) && + !IN6_IS_ADDR_UNSPECIFIED(&ap->addr) && !ipv6rs_addrexists(ap) && !dhcp6_addrexists(ap)) { syslog(LOG_INFO, "%s: deleting address %s", @@ -581,6 +582,11 @@ ipv6rs_handledata(_unused void *arg) sizeof(ap->prefix.s6_addr)) == 0) break; if (ap == NULL) { + if (!(pi->nd_opt_pi_flags_reserved & + ND_OPT_PI_FLAG_AUTO) && + !(pi->nd_opt_pi_flags_reserved & + ND_OPT_PI_FLAG_ONLINK)) + break; ap = xmalloc(sizeof(*ap)); ap->new = 1; ap->prefix_len = pi->nd_opt_pi_prefix_len; @@ -615,6 +621,9 @@ ipv6rs_handledata(_unused void *arg) ap->new = 1; else ap->new = 0; + if (pi->nd_opt_pi_flags_reserved & + ND_OPT_PI_FLAG_ONLINK) + ap->onlink = 1; ap->prefix_vltime = ntohl(pi->nd_opt_pi_valid_time); ap->prefix_pltime =