aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_divert.c
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2011-06-04 16:26:02 +0000
committerRobert Watson <rwatson@FreeBSD.org>2011-06-04 16:26:02 +0000
commit711b3dbd5454ceb1f0ed0e52179b0e681f60b232 (patch)
tree8151fa33fe565b39db6e4d8f2bdb6a691e071bff /sys/netinet/ip_divert.c
parent7fcc404b47b05787e46b03e1c5312267d6678182 (diff)
downloadsrc-711b3dbd5454ceb1f0ed0e52179b0e681f60b232.tar.gz
src-711b3dbd5454ceb1f0ed0e52179b0e681f60b232.zip
IP divert sockets use their inpcbinfo for port reservation, although not
for lookup. I missed its call to in_pcbbind() when preparing previous patches, which would lead to a lock assertion failure (although problem not an actual race condition due to global pcbinfo locks providing required synchronisation -- in this particular case only). This change adds the missing locking of the pcbhash lock. (Existing comments in the ipdivert code question the need for using the global hash to manage the namespace, as really it's a simple port namespace and not an address/port namespace. Also, although in_pcbbind is used to manage reservations, the hash tables aren't used for lookup. It might be a good idea to make them use hashed lookup, or to use a different reservation scheme.) Reviewed by: bz Reported by: Kristof Provost <kristof at sigsegv.be> Sponsored by: Juniper Networks
Notes
Notes: svn path=/head/; revision=222690
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r--sys/netinet/ip_divert.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 9f0e31c16001..6f5bce7d4876 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -530,7 +530,9 @@ div_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY;
INP_INFO_WLOCK(&V_divcbinfo);
INP_WLOCK(inp);
+ INP_HASH_WLOCK(&V_divcbinfo);
error = in_pcbbind(inp, nam, td->td_ucred);
+ INP_HASH_WUNLOCK(&V_divcbinfo);
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_divcbinfo);
return error;