summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/in6.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-11-05 17:19:31 +0000
committerume <ume@FreeBSD.org>2003-11-05 17:19:31 +0000
commitd2486e878b8753b281c2dbc6a91c6652e643d840 (patch)
tree77d6bd8dc771c045aa9efbf15f26042c607a13c4 /sys/netinet6/in6.c
parent4dcc0c992a08f968d2add69130aa2373e6ec34c0 (diff)
downloadFreeBSD-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.c282
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.
*/
OpenPOWER on IntegriCloud