aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_output.c')
-rw-r--r--net/xfrm/xfrm_output.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 64f2ae1fdc15..47bacd8c0250 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -67,17 +67,10 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
67 goto error; 67 goto error;
68 } 68 }
69 69
70 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { 70 err = x->repl->overflow(x, skb);
71 XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq; 71 if (err) {
72 if (unlikely(x->replay.oseq == 0)) { 72 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATESEQERROR);
73 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATESEQERROR); 73 goto error;
74 x->replay.oseq--;
75 xfrm_audit_state_replay_overflow(x, skb);
76 err = -EOVERFLOW;
77 goto error;
78 }
79 if (xfrm_aevent_is_on(net))
80 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
81 } 74 }
82 75
83 x->curlft.bytes += skb->len; 76 x->curlft.bytes += skb->len;
@@ -85,6 +78,8 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
85 78
86 spin_unlock_bh(&x->lock); 79 spin_unlock_bh(&x->lock);
87 80
81 skb_dst_force(skb);
82
88 err = x->type->output(x, skb); 83 err = x->type->output(x, skb);
89 if (err == -EINPROGRESS) 84 if (err == -EINPROGRESS)
90 goto out_exit; 85 goto out_exit;
@@ -101,7 +96,7 @@ resume:
101 err = -EHOSTUNREACH; 96 err = -EHOSTUNREACH;
102 goto error_nolock; 97 goto error_nolock;
103 } 98 }
104 skb_dst_set(skb, dst_clone(dst)); 99 skb_dst_set(skb, dst);
105 x = dst->xfrm; 100 x = dst->xfrm;
106 } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); 101 } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
107 102