{"record":{"id":"f8ae06661360d8c0","repo":"ruvnet/RuView","slug":"eio","errorCode":"EIO","errorMessage":"veil: genl_connect failed\\n","messagePattern":"veil: genl_connect failed\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"firmware/privshield/openwrt/veil_shieldd.c","lineNumber":75,"sourceCode":"    size_t          passes; /* Givens passes                                */\n    volatile sig_atomic_t running;\n};\n\nstatic struct veil_ctx g_ctx;\n\nstatic void on_signal(int sig) { (void)sig; g_ctx.running = 0; }\n\n/* ---------------------------------------------------------------------- */\n/* nl80211 bring-up — all REAL libnl-genl-3 API names.                     */\n/* ---------------------------------------------------------------------- */\nstatic int veil_nl_connect(struct veil_ctx *c) {\n    c->sock = nl_socket_alloc();\n    if (!c->sock) {\n        fprintf(stderr, \"veil: nl_socket_alloc failed\\n\");\n        return -ENOMEM;\n    }\n    if (genl_connect(c->sock)) {\n        fprintf(stderr, \"veil: genl_connect failed\\n\");\n        return -EIO;\n    }\n    c->family = genl_ctrl_resolve(c->sock, \"nl80211\");\n    if (c->family < 0) {\n        fprintf(stderr, \"veil: genl_ctrl_resolve(nl80211) failed: %d\\n\",\n                c->family);\n        return c->family;\n    }\n    /* Observe MLME events (auth/assoc, and — where the driver forwards them —\n     * action-frame notifications). Real multicast group name is \"mlme\". */\n    int grp = genl_ctrl_resolve_grp(c->sock, \"nl80211\", \"mlme\");\n    if (grp >= 0) {\n        (void)nl_socket_add_membership(c->sock, grp);\n    }\n    return 0;\n}\n\n/* ---------------------------------------------------------------------- */","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/firmware/privshield/openwrt/veil_shieldd.c#L57-L93","documentation":"`genl_connect()` connects the allocated socket to the kernel's NETLINK_GENERIC subsystem; any non-zero return is flattened by this code to `-EIO`. In practice the underlying causes are environmental: AF_NETLINK blocked by a container/seccomp policy, insufficient privileges in a user namespace, or fd exhaustion (EMFILE) at startup — the daemon deliberately does not distinguish them.","triggerScenarios":"Running inside Docker/LXC with a default seccomp profile blocking netlink; unprivileged user namespace without CAP_NET_ADMIN; fd limit exhausted by a leaked loop before the daemon starts; kernel built without generic netlink.","commonSituations":"Smoke-testing the daemon in a container instead of on the router; systemd unit with restrictive `RestrictAddressFamilies`; long-running hosts with fd leaks from other processes under the same limits.","solutions":["Run on the target (or container) with host netns and privilege: `docker run --net=host --cap-add NET_ADMIN ...`.","Raise/inspect fd limits: `ulimit -n`, `ls /proc/$(pidof veil_shieldd)/fd | wc -l`.","Confirm generic netlink works for other tools on the same host (`genl-ctrl-list` or `iw list`); if they also fail, fix the kernel/policy, not the daemon."],"exampleFix":"# before\ndocker run openwrt/veil_shieldd -i 2        # veil: genl_connect failed\n# after\ndocker run --net=host --cap-add NET_ADMIN openwrt/veil_shieldd -i 2","handlingStrategy":"validation","validationCode":"/* connectivity pre-check before starting the daemon loop */\nstatic int netlink_available(void) {\n    struct nl_sock *t = nl_socket_alloc();\n    if (!t) return -1;\n    int rc = genl_connect(t);\n    nl_socket_free(t);\n    return rc == 0 ? 0 : -1;\n}","typeGuard":null,"tryCatchPattern":"int rc = veil_nl_connect(&g_ctx);\nif (rc == -EIO) {\n    /* environment blocks AF_NETLINK: container policy, caps, or fd limits */\n    fprintf(stderr, \"veil: netlink blocked — run with host netns + CAP_NET_ADMIN\\n\");\n    exit(rc);\n}","preventionTips":["Always run with host network namespace and CAP_NET_ADMIN (or directly on the router).","In systemd units allow AF_NETLINK in RestrictAddressFamilies.","Smoke-test with `iw list` first; if that fails, fix the environment before debugging the daemon."],"tags":["c","openwrt","nl80211","libnl","permissions","containers"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}