From cd30efe58e3284ab81f95073a0d802d4cbca72b1 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Wed, 25 Mar 2026 17:11:57 +0900 Subject: [PATCH] internal/netlink: enlarge recvfrom buffer This also uses an array type for the buffer since its size now uses the hardcoded value found in the kernel. Signed-off-by: Ophestra --- internal/netlink/netlink.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/internal/netlink/netlink.go b/internal/netlink/netlink.go index 406f567b..89f692a5 100644 --- a/internal/netlink/netlink.go +++ b/internal/netlink/netlink.go @@ -23,6 +23,9 @@ func getpid() uint32 { return nlPid } +// net/netlink/af_netlink.c +const maxRecvmsgLen = 32768 + // A conn represents resources associated to a netlink socket. type conn struct { // AF_NETLINK socket. @@ -37,8 +40,8 @@ type conn struct { typ, flags uint16 // Outgoing position in buf. pos int - // A page holding incoming and outgoing messages. - buf []byte + // Pages holding incoming and outgoing messages. + buf [maxRecvmsgLen]byte // An instant some time after conn was established, but before the first // I/O operation on f through raw. This serves as a cached deadline to // cancel blocking I/O. @@ -70,17 +73,19 @@ func dial(family int) (*conn, error) { } c.pos = syscall.NLMSG_HDRLEN - c.buf = make([]byte, os.Getpagesize()) c.t = time.Now().UTC() return &c, nil } +// ok returns whether conn is still open. +func (c *conn) ok() bool { return c.family >= 0 } + // Close closes the underlying socket. func (c *conn) Close() error { - if c.buf == nil { + if !c.ok() { return syscall.EINVAL } - c.buf = nil + c.family = -1 return c.f.Close() } @@ -245,7 +250,7 @@ type HandlerFunc func(resp []syscall.NetlinkMessage) error // returned by f. An error of type [Complete] is returned as nil. func (c *conn) receive(ctx context.Context, f HandlerFunc, flags int) error { for { - buf := c.buf + buf := c.buf[:] if n, _, err := c.recvfrom(ctx, buf, flags); err != nil { return err } else if n < syscall.NLMSG_HDRLEN { @@ -276,7 +281,7 @@ func (c *conn) receive(ctx context.Context, f HandlerFunc, flags int) error { // Roundtrip sends the pending message and handles the reply. func (c *conn) Roundtrip(ctx context.Context, f HandlerFunc) error { - if c.buf == nil { + if !c.ok() { return syscall.EINVAL } defer func() { c.seq++ }()