Skip to content

Commit

Permalink
[XFRM] MIPv6: Fix to input RO state correctly.
Browse files Browse the repository at this point in the history
Disable spin_lock during xfrm_type.input() function.
Follow design as IPsec inbound does.

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Masahide NAKAMURA authored and davem330 committed Jan 28, 2008
1 parent a1b0514 commit 9473e1f
Showing 1 changed file with 29 additions and 25 deletions.
54 changes: 29 additions & 25 deletions net/ipv6/xfrm6_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,26 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
struct xfrm_state *x = NULL;
int wildcard = 0;
xfrm_address_t *xany;
struct xfrm_state *xfrm_vec_one = NULL;
int nh = 0;
int i = 0;

/* Allocate new secpath or COW existing one. */
if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
struct sec_path *sp;

sp = secpath_dup(skb->sp);
if (!sp) {
goto drop;
}
if (skb->sp)
secpath_put(skb->sp);
skb->sp = sp;
}

if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
goto drop;
}

xany = (xfrm_address_t *)&in6addr_any;

for (i = 0; i < 3; i++) {
Expand Down Expand Up @@ -119,47 +135,35 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
continue;
}

spin_unlock(&x->lock);

nh = x->type->input(x, skb);
if (nh <= 0) {
spin_unlock(&x->lock);
xfrm_state_put(x);
x = NULL;
continue;
}

x->curlft.bytes += skb->len;
x->curlft.packets++;

spin_unlock(&x->lock);

xfrm_vec_one = x;
/* Found a state */
break;
}

if (!xfrm_vec_one)
if (!x) {
goto drop;

/* Allocate new secpath or COW existing one. */
if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
struct sec_path *sp;
sp = secpath_dup(skb->sp);
if (!sp)
goto drop;
if (skb->sp)
secpath_put(skb->sp);
skb->sp = sp;
}

if (1 + skb->sp->len > XFRM_MAX_DEPTH)
goto drop;
skb->sp->xvec[skb->sp->len++] = x;

spin_lock(&x->lock);

skb->sp->xvec[skb->sp->len] = xfrm_vec_one;
skb->sp->len ++;
x->curlft.bytes += skb->len;
x->curlft.packets++;

spin_unlock(&x->lock);

return 1;

drop:
if (xfrm_vec_one)
xfrm_state_put(xfrm_vec_one);
return -1;
}

Expand Down

0 comments on commit 9473e1f

Please sign in to comment.