diff options
author | ume <ume@FreeBSD.org> | 2003-11-05 17:19:31 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-11-05 17:19:31 +0000 |
commit | d2486e878b8753b281c2dbc6a91c6652e643d840 (patch) | |
tree | 77d6bd8dc771c045aa9efbf15f26042c607a13c4 /sys/netinet6/in6.c | |
parent | 4dcc0c992a08f968d2add69130aa2373e6ec34c0 (diff) | |
download | FreeBSD-src-d2486e878b8753b281c2dbc6a91c6652e643d840.zip FreeBSD-src-d2486e878b8753b281c2dbc6a91c6652e643d840.tar.gz |
byebye in6_ifawithscope(). it was a function for old source
address selection.
Obtained from: KAME
Diffstat (limited to 'sys/netinet6/in6.c')
-rw-r--r-- | sys/netinet6/in6.c | 282 |
1 files changed, 0 insertions, 282 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 1f2c337..ae01112 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1859,288 +1859,6 @@ in6_prefixlen2mask(maskp, len) } /* - * return the best address out of the same scope - */ -struct in6_ifaddr * -in6_ifawithscope(oifp, dst) - struct ifnet *oifp; - struct in6_addr *dst; -{ - int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0; - int blen = -1; - struct ifaddr *ifa; - struct ifnet *ifp; - struct in6_ifaddr *ifa_best = NULL; - u_int32_t dstzone, odstzone; - - if (oifp == NULL) { - return (NULL); - } - - if (in6_addr2zoneid(oifp, dst, &odstzone)) - return (NULL); - - /* - * We search for all addresses on all interfaces from the beginning. - * Comparing an interface with the outgoing interface will be done - * only at the final stage of tiebreaking. - */ - IFNET_RLOCK(); - for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) - { - /* - * We can never take an address that breaks the scope zone - * of the destination. - */ - if (in6_addr2zoneid(ifp, dst, &dstzone) || dstzone != odstzone) - continue; - - TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) - { - int tlen = -1, dscopecmp, bscopecmp, matchcmp; - - if (ifa->ifa_addr->sa_family != AF_INET6) - continue; - - src_scope = in6_addrscope(IFA_IN6(ifa)); - - /* - * Don't use an address before completing DAD - * nor a duplicated address. - */ - if (((struct in6_ifaddr *)ifa)->ia6_flags & - IN6_IFF_NOTREADY) - continue; - - /* XXX: is there any case to allow anycasts? */ - if (((struct in6_ifaddr *)ifa)->ia6_flags & - IN6_IFF_ANYCAST) - continue; - - if (((struct in6_ifaddr *)ifa)->ia6_flags & - IN6_IFF_DETACHED) - continue; - - /* - * If this is the first address we find, - * keep it anyway. - */ - if (ifa_best == NULL) - goto replace; - - /* - * ifa_best is never NULL beyond this line except - * within the block labeled "replace". - */ - - /* - * If ifa_best has a smaller scope than dst and - * the current address has a larger one than - * (or equal to) dst, always replace ifa_best. - * Also, if the current address has a smaller scope - * than dst, ignore it unless ifa_best also has a - * smaller scope. - * Consequently, after the two if-clause below, - * the followings must be satisfied: - * (scope(src) < scope(dst) && - * scope(best) < scope(dst)) - * OR - * (scope(best) >= scope(dst) && - * scope(src) >= scope(dst)) - */ - if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0 && - IN6_ARE_SCOPE_CMP(src_scope, dst_scope) >= 0) - goto replace; /* (A) */ - if (IN6_ARE_SCOPE_CMP(src_scope, dst_scope) < 0 && - IN6_ARE_SCOPE_CMP(best_scope, dst_scope) >= 0) - continue; /* (B) */ - - /* - * A deprecated address SHOULD NOT be used in new - * communications if an alternate (non-deprecated) - * address is available and has sufficient scope. - * RFC 2462, Section 5.5.4. - */ - if (((struct in6_ifaddr *)ifa)->ia6_flags & - IN6_IFF_DEPRECATED) { - /* - * Ignore any deprecated addresses if - * specified by configuration. - */ - if (!ip6_use_deprecated) - continue; - - /* - * If we have already found a non-deprecated - * candidate, just ignore deprecated addresses. - */ - if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) - == 0) - continue; - } - - /* - * A non-deprecated address is always preferred - * to a deprecated one regardless of scopes and - * address matching (Note invariants ensured by the - * conditions (A) and (B) above.) - */ - if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) && - (((struct in6_ifaddr *)ifa)->ia6_flags & - IN6_IFF_DEPRECATED) == 0) - goto replace; - - /* - * When we use temporary addresses described in - * RFC 3041, we prefer temporary addresses to - * public autoconf addresses. Again, note the - * invariants from (A) and (B). Also note that we - * don't have any preference between static addresses - * and autoconf addresses (despite of whether or not - * the latter is temporary or public.) - */ - if (ip6_use_tempaddr) { - struct in6_ifaddr *ifat; - - ifat = (struct in6_ifaddr *)ifa; - if ((ifa_best->ia6_flags & - (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) - == IN6_IFF_AUTOCONF && - (ifat->ia6_flags & - (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) - == (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) { - goto replace; - } - if ((ifa_best->ia6_flags & - (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) - == (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY) && - (ifat->ia6_flags & - (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) - == IN6_IFF_AUTOCONF) { - continue; - } - } - - /* - * At this point, we have two cases: - * 1. we are looking at a non-deprecated address, - * and ifa_best is also non-deprecated. - * 2. we are looking at a deprecated address, - * and ifa_best is also deprecated. - * Also, we do not have to consider a case where - * the scope of if_best is larger(smaller) than dst and - * the scope of the current address is smaller(larger) - * than dst. Such a case has already been covered. - * Tiebreaking is done according to the following - * items: - * - the scope comparison between the address and - * dst (dscopecmp) - * - the scope comparison between the address and - * ifa_best (bscopecmp) - * - if the address match dst longer than ifa_best - * (matchcmp) - * - if the address is on the outgoing I/F (outI/F) - * - * Roughly speaking, the selection policy is - * - the most important item is scope. The same scope - * is best. Then search for a larger scope. - * Smaller scopes are the last resort. - * - A deprecated address is chosen only when we have - * no address that has an enough scope, but is - * prefered to any addresses of smaller scopes - * (this must be already done above.) - * - addresses on the outgoing I/F are preferred to - * ones on other interfaces if none of above - * tiebreaks. In the table below, the column "bI" - * means if the best_ifa is on the outgoing - * interface, and the column "sI" means if the ifa - * is on the outgoing interface. - * - If there is no other reasons to choose one, - * longest address match against dst is considered. - * - * The precise decision table is as follows: - * dscopecmp bscopecmp match bI oI | replace? - * N/A equal N/A Y N | No (1) - * N/A equal N/A N Y | Yes (2) - * N/A equal larger N/A | Yes (3) - * N/A equal !larger N/A | No (4) - * larger larger N/A N/A | No (5) - * larger smaller N/A N/A | Yes (6) - * smaller larger N/A N/A | Yes (7) - * smaller smaller N/A N/A | No (8) - * equal smaller N/A N/A | Yes (9) - * equal larger (already done at A above) - */ - dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope); - bscopecmp = IN6_ARE_SCOPE_CMP(src_scope, best_scope); - - if (bscopecmp == 0) { - struct ifnet *bifp = ifa_best->ia_ifp; - - if (bifp == oifp && ifp != oifp) /* (1) */ - continue; - if (bifp != oifp && ifp == oifp) /* (2) */ - goto replace; - - /* - * Both bifp and ifp are on the outgoing - * interface, or both two are on a different - * interface from the outgoing I/F. - * now we need address matching against dst - * for tiebreaking. - */ - tlen = in6_matchlen(IFA_IN6(ifa), dst); - matchcmp = tlen - blen; - if (matchcmp > 0) /* (3) */ - goto replace; - continue; /* (4) */ - } - if (dscopecmp > 0) { - if (bscopecmp > 0) /* (5) */ - continue; - goto replace; /* (6) */ - } - if (dscopecmp < 0) { - if (bscopecmp > 0) /* (7) */ - goto replace; - continue; /* (8) */ - } - - /* now dscopecmp must be 0 */ - if (bscopecmp < 0) - goto replace; /* (9) */ - - replace: - ifa_best = (struct in6_ifaddr *)ifa; - blen = tlen >= 0 ? tlen : - in6_matchlen(IFA_IN6(ifa), dst); - best_scope = in6_addrscope(&ifa_best->ia_addr.sin6_addr); - } - } - IFNET_RUNLOCK(); - - /* count statistics for future improvements */ - if (ifa_best == NULL) - ip6stat.ip6s_sources_none++; - else { - if (oifp == ifa_best->ia_ifp) - ip6stat.ip6s_sources_sameif[best_scope]++; - else - ip6stat.ip6s_sources_otherif[best_scope]++; - - if (best_scope == dst_scope) - ip6stat.ip6s_sources_samescope[best_scope]++; - else - ip6stat.ip6s_sources_otherscope[best_scope]++; - - if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) != 0) - ip6stat.ip6s_sources_deprecated[best_scope]++; - } - - return (ifa_best); -} - -/* * return the best address out of the same scope. if no address was * found, return the first valid address from designated IF. */ |