| 2077 | } |
| 2078 | |
| 2079 | static int |
| 2080 | nd6_prefix_onlink(struct nd_prefix *pr) |
| 2081 | { |
| 2082 | struct epoch_tracker et; |
| 2083 | struct ifaddr *ifa; |
| 2084 | struct ifnet *ifp = pr->ndpr_ifp; |
| 2085 | struct nd_prefix *opr; |
| 2086 | char ip6buf[INET6_ADDRSTRLEN]; |
| 2087 | int error; |
| 2088 | |
| 2089 | ND6_ONLINK_LOCK_ASSERT(); |
| 2090 | ND6_UNLOCK_ASSERT(); |
| 2091 | |
| 2092 | if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) |
| 2093 | return (EEXIST); |
| 2094 | |
| 2095 | /* |
| 2096 | * Add the interface route associated with the prefix. Before |
| 2097 | * installing the route, check if there's the same prefix on another |
| 2098 | * interface, and the prefix has already installed the interface route. |
| 2099 | * Although such a configuration is expected to be rare, we explicitly |
| 2100 | * allow it. |
| 2101 | */ |
| 2102 | ND6_RLOCK(); |
| 2103 | LIST_FOREACH(opr, &V_nd_prefix, ndpr_entry) { |
| 2104 | if (opr == pr) |
| 2105 | continue; |
| 2106 | |
| 2107 | if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) |
| 2108 | continue; |
| 2109 | |
| 2110 | if (!V_rt_add_addr_allfibs && |
| 2111 | opr->ndpr_ifp->if_fib != pr->ndpr_ifp->if_fib) |
| 2112 | continue; |
| 2113 | |
| 2114 | if (opr->ndpr_plen == pr->ndpr_plen && |
| 2115 | in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, |
| 2116 | &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { |
| 2117 | ND6_RUNLOCK(); |
| 2118 | return (0); |
| 2119 | } |
| 2120 | } |
| 2121 | ND6_RUNLOCK(); |
| 2122 | |
| 2123 | /* |
| 2124 | * We prefer link-local addresses as the associated interface address. |
| 2125 | */ |
| 2126 | /* search for a link-local addr */ |
| 2127 | NET_EPOCH_ENTER(et); |
| 2128 | ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, |
| 2129 | IN6_IFF_NOTREADY | IN6_IFF_ANYCAST); |
| 2130 | if (ifa == NULL) { |
| 2131 | /* XXX: freebsd does not have ifa_ifwithaf */ |
| 2132 | CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { |
| 2133 | if (ifa->ifa_addr->sa_family == AF_INET6) { |
| 2134 | ifa_ref(ifa); |
| 2135 | break; |
| 2136 | } |
no test coverage detected