{"record":{"id":"0c99129a223b0988","repo":"ruvnet/RuView","slug":"enomem","errorCode":"ENOMEM","errorMessage":"veil: nl_socket_alloc failed\\n","messagePattern":"veil: nl_socket_alloc failed\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"firmware/privshield/openwrt/veil_shieldd.c","lineNumber":71,"sourceCode":"    struct nl_sock *sock;   /* generic-netlink socket to nl80211            */\n    int             family; /* resolved \"nl80211\" genl family id           */\n    int             ifindex;/* target AP interface (e.g. phy0-ap0)         */\n    uint64_t        key;    /* shared session key for the keyed rotation    */\n    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    }","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/firmware/privshield/openwrt/veil_shieldd.c#L53-L89","documentation":"veil_shieldd is the OpenWrt nl80211 privacy daemon; `veil_nl_connect` begins by allocating a libnl socket handle with `nl_socket_alloc()`. A NULL return is mapped to `-ENOMEM`: the C heap is exhausted or the process hit a memory rlimit before the netlink channel even opens, so the daemon aborts bring-up at its first step.","triggerScenarios":"Embedded router with 32-64 MB RAM under boot-time memory pressure; `ulimit -v` / cgroup memory caps on the daemon; a leaky supervisor restart loop; ABI-mismatched libnl3/libnl-genl3 returning garbage.","commonSituations":"Low-RAM OpenWrt targets running many services; OOM pressure from the wifi stack itself; chroot/proot environments intercepting allocation; SDK-built binary deployed against different libnl than linked.","solutions":["Free memory or raise limits: stop unneeded services, raise the cgroup/`ulimit -v` cap, add zram/swap, then restart the daemon.","Check `dmesg` for the OOM killer selecting veil_shieldd; add memory headroom or respawn throttling under procd.","If it reproduces with ample free memory, verify runtime libnl matches the SDK: `ldd /usr/sbin/veil_shieldd | grep nl` and compare package versions."],"exampleFix":"# before\nveil_shieldd -i 2        # veil: nl_socket_alloc failed\n# after\n/etc/init.d/uhttpd stop   # free RAM on a 32MB target\nopkg install zram-swap; /etc/init.d/veil_shieldd restart","handlingStrategy":"validation","validationCode":"/* headroom check before daemon start */\n#include <sys/resource.h>\nstatic int heap_headroom_ok(void) {\n    struct rlimit rl;\n    if (getrlimit(RLIMIT_AS, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY\n        && rl.rlim_cur < (32ull << 20)) return 0; /* < 32MB cap will likely fail */\n    return 1;\n}","typeGuard":null,"tryCatchPattern":"if (veil_nl_connect(&g_ctx) != 0) {\n    fprintf(stderr, \"veil: nl80211 bring-up failed; freeing memory and retrying once\\n\");\n    /* procd respawn with threshold; do not busy-loop */\n    return 1;\n}","preventionTips":["Run veil_shieldd under procd with respawn thresholds so OOM kills are bounded.","Install zram/swap on memory-constrained targets.","Keep runtime libnl3 and libnl-genl3 versions identical to the SDK the binary was built with."],"tags":["c","openwrt","nl80211","libnl","memory","daemon-startup"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}