summary refs log tree commit diff
path: root/net/xfrm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-10-12 22:03:24 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2006-10-15 23:14:18 -0700
commit918049f0135854a1583f9b3b88f44dbf2b027329 (patch)
treeddddc6beed8bf1cbe472d2fe106de34cf1726faa /net/xfrm
parent4663afe2c848e2abc8791202beecf40684f13eb4 (diff)
downloadlinux-918049f0135854a1583f9b3b88f44dbf2b027329.tar.gz
[XFRM]: Fix xfrm_state_num going negative.
Missing counter bump when hashing in a new ACQ
xfrm_state.

Now that we have two spots to do the hash grow
check, break it out into a helper function.

Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_state.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 39b8bf3a9ded..84bbf8474f3e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -614,6 +614,14 @@ out:
 	return x;
 }
 
+static void xfrm_hash_grow_check(int have_hash_collision)
+{
+	if (have_hash_collision &&
+	    (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
+	    xfrm_state_num > xfrm_state_hmask)
+		schedule_work(&xfrm_hash_work);
+}
+
 static void __xfrm_state_insert(struct xfrm_state *x)
 {
 	unsigned int h;
@@ -642,10 +650,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
 	xfrm_state_num++;
 
-	if (x->bydst.next != NULL &&
-	    (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
-	    xfrm_state_num > xfrm_state_hmask)
-		schedule_work(&xfrm_hash_work);
+	xfrm_hash_grow_check(x->bydst.next != NULL);
 }
 
 /* xfrm_state_lock is held */
@@ -753,6 +758,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
 		h = xfrm_src_hash(daddr, saddr, family);
 		hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
 		wake_up(&km_waitq);
+
+		xfrm_state_num++;
+
+		xfrm_hash_grow_check(x->bydst.next != NULL);
 	}
 
 	return x;