aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_replay.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_replay.c')
-rw-r--r--net/xfrm/xfrm_replay.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 8dafe6d3c6e4..dab57daae408 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -61,9 +61,9 @@ static void xfrm_replay_notify(struct xfrm_state *x, int event)
61 61
62 switch (event) { 62 switch (event) {
63 case XFRM_REPLAY_UPDATE: 63 case XFRM_REPLAY_UPDATE:
64 if (x->replay_maxdiff && 64 if (!x->replay_maxdiff ||
65 (x->replay.seq - x->preplay.seq < x->replay_maxdiff) && 65 ((x->replay.seq - x->preplay.seq < x->replay_maxdiff) &&
66 (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff)) { 66 (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))) {
67 if (x->xflags & XFRM_TIME_DEFER) 67 if (x->xflags & XFRM_TIME_DEFER)
68 event = XFRM_REPLAY_TIMEOUT; 68 event = XFRM_REPLAY_TIMEOUT;
69 else 69 else
@@ -129,8 +129,7 @@ static int xfrm_replay_check(struct xfrm_state *x,
129 return 0; 129 return 0;
130 130
131 diff = x->replay.seq - seq; 131 diff = x->replay.seq - seq;
132 if (diff >= min_t(unsigned int, x->props.replay_window, 132 if (diff >= x->props.replay_window) {
133 sizeof(x->replay.bitmap) * 8)) {
134 x->stats.replay_window++; 133 x->stats.replay_window++;
135 goto err; 134 goto err;
136 } 135 }
@@ -302,9 +301,10 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
302 301
303 switch (event) { 302 switch (event) {
304 case XFRM_REPLAY_UPDATE: 303 case XFRM_REPLAY_UPDATE:
305 if (x->replay_maxdiff && 304 if (!x->replay_maxdiff ||
306 (replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) && 305 ((replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) &&
307 (replay_esn->oseq - preplay_esn->oseq < x->replay_maxdiff)) { 306 (replay_esn->oseq - preplay_esn->oseq
307 < x->replay_maxdiff))) {
308 if (x->xflags & XFRM_TIME_DEFER) 308 if (x->xflags & XFRM_TIME_DEFER)
309 event = XFRM_REPLAY_TIMEOUT; 309 event = XFRM_REPLAY_TIMEOUT;
310 else 310 else
@@ -353,28 +353,30 @@ static void xfrm_replay_notify_esn(struct xfrm_state *x, int event)
353 353
354 switch (event) { 354 switch (event) {
355 case XFRM_REPLAY_UPDATE: 355 case XFRM_REPLAY_UPDATE:
356 if (!x->replay_maxdiff) 356 if (x->replay_maxdiff) {
357 break; 357 if (replay_esn->seq_hi == preplay_esn->seq_hi)
358 358 seq_diff = replay_esn->seq - preplay_esn->seq;
359 if (replay_esn->seq_hi == preplay_esn->seq_hi) 359 else
360 seq_diff = replay_esn->seq - preplay_esn->seq; 360 seq_diff = ~preplay_esn->seq + replay_esn->seq
361 else 361 + 1;
362 seq_diff = ~preplay_esn->seq + replay_esn->seq + 1;
363
364 if (replay_esn->oseq_hi == preplay_esn->oseq_hi)
365 oseq_diff = replay_esn->oseq - preplay_esn->oseq;
366 else
367 oseq_diff = ~preplay_esn->oseq + replay_esn->oseq + 1;
368
369 if (seq_diff < x->replay_maxdiff &&
370 oseq_diff < x->replay_maxdiff) {
371 362
372 if (x->xflags & XFRM_TIME_DEFER) 363 if (replay_esn->oseq_hi == preplay_esn->oseq_hi)
373 event = XFRM_REPLAY_TIMEOUT; 364 oseq_diff = replay_esn->oseq
365 - preplay_esn->oseq;
374 else 366 else
375 return; 367 oseq_diff = ~preplay_esn->oseq
368 + replay_esn->oseq + 1;
369
370 if (seq_diff >= x->replay_maxdiff ||
371 oseq_diff >= x->replay_maxdiff)
372 break;
376 } 373 }
377 374
375 if (x->xflags & XFRM_TIME_DEFER)
376 event = XFRM_REPLAY_TIMEOUT;
377 else
378 return;
379
378 break; 380 break;
379 381
380 case XFRM_REPLAY_TIMEOUT: 382 case XFRM_REPLAY_TIMEOUT: