bes2600: pre-empt AP-deauth-6 with mac80211 reassoc on decrypt-fail storm #1
Reference in New Issue
Block a user
Delete Branch "bes2600/decrypt-storm-fast-recover"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Patch A — Phase 6 implementation
Follows the Phase 4 plan merged at
marfrit/besserPR #4 (commit4acba3e7,notes/phase4-2026-05-06.md).What it does
When
bes2600_rx_cbreceives a frame withWSM_STATUS_DECRYPTFAILUREfrom firmware, account it on a sliding window. If ≥ 5 decrypt-fails fire within ≤ 5 s on the same vif, a worker callsieee80211_connection_loss(vif)to force mac80211 into clean disassociation. Userspace (NetworkManager / wpa_supplicant) then reconnects with fresh keys, before the AP gets a chance to fire its unprotected deauth-reason-6.Why
Reviewer feedback (from
marfrit/besserPR #4) folded inieee80211_connection_loss(vif)is the kernel-majority pattern (perinclude/net/mac80211.hdoc-comment) for STA drivers signalling "link is gone, reassoc please".cfg80211_disconnectedwould bypass mac80211 state-machine.DecryptStormRecoveries: %uline in the per-vifstatusseq_file under/sys/kernel/debug/ieee80211/phyN/bes2600/.Predicted Phase 7 delta vs unpatched baseline
Files touched
bes2600/bes2600.h— 4 new fields onstruct bes2600_vif+ 2 prototypesbes2600/txrx.c— new helpers + call at the existing decrypt-fail log site (bes2600_rx_cb)bes2600/sta.c—bes2600_decrypt_storm_init()inbes2600_vif_setupbes2600/debug.c—DecryptStormRecoveriesseq_printfVerification status
checkpatch.pl --no-tree --strict: clean (0 / 0 / 0)./usr/src/linux-rockchip-rkr3/not yet confirmed in this PR — would be next step before merge.Asks
cancel_work_sync(&priv->decrypt_storm_recover_work)be added to the vif teardown path? Existing per-vif workers don't all have explicit cancel — happy to follow whichever the maintainer prefers.🤖 Generated with Claude Code
When the BES2600 firmware reports WSM_STATUS_DECRYPTFAILURE for a burst of received frames (typically because the host's PTK or GTK has fallen out of sync with the AP), the AP eventually concludes that the STA is not authenticated and emits an unprotected deauth-reason-6 ("Class 2 frame received from non-authenticated station"). On the deployed pinetab2 + bes2600 stack this AP-initiated deauth has been observed to leave the link blackholed for up to 109 s before userspace finds a different SSID/channel to recover on. (Receipts at https://git.reauktion.de/marfrit/besser, notes/phase5-2026-05-06.md.) Add a sliding-window counter on each bes2600_vif: when 5 decrypt failures fire within 5 s, schedule a worker that calls ieee80211_connection_loss(vif). mac80211 then performs immediate disassociation; userspace (NetworkManager / wpa_supplicant) reconnects with fresh keys before the AP gets a chance to fire its unprotected deauth. Predicted Phase 7 delta vs the unpatched baseline: - decrypt-burst rate: unchanged (this does not address root cause) - AP-deauth-6 rate: <= 0.2 of baseline - conditional probability of >5s blackhole given a burst: 100% -> <= 10% - worst-case recovery time: 109s -> <5s Contract pin: ieee80211_connection_loss() per include/net/mac80211.h: "may also be called if the connection needs to be terminated for some other reason... will cause immediate change to disassociated state, without connection recovery attempts." Userspace recovery is the existing NM/wpa_supplicant path. The worker context satisfies the implicit process-context expectation. Files touched: - bes2600/bes2600.h: 4 new fields on struct bes2600_vif + 2 prototypes - bes2600/txrx.c: new helpers + the call site at the existing WSM_STATUS_DECRYPTFAILURE log point (the unconditional "goto drop" branch in bes2600_rx_cb) - bes2600/sta.c: bes2600_decrypt_storm_init() in bes2600_vif_setup - bes2600/debug.c: DecryptStormRecoveries seq_printf in the per-vif status seq_file output Threshold (5/5s) is set well above the steady-state per-vif decrypt- fail rate observed in measurement (~1/min even under sustained 1 MB/s load), so a true storm is required to trip it. The cw1200/cw1260 ancestor has no equivalent storm-recovery; this is a clean addition. checkpatch.pl --no-tree --strict: clean (0/0/0). Signed-off-by: Claude (noether) <claude@reauktion.de> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Threshold OK? (5 / 5 s — looser than typical decrypt-fail bursts)
Should cancel_work_sync(&priv->decrypt_storm_recover_work) be added to the vif teardown path? Existing per-vif workers don't all have explicit cancel — happy to follow whichever the maintainer prefers.
Question: so some do, some don't - if there is no hurt in calling cancel_work_sync twice (no double free? dereferencing of a previously invalidated pointer?) then, yes.
Per-VIF or per-hw_priv counter scope? I went with per-VIF (storms come through wsm_handle_rx with a vif-resolved priv); per-hw_priv would aggregate across multiple vifs.
Per-VIF.
b8f57a8443toaf4b52affcFolded in the three resolutions, force-pushed
af4b52a:cancel_work_syncon teardown: added inbes2600_remove_interfacealongside the existing per-vifcancel_*_work_syncblock. Safety check (per your concern): the kernelcancel_work_synccontract guarantees:INIT_WORK'dwork_struct(which we did inbes2600_decrypt_storm_init),privwhen mac80211 frees the vif,false, no double-anything,Net: a single call here is sufficient and safe; calling it twice would also be harmless.
wsm_handle_rxwith a vif-resolvedpriv).Diff bumped from 86 → 87 lines (+ the one-line cancel).
checkpatch --no-tree --strictstill clean (0/0/0).Not yet done: build verification against the running kernel + Phase 7 measurement on ohm. Holding for your re-review.
Thank you for your PR, please go ahead.