Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Apr 2015 15:31:19 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r281152 - head/sys/netinet
Message-ID:  <201504061531.t36FVJwL098042@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Mon Apr  6 15:31:19 2015
New Revision: 281152
URL: https://svnweb.freebsd.org/changeset/base/281152

Log:
  Add sleepable lock to protect at least against two parallel SIOCSVHs.
  
  Sponsored by:	Nginx, Inc.

Modified:
  head/sys/netinet/ip_carp.c

Modified: head/sys/netinet/ip_carp.c
==============================================================================
--- head/sys/netinet/ip_carp.c	Mon Apr  6 15:22:32 2015	(r281151)
+++ head/sys/netinet/ip_carp.c	Mon Apr  6 15:31:19 2015	(r281152)
@@ -180,9 +180,6 @@ static int proto_reg[] = {-1, -1};
  *
  * Known issues with locking:
  *
- * - There is no protection for races between two ioctl() requests,
- *   neither SIOCSVH, nor SIOCAIFADDR & SIOCAIFADDR_IN6. I think that all
- *   interface ioctl()s should be serialized right in net/if.c.
  * - Sending ad, we put the pointer to the softc in an mtag, and no reference
  *   counting is done on the softc.
  * - On module unload we may race (?) with packet processing thread
@@ -321,6 +318,7 @@ static void	carp_demote_adj(int, char *)
 
 static LIST_HEAD(, carp_softc) carp_list;
 static struct mtx carp_mtx;
+static struct sx carp_sx;
 static struct task carp_sendall_task =
     TASK_INITIALIZER(0, carp_send_ad_all, NULL);
 
@@ -1650,6 +1648,7 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 		goto out;
 	}
 
+	sx_xlock(&carp_sx);
 	switch (cmd) {
 	case SIOCSVH:
 		if ((error = priv_check(td, PRIV_NETINET_CARP)))
@@ -1780,6 +1779,7 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 	default:
 		error = EINVAL;
 	}
+	sx_xunlock(&carp_sx);
 
 out:
 	if (locked)
@@ -2099,6 +2099,7 @@ carp_mod_cleanup(void)
 	mtx_unlock(&carp_mtx);
 	taskqueue_drain(taskqueue_swi, &carp_sendall_task);
 	mtx_destroy(&carp_mtx);
+	sx_destroy(&carp_sx);
 }
 
 static int
@@ -2107,6 +2108,7 @@ carp_mod_load(void)
 	int err;
 
 	mtx_init(&carp_mtx, "carp_mtx", NULL, MTX_DEF);
+	sx_init(&carp_sx, "carp_sx");
 	LIST_INIT(&carp_list);
 	carp_get_vhid_p = carp_get_vhid;
 	carp_forus_p = carp_forus;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504061531.t36FVJwL098042>