Skip to content

ax25: bound REJ-driven fast retransmits with the existing N2 counter - #8

Open
f6bvp wants to merge 1 commit into
linux-netdev:mainfrom
f6bvp:ax25-rej-storm-guard-clean
Open

f6bvp wants to merge 1 commit into
linux-netdev:mainfrom
f6bvp:ax25-rej-storm-guard-clean

Conversation

@f6bvp

@f6bvp f6bvp commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

REJ deliberately bypasses the T1/N2 backoff to trigger an immediate
go-back-N retransmit -- that is the whole point of REJ, fast recovery
from a single lost or out-of-order frame. But unlike every other
recovery path in this same state machine (T1 timeout, state 4
enquiry/DM, state 1/2 SABM retries), the REJ case in
ax25_std_state3_machine() never touches n2count, so it has no bound.

If something keeps corrupting or reordering every retransmitted burst
-- lossy RF, or packet reordering over a UDP-based transport such as
axudp -- each attempt draws an immediate fresh REJ and the link
retransmits at wire/CPU speed indefinitely, a "machine-gun" storm that
never reaches the N2 give-up already relied on everywhere else in this
file.

Reported independently twice: Chris Maness (KQ6UP) on a plain AX.25
link with no ROSE involved at all, and observed live on a ROSE/FPAC
White Pages link (same LAN, so plain network reordering over the
Internet is not the trigger there -- likely lossy retransmission of
the same PDU) reaching ~5900 pkt/s. Both hit the same code path since
ax25_std_in.c is shared regardless of what rides on top of AX.25.

Count consecutive REJ-driven fast retransmits the same way a T1
timeout already does in this state, and once N2 of them have failed to
get an in-sequence frame through, fall back to the paced state 4
enquiry -- which will genuinely disconnect after N2 further tries if
the link stays bad, exactly like every other recovery path already
does. A single frame accepted in sequence resets the counter, so an
isolated REJ during otherwise healthy traffic never gets close to N2.

Testing: deployed on three Raspberry Pi nodes since 2026-09-13,
running live production AX.25/ROSE/NET-ROM traffic since, with no
recurrence of the machine-gun storm and no other AX.25 regression
observed.

REJ deliberately bypasses the T1/N2 backoff to trigger an immediate
go-back-N retransmit -- that is the whole point of REJ, fast recovery
from a single lost or out-of-order frame. But unlike every other
recovery path in this same state machine (T1 timeout, state 4
enquiry/DM, state 1/2 SABM retries), the REJ case in
ax25_std_state3_machine() never touches n2count, so it has no bound.

If something keeps corrupting or reordering every retransmitted burst
-- lossy RF, or packet reordering over a UDP-based transport such as
axudp -- each attempt draws an immediate fresh REJ and the link
retransmits at wire/CPU speed indefinitely, a "machine-gun" storm that
never reaches the N2 give-up already relied on everywhere else in this
file.

Reported independently twice: Chris Maness (KQ6UP) on a plain AX.25
link with no ROSE involved at all, and observed live on a ROSE/FPAC
White Pages link (f6bvp-8<->f6bvp-10, same LAN, so plain network
reordering over the Internet is not the trigger there -- likely lossy
retransmission of the same PDU) reaching ~5900 pkt/s. Both hit the same
code path since ax25_std_in.c is shared regardless of what rides on
top of AX.25.

Count consecutive REJ-driven fast retransmits the same way a T1
timeout already does in this state, and once N2 of them have failed to
get an in-sequence frame through, fall back to the paced state 4
enquiry -- which will genuinely disconnect after N2 further tries if
the link stays bad, exactly like every other recovery path already
does. A single frame accepted in sequence resets the counter, so an
isolated REJ during otherwise healthy traffic never gets close to N2.

Deployed on three Raspberry Pi nodes (f6bvp-12, f6bvp-8, f6bvp-10)
since 2026-09-13, running live production AX.25/ROSE/NET-ROM traffic
since, with no recurrence of the machine-gun storm and no other AX.25
regression observed.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant