svn commit: r191286 - head/sys/netinet

Robert Watson rwatson at FreeBSD.org
Sun Apr 19 22:25:10 UTC 2009


Author: rwatson
Date: Sun Apr 19 22:25:09 2009
New Revision: 191286
URL: http://svn.freebsd.org/changeset/base/191286

Log:
  Lock interface address lists in in_pcbladdr() when searching for a
  source address for a connection and there's no route or now interface
  for the route.
  
  MFC after:	2 weeks

Modified:
  head/sys/netinet/in_pcb.c

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Sun Apr 19 22:16:19 2009	(r191285)
+++ head/sys/netinet/in_pcb.c	Sun Apr 19 22:25:09 2009	(r191286)
@@ -605,6 +605,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 
 		ifp = ia->ia_ifp;
 		ia = NULL;
+		IF_ADDR_LOCK(ifp);
 		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 
 			sa = ifa->ifa_addr;
@@ -618,8 +619,10 @@ in_pcbladdr(struct inpcb *inp, struct in
 		}
 		if (ia != NULL) {
 			laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
+			IF_ADDR_UNLOCK(ifp);
 			goto done;
 		}
+		IF_ADDR_UNLOCK(ifp);
 
 		/* 3. As a last resort return the 'default' jail address. */
 		error = prison_get_ip4(cred, laddr);
@@ -636,6 +639,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 	 * 3. as a last resort return the 'default' jail address.
 	 */
 	if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
+		struct ifnet *ifp;
 
 		/* If not jailed, use the default returned. */
 		if (cred == NULL || !jailed(cred)) {
@@ -657,7 +661,9 @@ in_pcbladdr(struct inpcb *inp, struct in
 		 * 2. Check if we have any address on the outgoing interface
 		 *    belonging to this jail.
 		 */
-		TAILQ_FOREACH(ifa, &sro.ro_rt->rt_ifp->if_addrhead, ifa_link) {
+		ifp = sro.ro_rt->rt_ifp;
+		IF_ADDR_LOCK(ifp);
+		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 
 			sa = ifa->ifa_addr;
 			if (sa->sa_family != AF_INET)
@@ -670,8 +676,10 @@ in_pcbladdr(struct inpcb *inp, struct in
 		}
 		if (ia != NULL) {
 			laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
+			IF_ADDR_UNLOCK(ifp);
 			goto done;
 		}
+		IF_ADDR_UNLOCK(ifp);
 
 		/* 3. As a last resort return the 'default' jail address. */
 		error = prison_get_ip4(cred, laddr);
@@ -718,6 +726,7 @@ in_pcbladdr(struct inpcb *inp, struct in
 
 			ifp = ia->ia_ifp;
 			ia = NULL;
+			IF_ADDR_LOCK(ifp);
 			TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 
 				sa = ifa->ifa_addr;
@@ -732,8 +741,10 @@ in_pcbladdr(struct inpcb *inp, struct in
 			}
 			if (ia != NULL) {
 				laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
+				IF_ADDR_UNLOCK(ifp);
 				goto done;
 			}
+			IF_ADDR_UNLOCK(ifp);
 		}
 
 		/* 3. As a last resort return the 'default' jail address. */


More information about the svn-src-head mailing list