diff options
author | Patrick McHardy <kaber@trash.net> | 2006-10-24 18:34:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-10-24 18:34:00 -0400 |
commit | 2fab22f2d3290ff7c602fe62f22e825c48e97a06 (patch) | |
tree | 1fa429c2efb77c55c6d0dd7ff7fecd60f1505995 | |
parent | 82571026b9771c4035b0c62abbbe588fe73373ea (diff) |
[XFRM]: Fix xfrm_state accounting
xfrm_state_num needs to be increased for XFRM_STATE_ACQ states created
by xfrm_state_find() to prevent the counter from going negative when
the state is destroyed.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/xfrm/xfrm_state.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 84bbf8474f3e..899de9ed22a6 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -505,6 +505,14 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) | |||
505 | x->id.proto, family); | 505 | x->id.proto, family); |
506 | } | 506 | } |
507 | 507 | ||
508 | static void xfrm_hash_grow_check(int have_hash_collision) | ||
509 | { | ||
510 | if (have_hash_collision && | ||
511 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
512 | xfrm_state_num > xfrm_state_hmask) | ||
513 | schedule_work(&xfrm_hash_work); | ||
514 | } | ||
515 | |||
508 | struct xfrm_state * | 516 | struct xfrm_state * |
509 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | 517 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, |
510 | struct flowi *fl, struct xfrm_tmpl *tmpl, | 518 | struct flowi *fl, struct xfrm_tmpl *tmpl, |
@@ -598,6 +606,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
598 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; | 606 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; |
599 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; | 607 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; |
600 | add_timer(&x->timer); | 608 | add_timer(&x->timer); |
609 | xfrm_state_num++; | ||
610 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
601 | } else { | 611 | } else { |
602 | x->km.state = XFRM_STATE_DEAD; | 612 | x->km.state = XFRM_STATE_DEAD; |
603 | xfrm_state_put(x); | 613 | xfrm_state_put(x); |
@@ -614,14 +624,6 @@ out: | |||
614 | return x; | 624 | return x; |
615 | } | 625 | } |
616 | 626 | ||
617 | static void xfrm_hash_grow_check(int have_hash_collision) | ||
618 | { | ||
619 | if (have_hash_collision && | ||
620 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
621 | xfrm_state_num > xfrm_state_hmask) | ||
622 | schedule_work(&xfrm_hash_work); | ||
623 | } | ||
624 | |||
625 | static void __xfrm_state_insert(struct xfrm_state *x) | 627 | static void __xfrm_state_insert(struct xfrm_state *x) |
626 | { | 628 | { |
627 | unsigned int h; | 629 | unsigned int h; |