xref: /openbmc/linux/net/xfrm/xfrm_replay.c (revision c7f87783)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * xfrm_replay.c - xfrm replay detection, derived from xfrm_state.c.
4  *
5  * Copyright (C) 2010 secunet Security Networks AG
6  * Copyright (C) 2010 Steffen Klassert <steffen.klassert@secunet.com>
7  */
8 
9 #include <linux/export.h>
10 #include <net/xfrm.h>
11 
12 u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq)
13 {
14 	u32 seq, seq_hi, bottom;
15 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
16 
17 	if (!(x->props.flags & XFRM_STATE_ESN))
18 		return 0;
19 
20 	seq = ntohl(net_seq);
21 	seq_hi = replay_esn->seq_hi;
22 	bottom = replay_esn->seq - replay_esn->replay_window + 1;
23 
24 	if (likely(replay_esn->seq >= replay_esn->replay_window - 1)) {
25 		/* A. same subspace */
26 		if (unlikely(seq < bottom))
27 			seq_hi++;
28 	} else {
29 		/* B. window spans two subspaces */
30 		if (unlikely(seq >= bottom))
31 			seq_hi--;
32 	}
33 
34 	return seq_hi;
35 }
36 EXPORT_SYMBOL(xfrm_replay_seqhi);
37 
38 static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event);
39 static void xfrm_replay_notify_esn(struct xfrm_state *x, int event);
40 
41 void xfrm_replay_notify(struct xfrm_state *x, int event)
42 {
43 	struct km_event c;
44 	/* we send notify messages in case
45 	 *  1. we updated on of the sequence numbers, and the seqno difference
46 	 *     is at least x->replay_maxdiff, in this case we also update the
47 	 *     timeout of our timer function
48 	 *  2. if x->replay_maxage has elapsed since last update,
49 	 *     and there were changes
50 	 *
51 	 *  The state structure must be locked!
52 	 */
53 
54 	switch (x->repl_mode) {
55 	case XFRM_REPLAY_MODE_LEGACY:
56 		break;
57 	case XFRM_REPLAY_MODE_BMP:
58 		xfrm_replay_notify_bmp(x, event);
59 		return;
60 	case XFRM_REPLAY_MODE_ESN:
61 		xfrm_replay_notify_esn(x, event);
62 		return;
63 	}
64 
65 	switch (event) {
66 	case XFRM_REPLAY_UPDATE:
67 		if (!x->replay_maxdiff ||
68 		    ((x->replay.seq - x->preplay.seq < x->replay_maxdiff) &&
69 		    (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))) {
70 			if (x->xflags & XFRM_TIME_DEFER)
71 				event = XFRM_REPLAY_TIMEOUT;
72 			else
73 				return;
74 		}
75 
76 		break;
77 
78 	case XFRM_REPLAY_TIMEOUT:
79 		if (memcmp(&x->replay, &x->preplay,
80 			   sizeof(struct xfrm_replay_state)) == 0) {
81 			x->xflags |= XFRM_TIME_DEFER;
82 			return;
83 		}
84 
85 		break;
86 	}
87 
88 	memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state));
89 	c.event = XFRM_MSG_NEWAE;
90 	c.data.aevent = event;
91 	km_state_notify(x, &c);
92 
93 	if (x->replay_maxage &&
94 	    !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
95 		x->xflags &= ~XFRM_TIME_DEFER;
96 }
97 
98 static int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
99 {
100 	int err = 0;
101 	struct net *net = xs_net(x);
102 
103 	if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
104 		XFRM_SKB_CB(skb)->seq.output.low = ++x->replay.oseq;
105 		XFRM_SKB_CB(skb)->seq.output.hi = 0;
106 		if (unlikely(x->replay.oseq == 0) &&
107 		    !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
108 			x->replay.oseq--;
109 			xfrm_audit_state_replay_overflow(x, skb);
110 			err = -EOVERFLOW;
111 
112 			return err;
113 		}
114 		if (xfrm_aevent_is_on(net))
115 			xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
116 	}
117 
118 	return err;
119 }
120 
121 static int xfrm_replay_check(struct xfrm_state *x,
122 		      struct sk_buff *skb, __be32 net_seq)
123 {
124 	u32 diff;
125 	u32 seq = ntohl(net_seq);
126 
127 	if (!x->props.replay_window)
128 		return 0;
129 
130 	if (unlikely(seq == 0))
131 		goto err;
132 
133 	if (likely(seq > x->replay.seq))
134 		return 0;
135 
136 	diff = x->replay.seq - seq;
137 	if (diff >= x->props.replay_window) {
138 		x->stats.replay_window++;
139 		goto err;
140 	}
141 
142 	if (x->replay.bitmap & (1U << diff)) {
143 		x->stats.replay++;
144 		goto err;
145 	}
146 	return 0;
147 
148 err:
149 	xfrm_audit_state_replay(x, skb, net_seq);
150 	return -EINVAL;
151 }
152 
153 static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq);
154 static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq);
155 
156 void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
157 {
158 	u32 diff, seq;
159 
160 	switch (x->repl_mode) {
161 	case XFRM_REPLAY_MODE_LEGACY:
162 		break;
163 	case XFRM_REPLAY_MODE_BMP:
164 		return xfrm_replay_advance_bmp(x, net_seq);
165 	case XFRM_REPLAY_MODE_ESN:
166 		return xfrm_replay_advance_esn(x, net_seq);
167 	}
168 
169 	if (!x->props.replay_window)
170 		return;
171 
172 	seq = ntohl(net_seq);
173 	if (seq > x->replay.seq) {
174 		diff = seq - x->replay.seq;
175 		if (diff < x->props.replay_window)
176 			x->replay.bitmap = ((x->replay.bitmap) << diff) | 1;
177 		else
178 			x->replay.bitmap = 1;
179 		x->replay.seq = seq;
180 	} else {
181 		diff = x->replay.seq - seq;
182 		x->replay.bitmap |= (1U << diff);
183 	}
184 
185 	if (xfrm_aevent_is_on(xs_net(x)))
186 		xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
187 }
188 
189 static int xfrm_replay_overflow_bmp(struct xfrm_state *x, struct sk_buff *skb)
190 {
191 	int err = 0;
192 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
193 	struct net *net = xs_net(x);
194 
195 	if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
196 		XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
197 		XFRM_SKB_CB(skb)->seq.output.hi = 0;
198 		if (unlikely(replay_esn->oseq == 0) &&
199 		    !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
200 			replay_esn->oseq--;
201 			xfrm_audit_state_replay_overflow(x, skb);
202 			err = -EOVERFLOW;
203 
204 			return err;
205 		}
206 		if (xfrm_aevent_is_on(net))
207 			xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
208 	}
209 
210 	return err;
211 }
212 
213 static int xfrm_replay_check_bmp(struct xfrm_state *x,
214 				 struct sk_buff *skb, __be32 net_seq)
215 {
216 	unsigned int bitnr, nr;
217 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
218 	u32 pos;
219 	u32 seq = ntohl(net_seq);
220 	u32 diff =  replay_esn->seq - seq;
221 
222 	if (!replay_esn->replay_window)
223 		return 0;
224 
225 	if (unlikely(seq == 0))
226 		goto err;
227 
228 	if (likely(seq > replay_esn->seq))
229 		return 0;
230 
231 	if (diff >= replay_esn->replay_window) {
232 		x->stats.replay_window++;
233 		goto err;
234 	}
235 
236 	pos = (replay_esn->seq - 1) % replay_esn->replay_window;
237 
238 	if (pos >= diff)
239 		bitnr = (pos - diff) % replay_esn->replay_window;
240 	else
241 		bitnr = replay_esn->replay_window - (diff - pos);
242 
243 	nr = bitnr >> 5;
244 	bitnr = bitnr & 0x1F;
245 	if (replay_esn->bmp[nr] & (1U << bitnr))
246 		goto err_replay;
247 
248 	return 0;
249 
250 err_replay:
251 	x->stats.replay++;
252 err:
253 	xfrm_audit_state_replay(x, skb, net_seq);
254 	return -EINVAL;
255 }
256 
257 static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq)
258 {
259 	unsigned int bitnr, nr, i;
260 	u32 diff;
261 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
262 	u32 seq = ntohl(net_seq);
263 	u32 pos;
264 
265 	if (!replay_esn->replay_window)
266 		return;
267 
268 	pos = (replay_esn->seq - 1) % replay_esn->replay_window;
269 
270 	if (seq > replay_esn->seq) {
271 		diff = seq - replay_esn->seq;
272 
273 		if (diff < replay_esn->replay_window) {
274 			for (i = 1; i < diff; i++) {
275 				bitnr = (pos + i) % replay_esn->replay_window;
276 				nr = bitnr >> 5;
277 				bitnr = bitnr & 0x1F;
278 				replay_esn->bmp[nr] &=  ~(1U << bitnr);
279 			}
280 		} else {
281 			nr = (replay_esn->replay_window - 1) >> 5;
282 			for (i = 0; i <= nr; i++)
283 				replay_esn->bmp[i] = 0;
284 		}
285 
286 		bitnr = (pos + diff) % replay_esn->replay_window;
287 		replay_esn->seq = seq;
288 	} else {
289 		diff = replay_esn->seq - seq;
290 
291 		if (pos >= diff)
292 			bitnr = (pos - diff) % replay_esn->replay_window;
293 		else
294 			bitnr = replay_esn->replay_window - (diff - pos);
295 	}
296 
297 	nr = bitnr >> 5;
298 	bitnr = bitnr & 0x1F;
299 	replay_esn->bmp[nr] |= (1U << bitnr);
300 
301 	if (xfrm_aevent_is_on(xs_net(x)))
302 		xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
303 }
304 
305 static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
306 {
307 	struct km_event c;
308 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
309 	struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn;
310 
311 	/* we send notify messages in case
312 	 *  1. we updated on of the sequence numbers, and the seqno difference
313 	 *     is at least x->replay_maxdiff, in this case we also update the
314 	 *     timeout of our timer function
315 	 *  2. if x->replay_maxage has elapsed since last update,
316 	 *     and there were changes
317 	 *
318 	 *  The state structure must be locked!
319 	 */
320 
321 	switch (event) {
322 	case XFRM_REPLAY_UPDATE:
323 		if (!x->replay_maxdiff ||
324 		    ((replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) &&
325 		    (replay_esn->oseq - preplay_esn->oseq
326 		     < x->replay_maxdiff))) {
327 			if (x->xflags & XFRM_TIME_DEFER)
328 				event = XFRM_REPLAY_TIMEOUT;
329 			else
330 				return;
331 		}
332 
333 		break;
334 
335 	case XFRM_REPLAY_TIMEOUT:
336 		if (memcmp(x->replay_esn, x->preplay_esn,
337 			   xfrm_replay_state_esn_len(replay_esn)) == 0) {
338 			x->xflags |= XFRM_TIME_DEFER;
339 			return;
340 		}
341 
342 		break;
343 	}
344 
345 	memcpy(x->preplay_esn, x->replay_esn,
346 	       xfrm_replay_state_esn_len(replay_esn));
347 	c.event = XFRM_MSG_NEWAE;
348 	c.data.aevent = event;
349 	km_state_notify(x, &c);
350 
351 	if (x->replay_maxage &&
352 	    !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
353 		x->xflags &= ~XFRM_TIME_DEFER;
354 }
355 
356 static void xfrm_replay_notify_esn(struct xfrm_state *x, int event)
357 {
358 	u32 seq_diff, oseq_diff;
359 	struct km_event c;
360 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
361 	struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn;
362 
363 	/* we send notify messages in case
364 	 *  1. we updated on of the sequence numbers, and the seqno difference
365 	 *     is at least x->replay_maxdiff, in this case we also update the
366 	 *     timeout of our timer function
367 	 *  2. if x->replay_maxage has elapsed since last update,
368 	 *     and there were changes
369 	 *
370 	 *  The state structure must be locked!
371 	 */
372 
373 	switch (event) {
374 	case XFRM_REPLAY_UPDATE:
375 		if (x->replay_maxdiff) {
376 			if (replay_esn->seq_hi == preplay_esn->seq_hi)
377 				seq_diff = replay_esn->seq - preplay_esn->seq;
378 			else
379 				seq_diff = ~preplay_esn->seq + replay_esn->seq
380 					   + 1;
381 
382 			if (replay_esn->oseq_hi == preplay_esn->oseq_hi)
383 				oseq_diff = replay_esn->oseq
384 					    - preplay_esn->oseq;
385 			else
386 				oseq_diff = ~preplay_esn->oseq
387 					    + replay_esn->oseq + 1;
388 
389 			if (seq_diff >= x->replay_maxdiff ||
390 			    oseq_diff >= x->replay_maxdiff)
391 				break;
392 		}
393 
394 		if (x->xflags & XFRM_TIME_DEFER)
395 			event = XFRM_REPLAY_TIMEOUT;
396 		else
397 			return;
398 
399 		break;
400 
401 	case XFRM_REPLAY_TIMEOUT:
402 		if (memcmp(x->replay_esn, x->preplay_esn,
403 			   xfrm_replay_state_esn_len(replay_esn)) == 0) {
404 			x->xflags |= XFRM_TIME_DEFER;
405 			return;
406 		}
407 
408 		break;
409 	}
410 
411 	memcpy(x->preplay_esn, x->replay_esn,
412 	       xfrm_replay_state_esn_len(replay_esn));
413 	c.event = XFRM_MSG_NEWAE;
414 	c.data.aevent = event;
415 	km_state_notify(x, &c);
416 
417 	if (x->replay_maxage &&
418 	    !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
419 		x->xflags &= ~XFRM_TIME_DEFER;
420 }
421 
422 static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb)
423 {
424 	int err = 0;
425 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
426 	struct net *net = xs_net(x);
427 
428 	if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
429 		XFRM_SKB_CB(skb)->seq.output.low = ++replay_esn->oseq;
430 		XFRM_SKB_CB(skb)->seq.output.hi = replay_esn->oseq_hi;
431 
432 		if (unlikely(replay_esn->oseq == 0)) {
433 			XFRM_SKB_CB(skb)->seq.output.hi = ++replay_esn->oseq_hi;
434 
435 			if (replay_esn->oseq_hi == 0) {
436 				replay_esn->oseq--;
437 				replay_esn->oseq_hi--;
438 				xfrm_audit_state_replay_overflow(x, skb);
439 				err = -EOVERFLOW;
440 
441 				return err;
442 			}
443 		}
444 		if (xfrm_aevent_is_on(net))
445 			xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
446 	}
447 
448 	return err;
449 }
450 
451 static int xfrm_replay_check_esn(struct xfrm_state *x,
452 				 struct sk_buff *skb, __be32 net_seq)
453 {
454 	unsigned int bitnr, nr;
455 	u32 diff;
456 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
457 	u32 pos;
458 	u32 seq = ntohl(net_seq);
459 	u32 wsize = replay_esn->replay_window;
460 	u32 top = replay_esn->seq;
461 	u32 bottom = top - wsize + 1;
462 
463 	if (!wsize)
464 		return 0;
465 
466 	if (unlikely(seq == 0 && replay_esn->seq_hi == 0 &&
467 		     (replay_esn->seq < replay_esn->replay_window - 1)))
468 		goto err;
469 
470 	diff = top - seq;
471 
472 	if (likely(top >= wsize - 1)) {
473 		/* A. same subspace */
474 		if (likely(seq > top) || seq < bottom)
475 			return 0;
476 	} else {
477 		/* B. window spans two subspaces */
478 		if (likely(seq > top && seq < bottom))
479 			return 0;
480 		if (seq >= bottom)
481 			diff = ~seq + top + 1;
482 	}
483 
484 	if (diff >= replay_esn->replay_window) {
485 		x->stats.replay_window++;
486 		goto err;
487 	}
488 
489 	pos = (replay_esn->seq - 1) % replay_esn->replay_window;
490 
491 	if (pos >= diff)
492 		bitnr = (pos - diff) % replay_esn->replay_window;
493 	else
494 		bitnr = replay_esn->replay_window - (diff - pos);
495 
496 	nr = bitnr >> 5;
497 	bitnr = bitnr & 0x1F;
498 	if (replay_esn->bmp[nr] & (1U << bitnr))
499 		goto err_replay;
500 
501 	return 0;
502 
503 err_replay:
504 	x->stats.replay++;
505 err:
506 	xfrm_audit_state_replay(x, skb, net_seq);
507 	return -EINVAL;
508 }
509 
510 static int xfrm_replay_recheck_esn(struct xfrm_state *x,
511 				   struct sk_buff *skb, __be32 net_seq)
512 {
513 	if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi !=
514 		     htonl(xfrm_replay_seqhi(x, net_seq)))) {
515 			x->stats.replay_window++;
516 			return -EINVAL;
517 	}
518 
519 	return xfrm_replay_check_esn(x, skb, net_seq);
520 }
521 
522 static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
523 {
524 	unsigned int bitnr, nr, i;
525 	int wrap;
526 	u32 diff, pos, seq, seq_hi;
527 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
528 
529 	if (!replay_esn->replay_window)
530 		return;
531 
532 	seq = ntohl(net_seq);
533 	pos = (replay_esn->seq - 1) % replay_esn->replay_window;
534 	seq_hi = xfrm_replay_seqhi(x, net_seq);
535 	wrap = seq_hi - replay_esn->seq_hi;
536 
537 	if ((!wrap && seq > replay_esn->seq) || wrap > 0) {
538 		if (likely(!wrap))
539 			diff = seq - replay_esn->seq;
540 		else
541 			diff = ~replay_esn->seq + seq + 1;
542 
543 		if (diff < replay_esn->replay_window) {
544 			for (i = 1; i < diff; i++) {
545 				bitnr = (pos + i) % replay_esn->replay_window;
546 				nr = bitnr >> 5;
547 				bitnr = bitnr & 0x1F;
548 				replay_esn->bmp[nr] &=  ~(1U << bitnr);
549 			}
550 		} else {
551 			nr = (replay_esn->replay_window - 1) >> 5;
552 			for (i = 0; i <= nr; i++)
553 				replay_esn->bmp[i] = 0;
554 		}
555 
556 		bitnr = (pos + diff) % replay_esn->replay_window;
557 		replay_esn->seq = seq;
558 
559 		if (unlikely(wrap > 0))
560 			replay_esn->seq_hi++;
561 	} else {
562 		diff = replay_esn->seq - seq;
563 
564 		if (pos >= diff)
565 			bitnr = (pos - diff) % replay_esn->replay_window;
566 		else
567 			bitnr = replay_esn->replay_window - (diff - pos);
568 	}
569 
570 	xfrm_dev_state_advance_esn(x);
571 
572 	nr = bitnr >> 5;
573 	bitnr = bitnr & 0x1F;
574 	replay_esn->bmp[nr] |= (1U << bitnr);
575 
576 	if (xfrm_aevent_is_on(xs_net(x)))
577 		xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
578 }
579 
580 #ifdef CONFIG_XFRM_OFFLOAD
581 static int xfrm_replay_overflow_offload(struct xfrm_state *x, struct sk_buff *skb)
582 {
583 	int err = 0;
584 	struct net *net = xs_net(x);
585 	struct xfrm_offload *xo = xfrm_offload(skb);
586 	__u32 oseq = x->replay.oseq;
587 
588 	if (!xo)
589 		return xfrm_replay_overflow(x, skb);
590 
591 	if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
592 		if (!skb_is_gso(skb)) {
593 			XFRM_SKB_CB(skb)->seq.output.low = ++oseq;
594 			xo->seq.low = oseq;
595 		} else {
596 			XFRM_SKB_CB(skb)->seq.output.low = oseq + 1;
597 			xo->seq.low = oseq + 1;
598 			oseq += skb_shinfo(skb)->gso_segs;
599 		}
600 
601 		XFRM_SKB_CB(skb)->seq.output.hi = 0;
602 		xo->seq.hi = 0;
603 		if (unlikely(oseq < x->replay.oseq) &&
604 		    !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
605 			xfrm_audit_state_replay_overflow(x, skb);
606 			err = -EOVERFLOW;
607 
608 			return err;
609 		}
610 
611 		x->replay.oseq = oseq;
612 
613 		if (xfrm_aevent_is_on(net))
614 			xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
615 	}
616 
617 	return err;
618 }
619 
620 static int xfrm_replay_overflow_offload_bmp(struct xfrm_state *x, struct sk_buff *skb)
621 {
622 	int err = 0;
623 	struct xfrm_offload *xo = xfrm_offload(skb);
624 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
625 	struct net *net = xs_net(x);
626 	__u32 oseq = replay_esn->oseq;
627 
628 	if (!xo)
629 		return xfrm_replay_overflow_bmp(x, skb);
630 
631 	if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
632 		if (!skb_is_gso(skb)) {
633 			XFRM_SKB_CB(skb)->seq.output.low = ++oseq;
634 			xo->seq.low = oseq;
635 		} else {
636 			XFRM_SKB_CB(skb)->seq.output.low = oseq + 1;
637 			xo->seq.low = oseq + 1;
638 			oseq += skb_shinfo(skb)->gso_segs;
639 		}
640 
641 		XFRM_SKB_CB(skb)->seq.output.hi = 0;
642 		xo->seq.hi = 0;
643 		if (unlikely(oseq < replay_esn->oseq) &&
644 		    !(x->props.extra_flags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP)) {
645 			xfrm_audit_state_replay_overflow(x, skb);
646 			err = -EOVERFLOW;
647 
648 			return err;
649 		} else {
650 			replay_esn->oseq = oseq;
651 		}
652 
653 		if (xfrm_aevent_is_on(net))
654 			xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
655 	}
656 
657 	return err;
658 }
659 
660 static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff *skb)
661 {
662 	int err = 0;
663 	struct xfrm_offload *xo = xfrm_offload(skb);
664 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
665 	struct net *net = xs_net(x);
666 	__u32 oseq = replay_esn->oseq;
667 	__u32 oseq_hi = replay_esn->oseq_hi;
668 
669 	if (!xo)
670 		return xfrm_replay_overflow_esn(x, skb);
671 
672 	if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
673 		if (!skb_is_gso(skb)) {
674 			XFRM_SKB_CB(skb)->seq.output.low = ++oseq;
675 			XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi;
676 			xo->seq.low = oseq;
677 			xo->seq.hi = oseq_hi;
678 		} else {
679 			XFRM_SKB_CB(skb)->seq.output.low = oseq + 1;
680 			XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi;
681 			xo->seq.low = oseq + 1;
682 			xo->seq.hi = oseq_hi;
683 			oseq += skb_shinfo(skb)->gso_segs;
684 		}
685 
686 		if (unlikely(oseq < replay_esn->oseq)) {
687 			XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi;
688 			xo->seq.hi = oseq_hi;
689 			replay_esn->oseq_hi = oseq_hi;
690 			if (replay_esn->oseq_hi == 0) {
691 				replay_esn->oseq--;
692 				replay_esn->oseq_hi--;
693 				xfrm_audit_state_replay_overflow(x, skb);
694 				err = -EOVERFLOW;
695 
696 				return err;
697 			}
698 		}
699 
700 		replay_esn->oseq = oseq;
701 
702 		if (xfrm_aevent_is_on(net))
703 			xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
704 	}
705 
706 	return err;
707 }
708 
709 static const struct xfrm_replay xfrm_replay_legacy = {
710 	.check		= xfrm_replay_check,
711 	.recheck	= xfrm_replay_check,
712 	.overflow	= xfrm_replay_overflow_offload,
713 };
714 
715 static const struct xfrm_replay xfrm_replay_bmp = {
716 	.check		= xfrm_replay_check_bmp,
717 	.recheck	= xfrm_replay_check_bmp,
718 	.overflow	= xfrm_replay_overflow_offload_bmp,
719 };
720 
721 static const struct xfrm_replay xfrm_replay_esn = {
722 	.check		= xfrm_replay_check_esn,
723 	.recheck	= xfrm_replay_recheck_esn,
724 	.overflow	= xfrm_replay_overflow_offload_esn,
725 };
726 #else
727 static const struct xfrm_replay xfrm_replay_legacy = {
728 	.check		= xfrm_replay_check,
729 	.recheck	= xfrm_replay_check,
730 	.overflow	= xfrm_replay_overflow,
731 };
732 
733 static const struct xfrm_replay xfrm_replay_bmp = {
734 	.check		= xfrm_replay_check_bmp,
735 	.recheck	= xfrm_replay_check_bmp,
736 	.overflow	= xfrm_replay_overflow_bmp,
737 };
738 
739 static const struct xfrm_replay xfrm_replay_esn = {
740 	.check		= xfrm_replay_check_esn,
741 	.recheck	= xfrm_replay_recheck_esn,
742 	.overflow	= xfrm_replay_overflow_esn,
743 };
744 #endif
745 
746 int xfrm_init_replay(struct xfrm_state *x)
747 {
748 	struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
749 
750 	if (replay_esn) {
751 		if (replay_esn->replay_window >
752 		    replay_esn->bmp_len * sizeof(__u32) * 8)
753 			return -EINVAL;
754 
755 		if (x->props.flags & XFRM_STATE_ESN) {
756 			if (replay_esn->replay_window == 0)
757 				return -EINVAL;
758 			x->repl = &xfrm_replay_esn;
759 			x->repl_mode = XFRM_REPLAY_MODE_ESN;
760 		} else {
761 			x->repl = &xfrm_replay_bmp;
762 			x->repl_mode = XFRM_REPLAY_MODE_BMP;
763 		}
764 	} else {
765 		x->repl = &xfrm_replay_legacy;
766 		x->repl_mode = XFRM_REPLAY_MODE_LEGACY;
767 	}
768 
769 	return 0;
770 }
771 EXPORT_SYMBOL(xfrm_init_replay);
772