What rxg_sdan 1.18 fixes

Local switching between two clients on the same WAP. Summary of two lab runs on WF‑188n pairs.

1.18 fixes client‑to‑client traffic when both clients are on the same WAP but on different sdan ports. That covers two radios of one WAP, and it covers a wired LAN‑port client talking to a wireless one. On 1.16 those combinations fail completely, in both directions.

Two things are not affected and work on both versions: clients on the same radio, and clients on different WAPs. Nothing about north/south (client to gateway, DNS, internet) changes either.

The rule

Both clients are…1.161.18Why
on the same radio of one WAPworksworks the WAP’s own intra‑BSS path forwards it; sdan never sees the frame
on different radios of one WAPfailsworks two dynamic VIFs, nothing bridging them — needs local switching
one wired, one wireless, same WAPfailsworks LAN port and VIF are separate sdan ports — needs local switching
on different WAPs (any mix)worksworks exits to the uplink and comes back; local switching not involved

Why it looks intermittent in the field

This is the part worth passing on to anyone triaging a complaint. On 1.16 the same two devices succeed or fail depending on where they happen to land:

So a guest casting to a TV, a laptop printing to a wired printer in the same unit, or any mDNS‑based discovery (AirPlay, Chromecast, printer discovery) can work, then stop, then start again, with no configuration change and nothing in the logs. Band steering and roaming are enough to move a device between all three states on their own. Reports of “flaky” in‑unit device‑to‑device behaviour on 1.16 are worth re‑reading as this bug rather than as RF.

Evidence

Case1.161.18Run
Same radio, one WAP5/55/5 east‑west 1.16 vs 1.18 — 5 trials
Different radios, one WAP0/55/5 east‑west 1.16 vs 1.18 — 5 trials
Wired ↔ wireless, one WAP0/186/6 wired + wireless matrix
Across WAPs, all mixes42/42 — no difference wired + wireless matrix
North/south (gateway, DNS, HTTP)24/24 — no difference wired + wireless matrix

Both runs used two WF‑188n of identical model, firmware and configuration, on one VLAN, with the kernel module as the only variable. Clients were WF‑189 sensors: a real STA placed on an exact BSSID, and for the wired case a real LAN‑port station authorised by RADIUS MAC‑auth and leased by DHCP.

Mechanism, in one paragraph

hostapd runs with vlan_no_bridge=1 and the client VLAN is deliberately absent from the Linux bridge, so each dynamic VIF (wlan0-v301, wlan1-v301) and each wired port (eth1) is its own sdan port with nothing bridging them. Traffic between any two of them has only one possible path, and that path is local switching — which is what 1.18 adds. You can see it in rxg_sdanctl tunnels: 1.18 reports local-switch=true with a climbing local-sw packet counter, while 1.16 (abi 3) has no such capability at all. Traffic that exits to the uplink never needs the feature, which is exactly why cross‑WAP is unaffected, and same‑radio traffic is handled by the WAP before sdan is involved, which is why its counter correctly stays flat there.

Limits of this testing

Wired ↔ wired on one WAP is untested. It is the same local‑switch path and so should behave the same way, but nothing here demonstrates it. It needs two LAN ports on one WAP — a WF‑189H (LAN1/LAN2) rather than the single‑port setup used here. Worth covering before assuming it, since a unit with two wired devices is a realistic hospitality case.

The wired result is unevenly sampled. 18 measurements on the failing side against 6 on the passing side, because of how the client placements were built. The 0/18 and 6/6 are each internally consistent across three traffic types and both directions, and the earlier cross‑radio case was 0/5 vs 5/5 over five trials — but a balanced re‑run is outstanding.

One uncontrolled difference. The 1.18 WAP also ran a patched rg_wss_client affecting wired tunnel selection. Both WAPs were untunneled plain‑VLAN in these runs, so it should not bear on local switching, but the software was not byte‑identical end to end.