diff options
Diffstat (limited to 'net/xfrm/xfrm_replay.c')
-rw-r--r-- | net/xfrm/xfrm_replay.c | 54 |
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: |