East‑west on one AP: rxg_sdan 1.16 vs 1.18

Two WF‑188n, identical model / firmware / VLAN / clients / scenario file. The only variable is the kernel module. A real TCP job to port 9100 between two wireless clients on the same AP.

Result

Topology188n‑96 — sdan 1.16188n‑99 — sdan 1.18
Same radio
both clients on one BSSID
AP forwards it; sdan not involved
5/5 delivered · 0.21s 5/5 delivered · 0.21s
Cross radio
the AP’s two radios, two dynamic VIFs
no bridge between them; needs local‑switch
0/5 delivered · OSError×5 5/5 delivered · 0.21s

Exactly one cell differs. Cross‑radio east‑west is dead on 1.16 and works on 1.18; same‑radio is unaffected by the module version because those frames never reach sdan.

Mechanism, in the counters

APrxg_sdanctl -j tunnels
188n-99 (1.18)local_switch_effective: true, local_sw_pkts: 496, local_sw_bytes: 34355
188n-96 (1.16){"vlan":301,"type":"vlan"} — no local-switch capability at all

Same‑radio traffic is forwarded by the AP’s own intra‑BSS path, so sdan never sees it and its counter correctly stays flat — a flat counter there is the expected result, not a fault. Cross‑radio puts the clients on separate dynamic VIFs (wlan0-v301 / wlan1-v301) which nothing bridges, because hostapd runs vlan_no_bridge=1 and the client VLAN is absent from the Linux bridge. Local switching is the only available path, and it is what 1.18 adds.

Method

Two WF‑189 sensors, one emulated client each (enforced: a second station on the same phy holds the radio and the driver then refuses the other client’s channel change). Each client is L3‑isolated in a Linux VRF via the production VrfDomain, leases by DHCP through udhcpc-vrf.sh, and is placed on an exact BSSID with verification before and after every trial. Delivery is judged by the receiver’s accept count, not the sender’s return code.