diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -326,7 +326,8 @@ struct prf_ra { u_char onlink : 1; u_char autonomous : 1; - u_char reserved : 6; + u_char ra_derived: 1; + u_char reserved : 5; } prf_ra; u_char prf_reserved1; u_short prf_reserved2; @@ -357,6 +358,7 @@ #define ipr_raf_onlink ipr_flags.prf_ra.onlink #define ipr_raf_auto ipr_flags.prf_ra.autonomous +#define ipr_raf_ra_derived ipr_flags.prf_ra.ra_derived #define ipr_statef_onlink ipr_flags.prf_state.onlink diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -243,6 +243,7 @@ #define ndpr_raf ndpr_flags #define ndpr_raf_onlink ndpr_flags.onlink #define ndpr_raf_auto ndpr_flags.autonomous +#define ndpr_raf_ra_derived ndpr_flags.ra_derived #define ndpr_raf_router ndpr_flags.router struct nd_pfxrouter { diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1786,9 +1786,8 @@ ND6_WLOCK(); LIST_FOREACH_SAFE(pr, &V_nd_prefix, ndpr_entry, next) { - if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) - continue; /* XXX */ - nd6_prefix_unlink(pr, &prl); + if (pr->ndpr_raf_ra_derived) + nd6_prefix_unlink(pr, &prl); } ND6_WUNLOCK(); @@ -2662,6 +2661,8 @@ ND6_RLOCK(); LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) { + if (!pr->ndpr_raf_ra_derived) + continue; p.prefix = pr->ndpr_prefix; if (sa6_recoverscope(&p.prefix)) { log(LOG_ERR, "scope error in prefix list (%s)\n", diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -517,6 +517,7 @@ ND_OPT_PI_FLAG_ONLINK) ? 1 : 0; pr.ndpr_raf_auto = (pi->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO) ? 1 : 0; + pr.ndpr_raf_ra_derived = 1; pr.ndpr_plen = pi->nd_opt_pi_prefix_len; pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time); pr.ndpr_pltime = ntohl(pi->nd_opt_pi_preferred_time);