2 * xfrm_replay.c - xfrm replay detection, derived from xfrm_state.c.
4 * Copyright (C) 2010 secunet Security Networks AG
5 * Copyright (C) 2010 Steffen Klassert <steffen.klassert@secunet.com>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 #include <linux/export.h>
24 u32
xfrm_replay_seqhi(struct xfrm_state
*x
, __be32 net_seq
)
26 u32 seq
, seq_hi
, bottom
;
27 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
29 if (!(x
->props
.flags
& XFRM_STATE_ESN
))
33 seq_hi
= replay_esn
->seq_hi
;
34 bottom
= replay_esn
->seq
- replay_esn
->replay_window
+ 1;
36 if (likely(replay_esn
->seq
>= replay_esn
->replay_window
- 1)) {
37 /* A. same subspace */
38 if (unlikely(seq
< bottom
))
41 /* B. window spans two subspaces */
42 if (unlikely(seq
>= bottom
))
48 EXPORT_SYMBOL(xfrm_replay_seqhi
);
50 static void xfrm_replay_notify(struct xfrm_state
*x
, int event
)
53 /* we send notify messages in case
54 * 1. we updated on of the sequence numbers, and the seqno difference
55 * is at least x->replay_maxdiff, in this case we also update the
56 * timeout of our timer function
57 * 2. if x->replay_maxage has elapsed since last update,
58 * and there were changes
60 * The state structure must be locked!
64 case XFRM_REPLAY_UPDATE
:
65 if (!x
->replay_maxdiff
||
66 ((x
->replay
.seq
- x
->preplay
.seq
< x
->replay_maxdiff
) &&
67 (x
->replay
.oseq
- x
->preplay
.oseq
< x
->replay_maxdiff
))) {
68 if (x
->xflags
& XFRM_TIME_DEFER
)
69 event
= XFRM_REPLAY_TIMEOUT
;
76 case XFRM_REPLAY_TIMEOUT
:
77 if (memcmp(&x
->replay
, &x
->preplay
,
78 sizeof(struct xfrm_replay_state
)) == 0) {
79 x
->xflags
|= XFRM_TIME_DEFER
;
86 memcpy(&x
->preplay
, &x
->replay
, sizeof(struct xfrm_replay_state
));
87 c
.event
= XFRM_MSG_NEWAE
;
88 c
.data
.aevent
= event
;
89 km_state_notify(x
, &c
);
91 if (x
->replay_maxage
&&
92 !mod_timer(&x
->rtimer
, jiffies
+ x
->replay_maxage
))
93 x
->xflags
&= ~XFRM_TIME_DEFER
;
96 static int xfrm_replay_overflow(struct xfrm_state
*x
, struct sk_buff
*skb
)
99 struct net
*net
= xs_net(x
);
101 if (x
->type
->flags
& XFRM_TYPE_REPLAY_PROT
) {
102 XFRM_SKB_CB(skb
)->seq
.output
.low
= ++x
->replay
.oseq
;
103 XFRM_SKB_CB(skb
)->seq
.output
.hi
= 0;
104 if (unlikely(x
->replay
.oseq
== 0)) {
106 xfrm_audit_state_replay_overflow(x
, skb
);
111 if (xfrm_aevent_is_on(net
))
112 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
118 static int xfrm_replay_check(struct xfrm_state
*x
,
119 struct sk_buff
*skb
, __be32 net_seq
)
122 u32 seq
= ntohl(net_seq
);
124 if (!x
->props
.replay_window
)
127 if (unlikely(seq
== 0))
130 if (likely(seq
> x
->replay
.seq
))
133 diff
= x
->replay
.seq
- seq
;
134 if (diff
>= x
->props
.replay_window
) {
135 x
->stats
.replay_window
++;
139 if (x
->replay
.bitmap
& (1U << diff
)) {
146 xfrm_audit_state_replay(x
, skb
, net_seq
);
150 static void xfrm_replay_advance(struct xfrm_state
*x
, __be32 net_seq
)
153 u32 seq
= ntohl(net_seq
);
155 if (!x
->props
.replay_window
)
158 if (seq
> x
->replay
.seq
) {
159 diff
= seq
- x
->replay
.seq
;
160 if (diff
< x
->props
.replay_window
)
161 x
->replay
.bitmap
= ((x
->replay
.bitmap
) << diff
) | 1;
163 x
->replay
.bitmap
= 1;
166 diff
= x
->replay
.seq
- seq
;
167 x
->replay
.bitmap
|= (1U << diff
);
170 if (xfrm_aevent_is_on(xs_net(x
)))
171 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
174 static int xfrm_replay_overflow_bmp(struct xfrm_state
*x
, struct sk_buff
*skb
)
177 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
178 struct net
*net
= xs_net(x
);
180 if (x
->type
->flags
& XFRM_TYPE_REPLAY_PROT
) {
181 XFRM_SKB_CB(skb
)->seq
.output
.low
= ++replay_esn
->oseq
;
182 XFRM_SKB_CB(skb
)->seq
.output
.hi
= 0;
183 if (unlikely(replay_esn
->oseq
== 0)) {
185 xfrm_audit_state_replay_overflow(x
, skb
);
190 if (xfrm_aevent_is_on(net
))
191 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
197 static int xfrm_replay_check_bmp(struct xfrm_state
*x
,
198 struct sk_buff
*skb
, __be32 net_seq
)
200 unsigned int bitnr
, nr
;
201 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
203 u32 seq
= ntohl(net_seq
);
204 u32 diff
= replay_esn
->seq
- seq
;
206 if (!replay_esn
->replay_window
)
209 if (unlikely(seq
== 0))
212 if (likely(seq
> replay_esn
->seq
))
215 if (diff
>= replay_esn
->replay_window
) {
216 x
->stats
.replay_window
++;
220 pos
= (replay_esn
->seq
- 1) % replay_esn
->replay_window
;
223 bitnr
= (pos
- diff
) % replay_esn
->replay_window
;
225 bitnr
= replay_esn
->replay_window
- (diff
- pos
);
228 bitnr
= bitnr
& 0x1F;
229 if (replay_esn
->bmp
[nr
] & (1U << bitnr
))
237 xfrm_audit_state_replay(x
, skb
, net_seq
);
241 static void xfrm_replay_advance_bmp(struct xfrm_state
*x
, __be32 net_seq
)
243 unsigned int bitnr
, nr
, i
;
245 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
246 u32 seq
= ntohl(net_seq
);
249 if (!replay_esn
->replay_window
)
252 pos
= (replay_esn
->seq
- 1) % replay_esn
->replay_window
;
254 if (seq
> replay_esn
->seq
) {
255 diff
= seq
- replay_esn
->seq
;
257 if (diff
< replay_esn
->replay_window
) {
258 for (i
= 1; i
< diff
; i
++) {
259 bitnr
= (pos
+ i
) % replay_esn
->replay_window
;
261 bitnr
= bitnr
& 0x1F;
262 replay_esn
->bmp
[nr
] &= ~(1U << bitnr
);
265 nr
= (replay_esn
->replay_window
- 1) >> 5;
266 for (i
= 0; i
<= nr
; i
++)
267 replay_esn
->bmp
[i
] = 0;
270 bitnr
= (pos
+ diff
) % replay_esn
->replay_window
;
271 replay_esn
->seq
= seq
;
273 diff
= replay_esn
->seq
- seq
;
276 bitnr
= (pos
- diff
) % replay_esn
->replay_window
;
278 bitnr
= replay_esn
->replay_window
- (diff
- pos
);
282 bitnr
= bitnr
& 0x1F;
283 replay_esn
->bmp
[nr
] |= (1U << bitnr
);
285 if (xfrm_aevent_is_on(xs_net(x
)))
286 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
289 static void xfrm_replay_notify_bmp(struct xfrm_state
*x
, int event
)
292 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
293 struct xfrm_replay_state_esn
*preplay_esn
= x
->preplay_esn
;
295 /* we send notify messages in case
296 * 1. we updated on of the sequence numbers, and the seqno difference
297 * is at least x->replay_maxdiff, in this case we also update the
298 * timeout of our timer function
299 * 2. if x->replay_maxage has elapsed since last update,
300 * and there were changes
302 * The state structure must be locked!
306 case XFRM_REPLAY_UPDATE
:
307 if (!x
->replay_maxdiff
||
308 ((replay_esn
->seq
- preplay_esn
->seq
< x
->replay_maxdiff
) &&
309 (replay_esn
->oseq
- preplay_esn
->oseq
310 < x
->replay_maxdiff
))) {
311 if (x
->xflags
& XFRM_TIME_DEFER
)
312 event
= XFRM_REPLAY_TIMEOUT
;
319 case XFRM_REPLAY_TIMEOUT
:
320 if (memcmp(x
->replay_esn
, x
->preplay_esn
,
321 xfrm_replay_state_esn_len(replay_esn
)) == 0) {
322 x
->xflags
|= XFRM_TIME_DEFER
;
329 memcpy(x
->preplay_esn
, x
->replay_esn
,
330 xfrm_replay_state_esn_len(replay_esn
));
331 c
.event
= XFRM_MSG_NEWAE
;
332 c
.data
.aevent
= event
;
333 km_state_notify(x
, &c
);
335 if (x
->replay_maxage
&&
336 !mod_timer(&x
->rtimer
, jiffies
+ x
->replay_maxage
))
337 x
->xflags
&= ~XFRM_TIME_DEFER
;
340 static void xfrm_replay_notify_esn(struct xfrm_state
*x
, int event
)
342 u32 seq_diff
, oseq_diff
;
344 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
345 struct xfrm_replay_state_esn
*preplay_esn
= x
->preplay_esn
;
347 /* we send notify messages in case
348 * 1. we updated on of the sequence numbers, and the seqno difference
349 * is at least x->replay_maxdiff, in this case we also update the
350 * timeout of our timer function
351 * 2. if x->replay_maxage has elapsed since last update,
352 * and there were changes
354 * The state structure must be locked!
358 case XFRM_REPLAY_UPDATE
:
359 if (x
->replay_maxdiff
) {
360 if (replay_esn
->seq_hi
== preplay_esn
->seq_hi
)
361 seq_diff
= replay_esn
->seq
- preplay_esn
->seq
;
363 seq_diff
= ~preplay_esn
->seq
+ replay_esn
->seq
366 if (replay_esn
->oseq_hi
== preplay_esn
->oseq_hi
)
367 oseq_diff
= replay_esn
->oseq
370 oseq_diff
= ~preplay_esn
->oseq
371 + replay_esn
->oseq
+ 1;
373 if (seq_diff
>= x
->replay_maxdiff
||
374 oseq_diff
>= x
->replay_maxdiff
)
378 if (x
->xflags
& XFRM_TIME_DEFER
)
379 event
= XFRM_REPLAY_TIMEOUT
;
385 case XFRM_REPLAY_TIMEOUT
:
386 if (memcmp(x
->replay_esn
, x
->preplay_esn
,
387 xfrm_replay_state_esn_len(replay_esn
)) == 0) {
388 x
->xflags
|= XFRM_TIME_DEFER
;
395 memcpy(x
->preplay_esn
, x
->replay_esn
,
396 xfrm_replay_state_esn_len(replay_esn
));
397 c
.event
= XFRM_MSG_NEWAE
;
398 c
.data
.aevent
= event
;
399 km_state_notify(x
, &c
);
401 if (x
->replay_maxage
&&
402 !mod_timer(&x
->rtimer
, jiffies
+ x
->replay_maxage
))
403 x
->xflags
&= ~XFRM_TIME_DEFER
;
406 static int xfrm_replay_overflow_esn(struct xfrm_state
*x
, struct sk_buff
*skb
)
409 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
410 struct net
*net
= xs_net(x
);
412 if (x
->type
->flags
& XFRM_TYPE_REPLAY_PROT
) {
413 XFRM_SKB_CB(skb
)->seq
.output
.low
= ++replay_esn
->oseq
;
414 XFRM_SKB_CB(skb
)->seq
.output
.hi
= replay_esn
->oseq_hi
;
416 if (unlikely(replay_esn
->oseq
== 0)) {
417 XFRM_SKB_CB(skb
)->seq
.output
.hi
= ++replay_esn
->oseq_hi
;
419 if (replay_esn
->oseq_hi
== 0) {
421 replay_esn
->oseq_hi
--;
422 xfrm_audit_state_replay_overflow(x
, skb
);
428 if (xfrm_aevent_is_on(net
))
429 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
435 static int xfrm_replay_check_esn(struct xfrm_state
*x
,
436 struct sk_buff
*skb
, __be32 net_seq
)
438 unsigned int bitnr
, nr
;
440 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
442 u32 seq
= ntohl(net_seq
);
443 u32 wsize
= replay_esn
->replay_window
;
444 u32 top
= replay_esn
->seq
;
445 u32 bottom
= top
- wsize
+ 1;
450 if (unlikely(seq
== 0 && replay_esn
->seq_hi
== 0 &&
451 (replay_esn
->seq
< replay_esn
->replay_window
- 1)))
456 if (likely(top
>= wsize
- 1)) {
457 /* A. same subspace */
458 if (likely(seq
> top
) || seq
< bottom
)
461 /* B. window spans two subspaces */
462 if (likely(seq
> top
&& seq
< bottom
))
465 diff
= ~seq
+ top
+ 1;
468 if (diff
>= replay_esn
->replay_window
) {
469 x
->stats
.replay_window
++;
473 pos
= (replay_esn
->seq
- 1) % replay_esn
->replay_window
;
476 bitnr
= (pos
- diff
) % replay_esn
->replay_window
;
478 bitnr
= replay_esn
->replay_window
- (diff
- pos
);
481 bitnr
= bitnr
& 0x1F;
482 if (replay_esn
->bmp
[nr
] & (1U << bitnr
))
490 xfrm_audit_state_replay(x
, skb
, net_seq
);
494 static int xfrm_replay_recheck_esn(struct xfrm_state
*x
,
495 struct sk_buff
*skb
, __be32 net_seq
)
497 if (unlikely(XFRM_SKB_CB(skb
)->seq
.input
.hi
!=
498 htonl(xfrm_replay_seqhi(x
, net_seq
)))) {
499 x
->stats
.replay_window
++;
503 return xfrm_replay_check_esn(x
, skb
, net_seq
);
506 static void xfrm_replay_advance_esn(struct xfrm_state
*x
, __be32 net_seq
)
508 unsigned int bitnr
, nr
, i
;
510 u32 diff
, pos
, seq
, seq_hi
;
511 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
513 if (!replay_esn
->replay_window
)
516 seq
= ntohl(net_seq
);
517 pos
= (replay_esn
->seq
- 1) % replay_esn
->replay_window
;
518 seq_hi
= xfrm_replay_seqhi(x
, net_seq
);
519 wrap
= seq_hi
- replay_esn
->seq_hi
;
521 if ((!wrap
&& seq
> replay_esn
->seq
) || wrap
> 0) {
523 diff
= seq
- replay_esn
->seq
;
525 diff
= ~replay_esn
->seq
+ seq
+ 1;
527 if (diff
< replay_esn
->replay_window
) {
528 for (i
= 1; i
< diff
; i
++) {
529 bitnr
= (pos
+ i
) % replay_esn
->replay_window
;
531 bitnr
= bitnr
& 0x1F;
532 replay_esn
->bmp
[nr
] &= ~(1U << bitnr
);
535 nr
= (replay_esn
->replay_window
- 1) >> 5;
536 for (i
= 0; i
<= nr
; i
++)
537 replay_esn
->bmp
[i
] = 0;
540 bitnr
= (pos
+ diff
) % replay_esn
->replay_window
;
541 replay_esn
->seq
= seq
;
543 if (unlikely(wrap
> 0))
544 replay_esn
->seq_hi
++;
546 diff
= replay_esn
->seq
- seq
;
549 bitnr
= (pos
- diff
) % replay_esn
->replay_window
;
551 bitnr
= replay_esn
->replay_window
- (diff
- pos
);
554 xfrm_dev_state_advance_esn(x
);
557 bitnr
= bitnr
& 0x1F;
558 replay_esn
->bmp
[nr
] |= (1U << bitnr
);
560 if (xfrm_aevent_is_on(xs_net(x
)))
561 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
564 #ifdef CONFIG_XFRM_OFFLOAD
565 static int xfrm_replay_overflow_offload(struct xfrm_state
*x
, struct sk_buff
*skb
)
568 struct net
*net
= xs_net(x
);
569 struct xfrm_offload
*xo
= xfrm_offload(skb
);
570 __u32 oseq
= x
->replay
.oseq
;
573 return xfrm_replay_overflow(x
, skb
);
575 if (x
->type
->flags
& XFRM_TYPE_REPLAY_PROT
) {
576 if (!skb_is_gso(skb
)) {
577 XFRM_SKB_CB(skb
)->seq
.output
.low
= ++oseq
;
580 XFRM_SKB_CB(skb
)->seq
.output
.low
= oseq
+ 1;
581 xo
->seq
.low
= oseq
+ 1;
582 oseq
+= skb_shinfo(skb
)->gso_segs
;
585 XFRM_SKB_CB(skb
)->seq
.output
.hi
= 0;
587 if (unlikely(oseq
< x
->replay
.oseq
)) {
588 xfrm_audit_state_replay_overflow(x
, skb
);
594 x
->replay
.oseq
= oseq
;
596 if (xfrm_aevent_is_on(net
))
597 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
603 static int xfrm_replay_overflow_offload_bmp(struct xfrm_state
*x
, struct sk_buff
*skb
)
606 struct xfrm_offload
*xo
= xfrm_offload(skb
);
607 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
608 struct net
*net
= xs_net(x
);
609 __u32 oseq
= replay_esn
->oseq
;
612 return xfrm_replay_overflow_bmp(x
, skb
);
614 if (x
->type
->flags
& XFRM_TYPE_REPLAY_PROT
) {
615 if (!skb_is_gso(skb
)) {
616 XFRM_SKB_CB(skb
)->seq
.output
.low
= ++oseq
;
619 XFRM_SKB_CB(skb
)->seq
.output
.low
= oseq
+ 1;
620 xo
->seq
.low
= oseq
+ 1;
621 oseq
+= skb_shinfo(skb
)->gso_segs
;
624 XFRM_SKB_CB(skb
)->seq
.output
.hi
= 0;
626 if (unlikely(oseq
< replay_esn
->oseq
)) {
627 xfrm_audit_state_replay_overflow(x
, skb
);
632 replay_esn
->oseq
= oseq
;
635 if (xfrm_aevent_is_on(net
))
636 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
642 static int xfrm_replay_overflow_offload_esn(struct xfrm_state
*x
, struct sk_buff
*skb
)
645 struct xfrm_offload
*xo
= xfrm_offload(skb
);
646 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
647 struct net
*net
= xs_net(x
);
648 __u32 oseq
= replay_esn
->oseq
;
649 __u32 oseq_hi
= replay_esn
->oseq_hi
;
652 return xfrm_replay_overflow_esn(x
, skb
);
654 if (x
->type
->flags
& XFRM_TYPE_REPLAY_PROT
) {
655 if (!skb_is_gso(skb
)) {
656 XFRM_SKB_CB(skb
)->seq
.output
.low
= ++oseq
;
657 XFRM_SKB_CB(skb
)->seq
.output
.hi
= oseq_hi
;
659 xo
->seq
.hi
= oseq_hi
;
661 XFRM_SKB_CB(skb
)->seq
.output
.low
= oseq
+ 1;
662 XFRM_SKB_CB(skb
)->seq
.output
.hi
= oseq_hi
;
663 xo
->seq
.low
= oseq
= oseq
+ 1;
664 xo
->seq
.hi
= oseq_hi
;
665 oseq
+= skb_shinfo(skb
)->gso_segs
;
668 if (unlikely(oseq
< replay_esn
->oseq
)) {
669 XFRM_SKB_CB(skb
)->seq
.output
.hi
= ++oseq_hi
;
670 xo
->seq
.hi
= oseq_hi
;
671 replay_esn
->oseq_hi
= oseq_hi
;
672 if (replay_esn
->oseq_hi
== 0) {
674 replay_esn
->oseq_hi
--;
675 xfrm_audit_state_replay_overflow(x
, skb
);
682 replay_esn
->oseq
= oseq
;
684 if (xfrm_aevent_is_on(net
))
685 x
->repl
->notify(x
, XFRM_REPLAY_UPDATE
);
691 static const struct xfrm_replay xfrm_replay_legacy
= {
692 .advance
= xfrm_replay_advance
,
693 .check
= xfrm_replay_check
,
694 .recheck
= xfrm_replay_check
,
695 .notify
= xfrm_replay_notify
,
696 .overflow
= xfrm_replay_overflow_offload
,
699 static const struct xfrm_replay xfrm_replay_bmp
= {
700 .advance
= xfrm_replay_advance_bmp
,
701 .check
= xfrm_replay_check_bmp
,
702 .recheck
= xfrm_replay_check_bmp
,
703 .notify
= xfrm_replay_notify_bmp
,
704 .overflow
= xfrm_replay_overflow_offload_bmp
,
707 static const struct xfrm_replay xfrm_replay_esn
= {
708 .advance
= xfrm_replay_advance_esn
,
709 .check
= xfrm_replay_check_esn
,
710 .recheck
= xfrm_replay_recheck_esn
,
711 .notify
= xfrm_replay_notify_esn
,
712 .overflow
= xfrm_replay_overflow_offload_esn
,
715 static const struct xfrm_replay xfrm_replay_legacy
= {
716 .advance
= xfrm_replay_advance
,
717 .check
= xfrm_replay_check
,
718 .recheck
= xfrm_replay_check
,
719 .notify
= xfrm_replay_notify
,
720 .overflow
= xfrm_replay_overflow
,
723 static const struct xfrm_replay xfrm_replay_bmp
= {
724 .advance
= xfrm_replay_advance_bmp
,
725 .check
= xfrm_replay_check_bmp
,
726 .recheck
= xfrm_replay_check_bmp
,
727 .notify
= xfrm_replay_notify_bmp
,
728 .overflow
= xfrm_replay_overflow_bmp
,
731 static const struct xfrm_replay xfrm_replay_esn
= {
732 .advance
= xfrm_replay_advance_esn
,
733 .check
= xfrm_replay_check_esn
,
734 .recheck
= xfrm_replay_recheck_esn
,
735 .notify
= xfrm_replay_notify_esn
,
736 .overflow
= xfrm_replay_overflow_esn
,
740 int xfrm_init_replay(struct xfrm_state
*x
)
742 struct xfrm_replay_state_esn
*replay_esn
= x
->replay_esn
;
745 if (replay_esn
->replay_window
>
746 replay_esn
->bmp_len
* sizeof(__u32
) * 8)
749 if (x
->props
.flags
& XFRM_STATE_ESN
) {
750 if (replay_esn
->replay_window
== 0)
752 x
->repl
= &xfrm_replay_esn
;
754 x
->repl
= &xfrm_replay_bmp
;
757 x
->repl
= &xfrm_replay_legacy
;
762 EXPORT_SYMBOL(xfrm_init_replay
);