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; |
