diff options
Diffstat (limited to 'net/xfrm/xfrm_replay.c')
| -rw-r--r-- | net/xfrm/xfrm_replay.c | 15 | 
1 files changed, 15 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 2f6d11d04a2..3efb07d3eb2 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c @@ -420,6 +420,18 @@ err:  	return -EINVAL;  } +static int xfrm_replay_recheck_esn(struct xfrm_state *x, +				   struct sk_buff *skb, __be32 net_seq) +{ +	if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi != +		     htonl(xfrm_replay_seqhi(x, net_seq)))) { +			x->stats.replay_window++; +			return -EINVAL; +	} + +	return xfrm_replay_check_esn(x, skb, net_seq); +} +  static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)  {  	unsigned int bitnr, nr, i; @@ -479,6 +491,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)  static struct xfrm_replay xfrm_replay_legacy = {  	.advance	= xfrm_replay_advance,  	.check		= xfrm_replay_check, +	.recheck	= xfrm_replay_check,  	.notify		= xfrm_replay_notify,  	.overflow	= xfrm_replay_overflow,  }; @@ -486,6 +499,7 @@ static struct xfrm_replay xfrm_replay_legacy = {  static struct xfrm_replay xfrm_replay_bmp = {  	.advance	= xfrm_replay_advance_bmp,  	.check		= xfrm_replay_check_bmp, +	.recheck	= xfrm_replay_check_bmp,  	.notify		= xfrm_replay_notify_bmp,  	.overflow	= xfrm_replay_overflow_bmp,  }; @@ -493,6 +507,7 @@ static struct xfrm_replay xfrm_replay_bmp = {  static struct xfrm_replay xfrm_replay_esn = {  	.advance	= xfrm_replay_advance_esn,  	.check		= xfrm_replay_check_esn, +	.recheck	= xfrm_replay_recheck_esn,  	.notify		= xfrm_replay_notify_bmp,  	.overflow	= xfrm_replay_overflow_esn,  };  |