ruvnet/RuView · error

veil: genl_ctrl_resolve(nl80211) failed: %d

Error message

veil: genl_ctrl_resolve(nl80211) failed: %d

What it means

Identical code in the wifi-veil vendored copy. `genl_ctrl_resolve(sock, "nl80211")` returns the nl80211 family id; a negative value (printed via `%d`) means the family is not registered with the kernel — almost always no cfg80211 driver is loaded or the kernel lacks nl80211. Bring-up aborts because neither MLME events nor commands can proceed without the family id.

Source

Thrown at wifi-veil/firmware/openwrt/veil_shieldd.c:80

static void on_signal(int sig) { (void)sig; g_ctx.running = 0; }

/* ---------------------------------------------------------------------- */
/* nl80211 bring-up — all REAL libnl-genl-3 API names.                     */
/* ---------------------------------------------------------------------- */
static int veil_nl_connect(struct veil_ctx *c) {
    c->sock = nl_socket_alloc();
    if (!c->sock) {
        fprintf(stderr, "veil: nl_socket_alloc failed\n");
        return -ENOMEM;
    }
    if (genl_connect(c->sock)) {
        fprintf(stderr, "veil: genl_connect failed\n");
        return -EIO;
    }
    c->family = genl_ctrl_resolve(c->sock, "nl80211");
    if (c->family < 0) {
        fprintf(stderr, "veil: genl_ctrl_resolve(nl80211) failed: %d\n",
                c->family);
        return c->family;
    }
    /* Observe MLME events (auth/assoc, and — where the driver forwards them —
     * action-frame notifications). Real multicast group name is "mlme". */
    int grp = genl_ctrl_resolve_grp(c->sock, "nl80211", "mlme");
    if (grp >= 0) {
        (void)nl_socket_add_membership(c->sock, grp);
    }
    return 0;
}

/* ---------------------------------------------------------------------- */
/* CONTROL 1 (FEASIBLE): TX antenna-map perturbation.                      */
/* Rotating the allowed TX antenna bitmap changes the static spatial       */
/* mapping the PHY uses, coarsely perturbing the CSI a sensor observes.    */
/* This is a genuinely userspace-reachable, compliant knob.                */
/*   NL80211_CMD_SET_WIPHY + NL80211_ATTR_WIPHY_ANTENNA_TX / _RX           */

View on GitHub (pinned to 4685618388)

Solutions

  1. Load the driver and verify resolution: `iw dev` and `genl-ctrl-list | grep nl80211`.
  2. Install matching kmods for the radio (e.g. kmod-mt76-*) and reboot.
  3. On custom kernels enable CONFIG_CFG80211 + CONFIG_NL80211 + the radio's mac80211 driver.

Example fix

# before
veil_shieldd -i 2                     # veil: genl_ctrl_resolve(nl80211) failed: -24
# after
opkg install kmod-mt76; iw dev >/dev/null && veil_shieldd -i 2
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
iw list >/dev/null 2>&1 || { echo "nl80211 not registered: load radio driver first"; exit 1; }
exec veil_shieldd -i "$(cat /sys/class/net/wlan0/ifindex)"

Try / catch

if (g_ctx.family < 0) {
    fprintf(stderr, "veil: nl80211 family missing — install matching kmods and reboot\n");
    return g_ctx.family;
}

Prevention

When it happens

Trigger: No wifi driver loaded (`lsmod | grep cfg80211` empty); radio not probed at boot; VM/container without wifi; custom kernel without CONFIG_NL80211; driver crashed and unloaded.

Common situations: Running the wifi-veil build on dev machines or VMs; routers with missing/mismatched kmod packages after a kernel upgrade.

Related errors


AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16). Data as JSON: /api/errors/cc02b787318b067f. Report an issue: GitHub.