summaryrefslogtreecommitdiff
path: root/net/xfrm/xfrm_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_input.c')
-rw-r--r--net/xfrm/xfrm_input.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index c9ddef869aa5..257935cbd221 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -505,6 +505,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
async = 1;
dev_put(skb->dev);
seq = XFRM_SKB_CB(skb)->seq.input.low;
+ spin_lock(&x->lock);
goto resume;
}
/* GRO call */
@@ -541,6 +542,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
goto drop;
}
+
+ nexthdr = x->type_offload->input_tail(x, skb);
}
goto lock;
@@ -638,11 +641,9 @@ lock:
goto drop_unlock;
}
- spin_unlock(&x->lock);
-
if (xfrm_tunnel_check(skb, x, family)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
- goto drop;
+ goto drop_unlock;
}
seq_hi = htonl(xfrm_replay_seqhi(x, seq));
@@ -650,9 +651,8 @@ lock:
XFRM_SKB_CB(skb)->seq.input.low = seq;
XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
- if (crypto_done) {
- nexthdr = x->type_offload->input_tail(x, skb);
- } else {
+ if (!crypto_done) {
+ spin_unlock(&x->lock);
dev_hold(skb->dev);
nexthdr = x->type->input(x, skb);
@@ -660,9 +660,9 @@ lock:
return 0;
dev_put(skb->dev);
+ spin_lock(&x->lock);
}
resume:
- spin_lock(&x->lock);
if (nexthdr < 0) {
if (nexthdr == -EBADMSG) {
xfrm_audit_state_icvfail(x, skb,