Skip to content

Dispatch getsockname/sendto/recvfrom on netlink sockets#56

Open
chenhunghan wants to merge 2 commits into
sysprog21:mainfrom
chenhunghan:fix-netlink-sockets
Open

Dispatch getsockname/sendto/recvfrom on netlink sockets#56
chenhunghan wants to merge 2 commits into
sysprog21:mainfrom
chenhunghan:fix-netlink-sockets

Conversation

@chenhunghan
Copy link
Copy Markdown
Collaborator

@chenhunghan chenhunghan commented May 29, 2026

Fixes #53.

Dispatches getsockname/sendto/recvfrom to the AF_NETLINK emulation (they previously fell through to the host socket calls on the netlink pipe fd and returned ENOTSOCK), and makes RTM_GETLINK honor the ifi_index/IFLA_IFNAME request filter so a single-link lookup returns exactly one link. Full rationale in the commit message.

Validation on Apple Silicon: make elfuse, make check, and make test-matrix pass; glibc getifaddrs() now succeeds where it previously failed with ENOTSOCK (errno 88). (Hosted CI builds + lints only; the runtime tests require an HVF host, so those results are local.)


Summary by cubic

Dispatches netlink getsockname/sendto/recvfrom and honors RTM_GETLINK name/index filters to return a single link when requested. Fixes ENOTSOCK fallthroughs and unblocks clients using flat send/recv and port ID via getsockname.

  • Bug Fixes
    • Route FD_NETLINK in sys_getsockname/sys_sendto/sys_recvfrom to netlink_getsockname/netlink_send/netlink_recv, fixing ENOTSOCK on host fds.
    • Honor ifi_index and IFLA_IFNAME in RTM_GETLINK and return only the matching link; share dispatch via nl_process_request so sendmsg and flat send use the same filters.
    • Add tests/test-netlink.c and register it in tests/manifest.txt to exercise these paths and the getifaddrs() flow.

Written for commit f2704fa. Summary will update on new commits.

Review in cubic

Go's route package (vishvananda/netlink, used by the Kubernetes node-IP
detection path) talks to NETLINK_ROUTE via sendto(2)/recvfrom(2) and queries
the bound port id with getsockname(2). Only sendmsg/recvmsg/read were
dispatched to the netlink emulation, so these calls fell through to the host
socket fd and failed with ENOTSOCK ("netlinkrib: socket operation on
non-socket"), forcing callers onto a 127.0.0.1 fallback and breaking real
interface and SAN detection.

Add three netlink entry points and dispatch FD_NETLINK to them from
sys_getsockname/sys_sendto/sys_recvfrom:

  - netlink_send: process a flat (non-msghdr) RTM_GET* request buffer.
  - netlink_recv: drain whole buffered messages and write back sockaddr_nl.
  - netlink_getsockname: report the bound or auto-assigned port id.

Also honor the RTM_GETLINK request filter: parse the ifinfomsg ifi_index and
an optional IFLA_IFNAME attribute and emit only the matching link, so
LinkByName/LinkByIndex see exactly one reply instead of erroring with "more
than one link found". The sendmsg and send paths share a single
nl_process_request dispatcher so both honor the filter.

Validated with make check and make test-matrix on Apple Silicon; the k0s
controller now detects the real host IP instead of the loopback fallback.

(cherry picked from commit 31d29d184be83d4700f21d156b76739893fe1412)
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Re-trigger cubic

@jserv jserv requested a review from Max042004 May 29, 2026 10:09
Copy link
Copy Markdown
Collaborator

@Max042004 Max042004 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make check not cover new three syscall. It is better to implements a simple test so that in future we can catch whether has regression for this.

make check did not exercise the getsockname/sendto/recvfrom paths that the
netlink emulation now handles, so a regression reverting them to the host
socket fd (ENOTSOCK) would pass unnoticed.

Add tests/test-netlink.c and register it in the manifest. The test drives
each dispatched syscall directly against a NETLINK_ROUTE socket: getsockname
must report an AF_NETLINK address and a non-zero port id, a flat RTM_GETLINK
dump request must be accepted by sendto, and recvfrom must drain at least one
RTM_NEWLINK message with an AF_NETLINK source. It then runs glibc getifaddrs(),
the end-to-end call from issue sysprog21#53 that originally failed with ENOTSOCK.

Only implementation-independent netlink semantics are asserted, so the same
static binary passes under a real kernel as well as the emulation.

Validated with make check on Apple Silicon (9/9 checks pass); the same binary
run against an elfuse built from main reproduces the bug with 7 ENOTSOCK
failures, confirming the test catches the regression.
Comment thread tests/test-netlink.c
#include <unistd.h>

#include <sys/socket.h>
#include <net/if.h>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

net/if.h not used. Can delete

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AF_NETLINK sockets reject sendto/recvfrom/getsockname (ENOTSOCK), and RTM_GETLINK ignores the ifi_index/IFLA_IFNAME filter

2 participants