svn commit: r191285 - head/sys/netinet

Robert Watson rwatson at FreeBSD.org
Sun Apr 19 22:16:20 UTC 2009


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

Log:
  Protect against some writer-writer races in in_control() by acquiring
  the interface address list lock around interface address list
  modifications.  More to do here.
  
  MFC after:	2 weeks

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Sun Apr 19 22:05:39 2009	(r191284)
+++ head/sys/netinet/in.c	Sun Apr 19 22:16:19 2009	(r191285)
@@ -330,14 +330,12 @@ in_control(struct socket *so, u_long cmd
 			 * Protect from ipintr() traversing address list
 			 * while we're modifying it.
 			 */
-			s = splnet();
 			ifa = &ia->ia_ifa;
 			IFA_LOCK_INIT(ifa);
 			ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
 			ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
 			ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
 			ifa->ifa_refcnt = 1;
-			TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
 
 			ia->ia_sockmask.sin_len = 8;
 			ia->ia_sockmask.sin_family = AF_INET;
@@ -347,6 +345,10 @@ in_control(struct socket *so, u_long cmd
 			}
 			ia->ia_ifp = ifp;
 
+			IF_ADDR_LOCK(ifp);
+			TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
+			IF_ADDR_UNLOCK(ifp);
+			s = splnet();
 			TAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link);
 			splx(s);
 			iaIsNew = 1;
@@ -512,8 +514,10 @@ in_control(struct socket *so, u_long cmd
 	 * Protect from ipintr() traversing address list while we're modifying
 	 * it.
 	 */
-	s = splnet();
+	IF_ADDR_LOCK(ifp);
 	TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
+	IF_ADDR_UNLOCK(ifp);
+	s = splnet();
 	TAILQ_REMOVE(&V_in_ifaddrhead, ia, ia_link);
 	if (ia->ia_addr.sin_family == AF_INET) {
 		LIST_REMOVE(ia, ia_hash);


More information about the svn-src-all mailing list