From 4c1b4e9a74f459600cd68452fb634df7a2708332 Mon Sep 17 00:00:00 2001 From: nickgarlis Date: Wed, 26 Mar 2025 17:46:24 +0100 Subject: [PATCH] Expose accumulated message size AFAIU, netlink has a message size limit of ~32KB. This means that a single transaction would be limited to a few operations. Going over the limit would result in the following error after flushing: netlink receive: recvmsg: no buffer space available If I am not mistaken, the only alternative is to then divide big transactions into smaller chunks. The only issue is that it's hard to tell when the limit has been exceeded. That's why I suggest exposing a function that would produce the accumulated message size since the messages slice is private. - https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/netlink/af_netlink.c?id=1e26c5e28ca5821a824e90dd359556f5e9e7b89f#n1930 - https://web.git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=d35c99ff77ecb2eb239731b799386f3b3637a31e --- conn.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/conn.go b/conn.go index d974b80..e1884e5 100644 --- a/conn.go +++ b/conn.go @@ -329,6 +329,22 @@ func (cc *Conn) FlushRuleset() { }) } +// GetMessageSize returns the total size of all messages in the buffer. +// This is useful for making sure that the messages will not exceed the limits +// of the netlink buffer which is 32768 + ~320 bytes. See also +// https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/netlink/af_netlink.c?id=1e26c5e28ca5821a824e90dd359556f5e9e7b89f#n1930 +// and +// https://web.git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=d35c99ff77ecb2eb239731b799386f3b3637a31e +func (cc *Conn) GetMessageSize() uint32 { + cc.mu.Lock() + defer cc.mu.Unlock() + var total uint32 + for _, msg := range cc.messages { + total += uint32(len(msg.Data)) + 16 // 16 bytes for the header + } + return total +} + func (cc *Conn) dialNetlink() (*netlink.Conn, error) { var ( conn *netlink.Conn