svn commit: r249528 - head/sys/netinet6

Andrey V. Elsukov ae at FreeBSD.org
Mon Apr 15 21:02:40 UTC 2013


Author: ae
Date: Mon Apr 15 21:02:40 2013
New Revision: 249528
URL: http://svnweb.freebsd.org/changeset/base/249528

Log:
  The source address selection algorithm tries to apply several rules
  for the set of IPv6 addresses. Now each attempt goes into IPv6 statistics,
  even if given rule did not won. Change this and take into account only
  those rules, that won. Also add accounting for cases, when algorithm
  fails to select an address.

Modified:
  head/sys/netinet6/in6_src.c

Modified: head/sys/netinet6/in6_src.c
==============================================================================
--- head/sys/netinet6/in6_src.c	Mon Apr 15 20:57:55 2013	(r249527)
+++ head/sys/netinet6/in6_src.c	Mon Apr 15 21:02:40 2013	(r249528)
@@ -151,9 +151,7 @@ static struct in6_addrpolicy *match_addr
  * an entry to the caller for later use.
  */
 #define REPLACE(r) do {\
-	if ((r) < sizeof(V_ip6stat.ip6s_sources_rule) / \
-		sizeof(V_ip6stat.ip6s_sources_rule[0])) /* check for safety */ \
-		IP6STAT_INC(ip6s_sources_rule[(r)]); \
+	rule = (r);	\
 	/* { \
 	char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \
 	printf("in6_selectsrc: replace %s with %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \
@@ -161,9 +159,6 @@ static struct in6_addrpolicy *match_addr
 	goto replace; \
 } while(0)
 #define NEXT(r) do {\
-	if ((r) < sizeof(V_ip6stat.ip6s_sources_rule) / \
-		sizeof(V_ip6stat.ip6s_sources_rule[0])) /* check for safety */ \
-		IP6STAT_INC(ip6s_sources_rule[(r)]); \
 	/* { \
 	char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \
 	printf("in6_selectsrc: keep %s against %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \
@@ -171,9 +166,7 @@ static struct in6_addrpolicy *match_addr
 	goto next;		/* XXX: we can't use 'continue' here */ \
 } while(0)
 #define BREAK(r) do { \
-	if ((r) < sizeof(V_ip6stat.ip6s_sources_rule) / \
-		sizeof(V_ip6stat.ip6s_sources_rule[0])) /* check for safety */ \
-		IP6STAT_INC(ip6s_sources_rule[(r)]); \
+	rule = (r);	\
 	goto out;		/* XXX: we can't use 'break' here */ \
 } while(0)
 
@@ -190,7 +183,7 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 	struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL;
 	u_int32_t odstzone;
 	int prefer_tempaddr;
-	int error;
+	int error, rule;
 	struct ip6_moptions *mopts;
 
 	KASSERT(srcp != NULL, ("%s: srcp is NULL", __func__));
@@ -306,6 +299,7 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 	if (error)
 		return (error);
 
+	rule = 0;
 	IN6_IFADDR_RLOCK();
 	TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) {
 		int new_scope = -1, new_matchlen = -1;
@@ -487,6 +481,7 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 
 	if ((ia = ia_best) == NULL) {
 		IN6_IFADDR_RUNLOCK();
+		IP6STAT_INC(ip6s_sources_none);
 		return (EADDRNOTAVAIL);
 	}
 
@@ -503,6 +498,7 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 	if (cred != NULL && prison_local_ip6(cred, &tmp, (inp != NULL &&
 	    (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
 		IN6_IFADDR_RUNLOCK();
+		IP6STAT_INC(ip6s_sources_none);
 		return (EADDRNOTAVAIL);
 	}
 
@@ -511,6 +507,7 @@ in6_selectsrc(struct sockaddr_in6 *dstso
 
 	bcopy(&tmp, srcp, sizeof(*srcp));
 	IN6_IFADDR_RUNLOCK();
+	IP6STAT_INC(ip6s_sources_rule[rule]);
 	return (0);
 }
 


More information about the svn-src-head mailing list