X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fxfrm%2Fxfrm_state.c;h=160bb617d7ebfc042cfe5d732a6f3cc42738487d;hb=73c4d347a0c98eb6599aefd1f9a91b4b071dd5e0;hp=f45fa55c2c6c57f429bed827540c7a4a07c6d593;hpb=a91482bdcc2e0f6035702e46f1b99043a0893346;p=linux-2.6.git diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index f45fa55c2..160bb617d 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -65,6 +65,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) xfrm_put_type(x->type); } kfree(x); + wake_up(&km_waitq); } static void xfrm_state_gc_task(void *data) @@ -81,7 +82,6 @@ static void xfrm_state_gc_task(void *data) x = list_entry(entry, struct xfrm_state, bydst); xfrm_state_gc_destroy(x); } - wake_up(&km_waitq); } static inline unsigned long make_jiffies(long secs) @@ -400,17 +400,23 @@ int xfrm_state_add(struct xfrm_state *x) spin_lock_bh(&xfrm_state_lock); x1 = afinfo->state_lookup(&x->id.daddr, x->id.spi, x->id.proto); - if (x1) { + if (!x1) { + x1 = afinfo->find_acq( + x->props.mode, x->props.reqid, x->id.proto, + &x->id.daddr, &x->props.saddr, 0); + if (x1 && x1->id.spi != x->id.spi && x1->id.spi) { + xfrm_state_put(x1); + x1 = NULL; + } + } + + if (x1 && x1->id.spi) { xfrm_state_put(x1); x1 = NULL; err = -EEXIST; goto out; } - x1 = afinfo->find_acq( - x->props.mode, x->props.reqid, x->id.proto, - &x->id.daddr, &x->props.saddr, 0); - __xfrm_state_insert(x); err = 0; @@ -624,12 +630,11 @@ xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi) for (h=0; hid.daddr, htonl(spi), x->id.proto, x->props.family); - if (x0 == NULL) { - x->id.spi = htonl(spi); + if (x0 == NULL) break; - } xfrm_state_put(x0); } + x->id.spi = htonl(spi); } if (x->id.spi) { spin_lock_bh(&xfrm_state_lock);