From 3bd74cd01b6362d69e9bc3a008894fea65cc7fc8 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 11 Dec 2012 08:45:33 +0000 Subject: [PATCH] Respect AUTO and ONLINK flags for each prefix in the RA. --- ipv6.c | 6 ++++++ ipv6.h | 3 ++- ipv6rs.c | 44 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/ipv6.c b/ipv6.c index 793cf6b8..c20d98ad 100644 --- a/ipv6.c +++ b/ipv6.c @@ -384,7 +384,11 @@ ipv6_remove_subnet(struct ra *rap, struct ipv6_addr *addr) #else if (!find_route6(routes, rt)) #endif + { r = del_route6(rt); + if (r == -1 && errno == ESRCH) + r = 0; + } free(rt); } return r; @@ -410,6 +414,8 @@ ipv6_build_routes(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, addr); if (rt) TAILQ_INSERT_TAIL(&dnr, rt, next); diff --git a/ipv6.h b/ipv6.h index ef3b2352..7f889bc2 100644 --- a/ipv6.h +++ b/ipv6.h @@ -46,7 +46,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]; }; diff --git a/ipv6rs.c b/ipv6rs.c index f48d01c7..d4877a9c 100644 --- a/ipv6rs.c +++ b/ipv6rs.c @@ -291,6 +291,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)) { syslog(LOG_INFO, "%s: deleting address %s", @@ -568,21 +569,41 @@ ipv6rs_handledata(_unused void *arg) sizeof(ap->prefix.s6_addr)) == 0) break; if (ap == NULL) { + /* As we haven't added the prefix before + * check if we can make an address with it */ + 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->onlink = 0; ap->prefix_len = pi->nd_opt_pi_prefix_len; memcpy(ap->prefix.s6_addr, pi->nd_opt_pi_prefix.s6_addr, sizeof(ap->prefix.s6_addr)); - ipv6_makeaddr(&ap->addr, ifp->name, - &ap->prefix, pi->nd_opt_pi_prefix_len); - cbp = inet_ntop(AF_INET6, ap->addr.s6_addr, - ntopbuf, INET6_ADDRSTRLEN); - if (cbp) - snprintf(ap->saddr, sizeof(ap->saddr), - "%s/%d", cbp, ap->prefix_len); - else + if (pi->nd_opt_pi_flags_reserved & + ND_OPT_PI_FLAG_AUTO) + { + ipv6_makeaddr(&ap->addr, ifp->name, + &ap->prefix, + pi->nd_opt_pi_prefix_len); + cbp = inet_ntop(AF_INET6, + ap->addr.s6_addr, + ntopbuf, INET6_ADDRSTRLEN); + if (cbp) + snprintf(ap->saddr, + sizeof(ap->saddr), + "%s/%d", + cbp, ap->prefix_len); + else + ap->saddr[0] = '\0'; + } else { + memset(ap->addr.s6_addr, 0, + sizeof(ap->addr.s6_addr)); ap->saddr[0] = '\0'; + } TAILQ_INSERT_TAIL(&rap->addrs, ap, next); } else if (ap->prefix_vltime != ntohl(pi->nd_opt_pi_valid_time) || @@ -591,6 +612,10 @@ ipv6rs_handledata(_unused void *arg) ap->new = 1; else ap->new = 0; + /* onlink should not change from on to off */ + 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 = @@ -722,7 +747,8 @@ ipv6rs_handledata(_unused void *arg) add_router(rap); if (options & DHCPCD_IPV6RA_OWN && !(options & DHCPCD_TEST)) { TAILQ_FOREACH(ap, &rap->addrs, next) { - if (ap->prefix_vltime == 0) + if (ap->prefix_vltime == 0 || + IN6_IS_ADDR_UNSPECIFIED(&ap->addr)) continue; syslog(ap->new ? LOG_INFO : LOG_DEBUG, "%s: adding address %s", -- 2.47.2