Fixes for running vwifi between an OpenWrt DUT VM and a Linux test
runner with mac80211_hwsim radios:
1. pmaddr fallback (ckernelwifi.cc):
ethtool GPERMADDR fails on OpenWrt hwsim VIFs (wlanc0/wlanc1).
handle_new_winet_notification() and handle_init_winet_notification()
now fall back to nl80211 MAC when get_pmaddr() returns false,
instead of silently dropping the VIF.
2. hwsim MAC 0x40 bit fix (cwirelessdevice.cc):
Set locally-administered bit on machwsim in constructor and
setMachwsim() to match the kernel's hwsim rhashtable key format.
Fixes frame delivery to radios created via netlink.
3. VIF name regex fix (cwirelessdevice.cc):
wlan regex changed from "wlan[0-9]*" to "wlan[a-z]?[0-9]*" to
match OpenWrt captive portal VIFs (wlanc0, wlanc1).
4. Frame deduplication (ckernelwifi.cc):
Multiple BSS VIFs (wlan0, wlan0-1) share the same PHY permanent
MAC. Without dedup, frames are delivered N times to the same radio,
causing duplicate auth/assoc and breaking WPA handshakes.
5. Frequency routing (ckernelwifi.cc, ckernelwifi.h):
Track each radio's channel from TX frames. Skip radios not tuned
to the frame's frequency in process_messages (local delivery).
Disabled for recv_from_server (kernel handles RX freq filtering).
6. freq=0 passthrough for recv_from_server (ckernelwifi.cc):
Pass freq=0 to send_cloned_frame_msg so the kernel skips its
HWSIM_ATTR_FREQ check. Prevents drops from TCP timing races
between scan dwell changes and frame delivery.
7. TCP_NODELAY (csocketclientitcp.cc, csocketserverfunctionitcp.cc):
Disable Nagle's algorithm for lower latency frame relay.
8. writev for atomic sends (cwifi.cc):
Replace two separate send() calls (power + data) with a single
writev() to prevent interleaving with concurrent writers.
9. Netlink buffer increase (ckernelwifi.cc):
nl_socket_set_buffer_size 16MB to prevent frame drops under load.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>