ruvnet/RuView · error
EIO
EIO
Error message
veil: genl_connect failed
What it means
Byte-identical copy of the privshield daemon inside the standalone wifi-veil workspace. `genl_connect()` attaches the socket to NETLINK_GENERIC; any failure is flattened to `-EIO` here. Real causes are environmental — AF_NETLINK blocked by seccomp/container policy, missing privileges in a user namespace, or fd exhaustion — rather than a daemon bug.
Source
Thrown at wifi-veil/firmware/openwrt/veil_shieldd.c:75
size_t passes; /* Givens passes */
volatile sig_atomic_t running;
};
static struct veil_ctx g_ctx;
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;
}
/* ---------------------------------------------------------------------- */View on GitHub (pinned to 4685618388)
Solutions
- Run with host network namespace and CAP_NET_ADMIN (`--net=host --cap-add NET_ADMIN`).
- Loosen `RestrictAddressFamilies` to include `AF_NETLINK` in the unit file, or raise fd limits.
- Cross-check with `iw list` on the same host: if that also fails, the environment blocks netlink, not the daemon.
Example fix
# before systemd-run ./veil_shieldd -i 2 # veil: genl_connect failed # after # unit file: RestrictAddressFamilies=AF_UNIX AF_NETLINK systemctl restart veil_shieldd
Defensive patterns
Strategy: validation
Validate before calling
static int netlink_available(void) {
struct nl_sock *t = nl_socket_alloc();
if (!t) return -1;
int rc = genl_connect(t);
nl_socket_free(t);
return rc == 0 ? 0 : -1;
} Try / catch
int rc = veil_nl_connect(&g_ctx);
if (rc == -EIO) {
fprintf(stderr, "veil: netlink blocked — need host netns + CAP_NET_ADMIN\n");
exit(rc);
} Prevention
- Launch with host netns and CAP_NET_ADMIN; plain containers block AF_NETLINK.
- Allow AF_NETLINK in systemd sandboxing directives.
- Verify `iw list` works in the exact environment before starting the daemon.
When it happens
Trigger: Container run without `--net=host`/CAP_NET_ADMIN; restrictive `RestrictAddressFamilies=AF_UNIX` in a systemd unit; EMFILE from fd leaks; kernel without generic netlink.
Common situations: CI or laptop smoke tests of the wifi-veil build; hardened service units; chroots without netlink devices.
Related errors
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/9929a801ad30cc0a.
Report an issue: GitHub.