Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 May 2024 22:10:39 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 279444] rtnetlink: recv(4) with MSG_DONTWAIT returns EAGAIN.
Message-ID:  <bug-279444-227@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D279444

            Bug ID: 279444
           Summary: rtnetlink: recv(4) with MSG_DONTWAIT returns EAGAIN.
           Product: Base System
           Version: 14.0-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: gnats@duck.com

When reading the title, you're probably thinking, =E2=80=9Cwell, yeah, that=
's how it
should work.=E2=80=9D and while I agree with you, the musl developers don't=
! [1]
(Though, it's really not their fault.) While testing the glibc netlink
shenanigans bug #279012, I also decided to test musl. In which, I found that
because musl does a recv(2) (which is technically a recvfrom(2)) with
MSG_DONTWAIT on a netlink socket, it always returns -1 (EAGAIN or EWOULDBLO=
CK).
[1] That said, you can actually get it to work intermittently if you supply
some latency (e.g., strace); however, like mentioned, this tends to be
unpredictable. I imagine that the Linux kernel is not faster than us here, =
but
rather doing something clever, and we have yet to implement such trickery as
well. I'll attach some code that reproduces the issue. This can be compiled=
 on
the linuxulator and freebsd to the same effect, which implies this problem
resides in the base netlink code.

#include <stdio.h>
#include <string.h>

#ifdef __FreeBSD__
#include <netlink/netlink.h>
#include <netlink/netlink_route.h>
#else
#include <linux/rtnetlink.h>
#endif

#include <arpa/inet.h>

int main(void) {
    int fd;
    fd =3D socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
    if (fd < 0) return -1;

    unsigned int seq =3D 1;
    int type =3D RTM_GETLINK;
    int af =3D AF_UNSPEC;

    struct nlmsghdr * h;
    union {
        uint8_t buf[8192];
        struct {
            struct nlmsghdr nlh;
            struct rtgenmsg g;
        }
        req;
        struct nlmsghdr reply;
    }
    u;
    int r, ret;

    memset( & u.req, 0, sizeof(u.req));
    u.req.nlh.nlmsg_len =3D sizeof(u.req);
    u.req.nlh.nlmsg_type =3D type;
    u.req.nlh.nlmsg_flags =3D NLM_F_DUMP | NLM_F_REQUEST;
    u.req.nlh.nlmsg_seq =3D seq;
    u.req.g.rtgen_family =3D af;
    r =3D send(fd, & u.req, sizeof(u.req), 0);
    if (r < 0) return r;

    do {
        r =3D recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT);
        if (r <=3D 0)
            printf("bad recv: %d\n", r);
        else
            printf("good recv: %d\n", r);
    } while (r <=3D 0);
    return 0;
}


[1] https://elixir.bootlin.com/musl/latest/source/src/network/netlink.c#L31

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-279444-227>