diff options
Diffstat (limited to 'internal/netlink/netlink.go')
| -rw-r--r-- | internal/netlink/netlink.go | 58 |
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) +} |
