Replies: 4 comments
Q5 (hostapd / AP role): Clarification — PR #111236 already handles this. It runs hostapd on wlan0 (AP) and wpa_supplicant on wlan1 (STA) and links them through the in-process relay bus. This means #111236 is the only PR of the three that tests all Wi-Fi roles including AP, STA, and P2P within a single Zephyr image. Q5 can be closed — the design already covers it. This actually reinforces #111236 as the right long-term target: once the inter-VIF data-path routing issue is resolved (Q1), it provides the most complete simulation coverage of any of the three approaches, with no host OS dependency. |
|
The namespace problem is solvable entirely within the hwsim driver — no Zephyr core changes needed. The key insight is that the relay bus must never touch the routing table. Instead it maintains its own MAC→iface lookup table populated at init time, and uses net_recv_data() to inject frames directly into the target interface's RX path, bypassing the IP stack entirely: This works cleanly because the interfaces are declared as offload ifaces — the Zephyr IP stack hands the full frame to the driver TX hook without doing ARP/NDP or route resolution, so the relay sees raw frames and can forward them purely at L2. EAPOL frames (which are below IP) flow through exactly the same path with no special casing. The reply from AP→STA takes the same route: AP driver TX → relay → net_recv_data() on STA iface. The routing table is never consulted for inter-radio traffic. |
Update: in-process data path solved (#111236)The data-path routing problem from the RFC is now solved entirely within the driver + two config knobs -- no Zephyr core changes. Full STA<->AP ICMP ping over the simulated medium passes in a single native_sim process (ztest test_04/test_05, 5/5 green). The MAC->iface idea from the earlier comment was right for the relay side, but it isn't sufficient on its own: in a single image both radios share one IP stack, so each radio's address is also a local address. That trips two IP-stack guards that have to be defeated, plus a relay routing rule. The three pieces
How a ping flows now STA ping 192.168.1.1 (AP)
The reply takes the same symmetric path: driver TX -> medium -> net_recv_data() on the peer iface. The routing table is never consulted for inter-radio traffic beyond the on-link ARP, and EAPOL/mgmt frames flow through the same medium with no special casing. Notes
|
MoM — Zephyr Wi-Fi Telco | July 1, 2026Attendees: Jukka, Pieter, Maochen, Hui Bai, Satish Nallamala, Robert Lubos Decisions
Next Steps
Future Extensions
|
Uh oh!
There was an error while loading. Please reload this page.
RFC: Wi-Fi Simulation Driver for hostapd/wpa_supplicant Testing (hwsim)
Summary
Three draft PRs now propose a way to test the Zephyr Wi-Fi stack (hostapd / wpa_supplicant / Wi-Fi mgmt) without physical hardware. This RFC summarises the approaches, compares them, proposes a merge strategy, and asks for community input on the open design questions — particularly around the data-path routing problem that is unique to Zephyr.
PRs under discussion:
drivers: wifi: add hwsim virtual Wi-Fi simulator driver(Chaitanya Tata / krish2718)drivers: wifi: native_sim: Add Wi-Fi driver using host nl80211(Jukka Rissanen / jukkar)drivers: wifi: add emulated Wi-Fi driver(Pieter De Gendt / pdgendt)Background
Testing the Zephyr Wi-Fi stack today requires physical Wi-Fi hardware. Every CI run that wants to exercise the hostapd/wpa_supplicant stack, the EAPOL 4-way handshake, or even just Wi-Fi management event handling must provision a radio. This is slow, fragile, and hard to scale.
Linux solved this problem a long time ago with
mac80211_hwsim: a kernel module that creates virtual radios connected by an in-kernel frame-relay bus, isolated per-process with network namespaces. All three PRs take different angles on bringing an equivalent to Zephyr.The Three Approaches
Approach A — PR #111236: Pure in-process Zephyr hwsim (Chaitanya)
Creates N virtual radios inside a single Zephyr image. Each radio is a
net_ifwith Ethernet L2 and Wi-Fi offload ops. An in-process frame-relay bus delivers frames transmitted on one radio to all other radios on the same channel, simulating a shared wireless medium.Strengths: No host OS dependency; runs anywhere Zephyr runs; true multi-radio simulation; most portable for CI.
Key open issue: Zephyr has no network namespace support. When the relay bus delivers a frame from Radio 0 to Radio 1, both interfaces live in the same global
net_iflist. The return path for replies (e.g. EAPOL frames from AP back to STA) may be mis-routed by the shared routing table or silently dropped by the Ethernet L2 loopback guard. See the data-path section below.Approach B — PR #110681: native_sim + host Linux nl80211 (Jukka)
Delegates the RF medium entirely to the Linux kernel. The Zephyr image runs as a
native_simprocess. The driver links the nl80211 host library directly into the binary and uses it to drive amac80211_hwsimvirtual radio on the host. The Zephyrwpa_supplicantis the sole SME.Strengths: Uses the battle-tested
mac80211_hwsimmedium; namespace isolation is handled by the host OS so there is no loopback ambiguity; full EAPOL 4-way handshake works today; data-path (AF_PACKET) is clean. Already tested: scan, connect (open + WPA2-PSK), status, disconnect, and data transfer all confirmed working.Key open issue: Linux-only (
native_sim). Testing path for CI is still described as work-in-progress in the PR. Also requires the host to havemac80211_hwsimloaded, which needs kernel module support on the CI runner.Approach C — PR #111194: Offload-style emulated driver (Pieter)
No RF medium at all. Scan results, connection outcomes, and disconnect events are injected at runtime through a
wifi_emultest-control API. The driver is an offload-style Zephyr driver that mimics a Wi-Fi-only board.Strengths: Extremely portable; fully deterministic; perfect for testing the application Wi-Fi event-handling layer (reconnect logic, scan throttling, error handling); zero setup overhead in CI.
Scope: Does not test hostapd / wpa_supplicant / EAPOL at all. This is an intentional design choice, not a gap.
The Namespace / Data-Path Problem
This is the hardest Zephyr-specific challenge and affects PR #111236 most directly. It is worth discussing explicitly.
On Linux,
mac80211_hwsimcreates separate netdevs (wlan0,wlan1, …). Processes in different network namespaces own one each, so the kernel routes frames naturally between them.Zephyr has no namespace support:
net_ifinstances share a single global interface list.net_recv_data()on Radio 1. But the Ethernet L2 receives it in the context of anet_ifthat shares state with Radio 0. The L2 layer can see Radio 1's own MAC in the destination field and process it correctly — but the reply frame from Radio 1 to Radio 0 goes through the shared routing table, which has no concept of "this packet belongs to a different virtual radio"; it may loop back to Radio 1 instead of being delivered to Radio 0.The fix is for the relay bus to route reply frames by explicit MAC lookup across the registered radios and call
net_recv_data()on the matched iface, bypassing the global routing table for inter-radio traffic. PR #111236 needs to document and validate this path explicitly — a test that exercises EAPOL across two virtual radios is the acceptance criterion.PR #110681 sidesteps this entirely: the Linux kernel's network namespaces handle isolation, and the Zephyr side sees only one interface with one socket.
Proposed Merge Strategy
Given the different scopes, a two-tier approach makes more sense than picking one winner:
All three PRs should share a common test sample directory (
samples/net/wifi/hwsim_test/) with Twister YAML covering each driver, plus a CI script for the nl80211 host setup.Open Questions for the Community
Data-path routing (drivers: wifi: add hwsim virtual Wi-Fi simulator driver #111236): Is the proposed
net_recv_data()bypass sufficient, or does Zephyr need a more formal concept of "virtual interface group" to make multi-VIF scenarios reliable? Should this be addressed as a net core change rather than a driver workaround?CI infrastructure (drivers: wifi: native_sim: Add Wi-Fi driver using host nl80211 #110681): Which CI runners in the Zephyr project currently support loading kernel modules? Is
mac80211_hwsimavailable on the GitHub Actions runners used for Twister, or would this require dedicated hardware or a custom container?Scope of drivers: wifi: add emulated Wi-Fi driver #111194: Should the
wifi_emulAPI be able to inject EAPOL failure events (even though no real EAPOL runs) so that application-level handling of auth failures can be tested? Or does that conflate the emulation layer with the supplicant layer?Long-term convergence: Once drivers: wifi: add hwsim virtual Wi-Fi simulator driver #111236's data-path issue is resolved, should it eventually replace drivers: wifi: native_sim: Add Wi-Fi driver using host nl80211 #110681 for all CI (making the stack fully host-OS-independent), or should both coexist permanently (nl80211 for deeper protocol fidelity, pure-Zephyr hwsim for portability)?
hostapd side: All three PRs focus on the STA role. Is there a plan / interest in also running hostapd inside the same Zephyr image (using drivers: wifi: add hwsim virtual Wi-Fi simulator driver #111236's multi-radio model) for AP-side testing?
Suggested Next Steps
scripts/ci/wifi_hwsim_setup.shfor the host setup stepswifi_emulas aZTEST_SUITEfixture; add negative-path test casesnet_recv_data()injection path; resolve loopback routingsamples/net/wifi/hwsim_test/with shared Twister YAMLdoc/connectivity/wifi/wifi_hwsim.rstto the Zephyr doc treeTagging @krish2718, @jukkar, @pdgendt for visibility. Input from the networking and Wi-Fi working groups very welcome.
All reactions