aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/netlink/netlink.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-03-23 15:16:21 +0900
committerOphestra <cat@gensokyo.uk>2026-03-23 16:39:25 +0900
commitd972cffe5a221cc585e2edfdd1d3514eab51271c (patch)
tree70c4d6fd0c2385011c65ae5084cdef3ac2fcd4bc /internal/netlink/netlink.go
parentd8648304bb4208593be0c48b8b1b26c1caa8b3ea (diff)
internal/netlink: make full response available
The previous API makes it impossible to retrieve remaining messages in the current iteration. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/netlink/netlink.go')
-rw-r--r--internal/netlink/netlink.go58
1 files changed, 30 insertions, 28 deletions
diff --git a/internal/netlink/netlink.go b/internal/netlink/netlink.go
index e6f6fa26..5df7b390 100644
--- a/internal/netlink/netlink.go
+++ b/internal/netlink/netlink.go
@@ -143,28 +143,13 @@ type Complete struct{}
// Error returns a hardcoded string that should never be displayed to the user.
func (Complete) Error() string { return "returning from roundtrip" }
-// Roundtrip sends the pending message and handles the reply.
-func (c *conn) Roundtrip(f func(msg *syscall.NetlinkMessage) error) error {
- if c.buf == nil {
- return syscall.EINVAL
- }
- defer func() { c.seq++ }()
-
- if err := syscall.Sendto(c.fd, c.pending(), 0, &syscall.SockaddrNetlink{
- Family: syscall.AF_NETLINK,
- }); err != nil {
- return os.NewSyscallError("sendto", err)
- }
-
- return c.receive(f, 0)
-}
+// HandlerFunc handles [syscall.NetlinkMessage] and returns a non-nil error to
+// discontinue the receiving of more messages.
+type HandlerFunc func(resp []syscall.NetlinkMessage) error
// receive receives from a socket with specified flags until a non-nil error is
// returned by f. An error of type [Complete] is returned as nil.
-func (c *conn) receive(
- f func(msg *syscall.NetlinkMessage) error,
- flags int,
-) error {
+func (c *conn) receive(f HandlerFunc, flags int) error {
for {
buf := c.buf
if n, _, err := syscall.Recvfrom(c.fd, buf, flags); err != nil {
@@ -175,21 +160,38 @@ func (c *conn) receive(
buf = buf[:n]
}
- msgs, err := syscall.ParseNetlinkMessage(buf)
+ resp, err := syscall.ParseNetlinkMessage(buf)
if err != nil {
return err
}
- for _, msg := range msgs {
- if msg.Header.Seq != c.seq || msg.Header.Pid != getpid() {
- return &InconsistentError{msg.Header, c.seq, getpid()}
+ for i := range resp {
+ header := &resp[i].Header
+ if header.Seq != c.seq || header.Pid != getpid() {
+ return &InconsistentError{*header, c.seq, getpid()}
}
- if err = f(&msg); err != nil {
- if err == (Complete{}) {
- return nil
- }
- return err
+ }
+ if err = f(resp); err != nil {
+ if err == (Complete{}) {
+ return nil
}
+ return err
}
}
}
+
+// Roundtrip sends the pending message and handles the reply.
+func (c *conn) Roundtrip(f HandlerFunc) error {
+ if c.buf == nil {
+ return syscall.EINVAL
+ }
+ defer func() { c.seq++ }()
+
+ if err := syscall.Sendto(c.fd, c.pending(), 0, &syscall.SockaddrNetlink{
+ Family: syscall.AF_NETLINK,
+ }); err != nil {
+ return os.NewSyscallError("sendto", err)
+ }
+
+ return c.receive(f, 0)
+}