Skip to content

Commit

Permalink
[XFRM]: Fix aevent timer.
Browse files Browse the repository at this point in the history
Send aevent immediately if we have sent nothing since last timer and
this is the first packet.

Fixes a corner case when packet threshold is very high, the timer low
and a very low packet rate input which is bursty.

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jamal Hadi Salim authored and David S. Miller committed Apr 14, 2006
1 parent 6c97e72 commit 2717096
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
8 changes: 8 additions & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ struct xfrm_state
/* Replay detection state at the time we sent the last notification */
struct xfrm_replay_state preplay;

/* internal flag that only holds state for delayed aevent at the
* moment
*/
u32 xflags;

/* Replay detection notification settings */
u32 replay_maxage;
u32 replay_maxdiff;
Expand All @@ -168,6 +173,9 @@ struct xfrm_state
void *data;
};

/* xflags - make enum if more show up */
#define XFRM_TIME_DEFER 1

enum {
XFRM_STATE_VOID,
XFRM_STATE_ACQ,
Expand Down
25 changes: 19 additions & 6 deletions net/xfrm/xfrm_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -805,16 +805,22 @@ void xfrm_replay_notify(struct xfrm_state *x, int event)
case XFRM_REPLAY_UPDATE:
if (x->replay_maxdiff &&
(x->replay.seq - x->preplay.seq < x->replay_maxdiff) &&
(x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))
return;
(x->replay.oseq - x->preplay.oseq < x->replay_maxdiff)) {
if (x->xflags & XFRM_TIME_DEFER)
event = XFRM_REPLAY_TIMEOUT;
else
return;
}

break;

case XFRM_REPLAY_TIMEOUT:
if ((x->replay.seq == x->preplay.seq) &&
(x->replay.bitmap == x->preplay.bitmap) &&
(x->replay.oseq == x->preplay.oseq))
(x->replay.oseq == x->preplay.oseq)) {
x->xflags |= XFRM_TIME_DEFER;
return;
}

break;
}
Expand All @@ -825,8 +831,10 @@ void xfrm_replay_notify(struct xfrm_state *x, int event)
km_state_notify(x, &c);

if (x->replay_maxage &&
!mod_timer(&x->rtimer, jiffies + x->replay_maxage))
!mod_timer(&x->rtimer, jiffies + x->replay_maxage)) {
xfrm_state_hold(x);
x->xflags &= ~XFRM_TIME_DEFER;
}
}
EXPORT_SYMBOL(xfrm_replay_notify);

Expand All @@ -836,10 +844,15 @@ static void xfrm_replay_timer_handler(unsigned long data)

spin_lock(&x->lock);

if (xfrm_aevent_is_on() && x->km.state == XFRM_STATE_VALID)
xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT);
if (x->km.state == XFRM_STATE_VALID) {
if (xfrm_aevent_is_on())
xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT);
else
x->xflags |= XFRM_TIME_DEFER;
}

spin_unlock(&x->lock);
xfrm_state_put(x);
}

int xfrm_replay_check(struct xfrm_state *x, u32 seq)
Expand Down

0 comments on commit 2717096

Please sign in to comment.