The following information has been reverse engineered to the best of my ability to diagnose, this took several hours to mitigate and pin down, if you need anything else i’m happy to provide information.
On firmware 4.9.0, ECM's PPE front-end performs zero conntrack stats syncs, while the SFE front-end on the same router performs roughly one per second with no failures. Because ECM refreshes a flow's nf_conntrack entry from those stats, any PPE-accelerated flow is never refreshed: its packet counters freeze and its timeout decays monotonically until the entry is destroyed while the flow is still passing traffic. The NAT mapping disappears, return traffic is dropped, and the application stalls.
This gives every accelerated flow a hard lifetime equal to its conntrack timeout, regardless of activity:
-
UDP: 180 seconds (
nf_conntrack_udp_timeout_stream) -
TCP: 7440 seconds (
nf_conntrack_tcp_timeout_established)
Games and other long-lived UDP sessions therefore break roughly every 3 minutes, while ping, DNS, PPPoE and link state all test perfectly clean, ICMP is not PPE-accelerated, so every conventional diagnostic passes.
Affected
| Model | GL-BE9300 (Flint 3) |
| Firmware | 4.9.0 |
| Base | OpenWrt 23.05-SNAPSHOT, kernel 5.4.213 |
| WAN | PPPoE (~900/100) |
| Setting | ecm.global.acceleration_engine='auto' (the default, which selects PPE) |
Symptoms of this bug, there might be more, but are some of the following:
-
Online games report a "disconnection" window and recover on their own
-
Long-running uploads fail intermittently
-
Individual applications stall while the rest of the machine stays online
-
The link never drops, the WAN never renegotiates, ping and DNS are flawless throughout
Root cause
Compare the two front-ends on the same router at the same moment, sampled over 90 seconds under normal load:
t=0s PPE: accel=60 stats=[success=0 fail=0 nack=0] SFE: accel=6 stats=[success=845017]
t=30s PPE: accel=73 stats=[success=0 fail=0 nack=0] SFE: accel=6 stats=[success=845045]
t=60s PPE: accel=82 stats=[success=0 fail=0 nack=0] SFE: accel=8 stats=[success=845074]
t=90s PPE: accel=102 stats=[success=0 fail=0 nack=0] SFE: accel=8 stats=[success=845103]
Read from:
/sys/kernel/debug/ecm/ecm_ppe_ipv4/stats_request_counter
/sys/kernel/debug/ecm/ecm_sfe_ipv4/stats_request_counter
/sys/kernel/debug/ecm/ecm_ppe_ipv4/accelerated_count
/sys/kernel/debug/ecm/ecm_sfe_ipv4/accelerated_count
PPE is carrying the large majority of flows and has never attempted a stats request, fail=0 and nack=0 show it is not failing, it simply never runs. SFE, handling a fraction of the flows, has 845,000 successes.
Reproduction: watching a live flow get killed
Four concurrent UDP flows from one LAN host to the same game server, sampled every ~15 s. to= is the conntrack timeout, pkts= are conntrack's packet counters:
:51937 to=169 →124 →109 → 94 pkts FROZEN at 722/595
:59902 to=109 → 63 → 48 → 33 pkts FROZEN at 419/815
:53955 to= 49 → 19 → 4 → GONE pkts FROZEN at 308/738
:55275 to=179 →179 →179 →169 pkts RISING 61/174 → 235/1214
The first three are PPE-accelerated: counters frozen because traffic bypasses the kernel, timeouts decaying with no refresh. :53955 was destroyed while still live. :55275 was not accelerated, so its packets traverse conntrack normally and its timeout keeps resetting to 180, the control case in the same capture.
A flow with 724,610 / 2,915,693 packets was also observed at to=16, and was gone 15 seconds later.
Consequence, from nft list chain inet fw4 accept_to_wan:
oifname "pppoe-wan" ct state invalid counter packets 30597 bytes 1611928 drop
30,597 outbound packets silently dropped as invalid, no RST, no ICMP, because their conntrack entry had been destroyed underneath them.
This is not conntrack exhaustion
Other reports of Flint 3 instability mention nf_conntrack: table full. This is a different failure with the same origin, and it is worth distinguishing:
count: 208 max: 28672
insert_failed=0 drop=0 early_drop=0 (all CPUs)
The table was nowhere near full and had never dropped a packet. The entries are not accumulating, they are being deleted too early.
Why it is easy to misdiagnose
Conntrack packet counters cannot be used as a health signal while PPE holds a flow. They freeze, so a perfectly healthy accelerated connection reads as out=11 pkts / back=1 pkt and looks like a stall. The reliable indicator is the timeout field: pinned near maximum means it is being refreshed; decaying monotonically means it is not.
Additionally, /sys/kernel/debug/ecm/ecm_state/ returns zero bytes at any output mask on this build, so ECM's accelerated-flow list cannot be enumerated from userspace. That rules out diagnosing per-flow engine assignment, and also rules out a userspace conntrack -U refresh daemon as a workaround.
Workaround that works
uci set ecm.global.acceleration_engine='ppe-sfe'
uci commit ecm
reboot
Mode 5 loads both front-ends. PPE remains available for the Wi-Fi / PPE Direct Switch path, while SFE takes routed WAN flows and refreshes their conntrack entries correctly.
Verified after this change:
-
UDP flow timeouts hold at 175–179 against a 180 maximum, with rising counters (previously decaying to zero)
-
TCP holds 7438–7439 against 7440
-
MLO client healthy, router→client latency 4.2 ms (was 14–66 ms)
-
Throughput unchanged: 551–630 Mbps vs 608–650 on
auto
PPE still reports success=0 under this mode and still holds ~100 flows, so the underlying defect is unfixed, the hybrid simply routes the flows that need conntrack onto the engine that maintains it.
Important: acceleration_engine='sfe' is not a valid workaround
Switching to SFE alone fixes conntrack but completely breaks MLO Wi-Fi clients. The client associates normally at strong signal (−46 dBm, 648 Mbps negotiated) but traffic times out.
Confirmed on both a hot swap and a clean cold boot, so it is not a module load-order artifact. qca_nss_ppe_ds (PPE Direct Switch) is bound to wifi_3_0, and MLD clients on mld0 appear to require the PPE front-end to be loaded.
Throughput for reference, same 1 GB file and path throughout:
| Engine | Throughput | Wired UDP flows | MLO Wi-Fi |
|---|---|---|---|
auto (PPE) |
608–650 Mbps | reaped at 180 s | works |
sfe |
603–627 Mbps | correct | broken |
ppe-sfe |
551–630 Mbps | correct | works |
| acceleration off | 365–378 Mbps | correct | works |