Commit cd808fc9 authored by Thomas Egerer's avatar Thomas Egerer Committed by Steffen Klassert

xfrm: Fix aevent generation for each received packet

If asynchronous events are enabled for a particular netlink socket,
the notify function is called by the advance function. The notify
function creates and dispatches a km_event if a replay timeout occurred,
or at least replay_maxdiff packets have been received since the last
asynchronous event has been sent. The function is supposed to return if
neither of the two events were detected for a state, or replay_maxdiff
is equal to zero.
Replay_maxdiff is initialized in xfrm_state_construct to the value of
the xfrm.sysctl_aevent_rseqth (2 by default), and updated if for a state
if the netlink attribute XFRMA_REPLAY_THRESH is set.
If, however, replay_maxdiff is set to zero, then all of the three notify
implementations perform a break from the switch statement instead of
checking whether a timeout occurred, and -- if not -- return.  As a
result an asynchronous event is generated for every replay update of a
state that has a zero replay_maxdiff value.
This patch modifies the notify functions such that they immediately
return if replay_maxdiff has the value zero, unless a timeout occurred.
Signed-off-by: default avatarThomas Egerer <thomas.egerer@secunet.com>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 33fce60d
...@@ -61,9 +61,9 @@ static void xfrm_replay_notify(struct xfrm_state *x, int event) ...@@ -61,9 +61,9 @@ static void xfrm_replay_notify(struct xfrm_state *x, int event)
switch (event) { switch (event) {
case XFRM_REPLAY_UPDATE: case XFRM_REPLAY_UPDATE:
if (x->replay_maxdiff && if (!x->replay_maxdiff ||
(x->replay.seq - x->preplay.seq < x->replay_maxdiff) && ((x->replay.seq - x->preplay.seq < x->replay_maxdiff) &&
(x->replay.oseq - x->preplay.oseq < x->replay_maxdiff)) { (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))) {
if (x->xflags & XFRM_TIME_DEFER) if (x->xflags & XFRM_TIME_DEFER)
event = XFRM_REPLAY_TIMEOUT; event = XFRM_REPLAY_TIMEOUT;
else else
...@@ -301,9 +301,10 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event) ...@@ -301,9 +301,10 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event)
switch (event) { switch (event) {
case XFRM_REPLAY_UPDATE: case XFRM_REPLAY_UPDATE:
if (x->replay_maxdiff && if (!x->replay_maxdiff ||
(replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) && ((replay_esn->seq - preplay_esn->seq < x->replay_maxdiff) &&
(replay_esn->oseq - preplay_esn->oseq < x->replay_maxdiff)) { (replay_esn->oseq - preplay_esn->oseq
< x->replay_maxdiff))) {
if (x->xflags & XFRM_TIME_DEFER) if (x->xflags & XFRM_TIME_DEFER)
event = XFRM_REPLAY_TIMEOUT; event = XFRM_REPLAY_TIMEOUT;
else else
...@@ -352,28 +353,30 @@ static void xfrm_replay_notify_esn(struct xfrm_state *x, int event) ...@@ -352,28 +353,30 @@ static void xfrm_replay_notify_esn(struct xfrm_state *x, int event)
switch (event) { switch (event) {
case XFRM_REPLAY_UPDATE: case XFRM_REPLAY_UPDATE:
if (!x->replay_maxdiff) if (x->replay_maxdiff) {
break; if (replay_esn->seq_hi == preplay_esn->seq_hi)
seq_diff = replay_esn->seq - preplay_esn->seq;
if (replay_esn->seq_hi == preplay_esn->seq_hi) else
seq_diff = replay_esn->seq - preplay_esn->seq; seq_diff = ~preplay_esn->seq + replay_esn->seq
else + 1;
seq_diff = ~preplay_esn->seq + replay_esn->seq + 1;
if (replay_esn->oseq_hi == preplay_esn->oseq_hi)
oseq_diff = replay_esn->oseq - preplay_esn->oseq;
else
oseq_diff = ~preplay_esn->oseq + replay_esn->oseq + 1;
if (seq_diff < x->replay_maxdiff &&
oseq_diff < x->replay_maxdiff) {
if (x->xflags & XFRM_TIME_DEFER) if (replay_esn->oseq_hi == preplay_esn->oseq_hi)
event = XFRM_REPLAY_TIMEOUT; oseq_diff = replay_esn->oseq
- preplay_esn->oseq;
else else
return; oseq_diff = ~preplay_esn->oseq
+ replay_esn->oseq + 1;
if (seq_diff >= x->replay_maxdiff ||
oseq_diff >= x->replay_maxdiff)
break;
} }
if (x->xflags & XFRM_TIME_DEFER)
event = XFRM_REPLAY_TIMEOUT;
else
return;
break; break;
case XFRM_REPLAY_TIMEOUT: case XFRM_REPLAY_TIMEOUT:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment