Change behavior of Subscribe to non-blocking. Fix test.

When listening for IPv6 address changes, I found that subscribe is not returning when there is message in the socket. After some researching, I found that libnl suggest setting socket to non-blocking when subscribing to groups. (Ref)[https://www.infradead.org/~tgr/libnl/doc/core.html#:~:text=best%20to%20put%20the%20socket%20in%20non-blocking%20mode]

Also fixed test related to BareUDP, which requires "bareudp" kmod. (Ref)[https://www.kernelconfig.io/config_bareudp]
This commit is contained in:
Kuroame
2024-01-08 17:05:08 +08:00
committed by Alessandro Boch
parent 7f562ed576
commit 916f9685fa
9 changed files with 35 additions and 4 deletions

View File

@@ -365,6 +365,9 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
for { for {
msgs, from, err := s.Receive() msgs, from, err := s.Receive()
if err != nil { if err != nil {
if err == syscall.EAGAIN {
continue
}
if cberr != nil { if cberr != nil {
cberr(fmt.Errorf("Receive failed: %v", cberr(fmt.Errorf("Receive failed: %v",
err)) err))

View File

@@ -2427,6 +2427,9 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c
for { for {
msgs, from, err := s.Receive() msgs, from, err := s.Receive()
if err != nil { if err != nil {
if err == syscall.EAGAIN {
continue
}
if cberr != nil { if cberr != nil {
cberr(fmt.Errorf("Receive failed: %v", cberr(fmt.Errorf("Receive failed: %v",
err)) err))

View File

@@ -1607,10 +1607,8 @@ func TestLinkAddDelVxlanFlowBased(t *testing.T) {
} }
func TestLinkAddDelBareUDP(t *testing.T) { func TestLinkAddDelBareUDP(t *testing.T) {
if os.Getenv("CI") == "true" { minKernelRequired(t, 5, 1)
t.Skipf("Fails in CI due to operation not supported (missing kernel module?)") setUpNetlinkTestWithKModule(t, "bareudp")
}
minKernelRequired(t, 5, 8)
tearDown := setUpNetlinkTest(t) tearDown := setUpNetlinkTest(t)
defer tearDown() defer tearDown()
@@ -1637,6 +1635,7 @@ func TestBareUDPCompareToIP(t *testing.T) {
} }
// requires iproute2 >= 5.10 // requires iproute2 >= 5.10
minKernelRequired(t, 5, 9) minKernelRequired(t, 5, 9)
setUpNetlinkTestWithKModule(t, "bareudp")
ns, tearDown := setUpNamedNetlinkTest(t) ns, tearDown := setUpNamedNetlinkTest(t)
defer tearDown() defer tearDown()

View File

@@ -416,6 +416,9 @@ func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <
for { for {
msgs, from, err := s.Receive() msgs, from, err := s.Receive()
if err != nil { if err != nil {
if err == syscall.EAGAIN {
continue
}
if cberr != nil { if cberr != nil {
cberr(err) cberr(err)
} }

View File

@@ -727,6 +727,16 @@ func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Sometimes (socket_linux.go:SocketGet), Subscribe is used to create a socket
// that subscirbed to no groups. So we don't need to set nonblock there.
if len(groups) > 0 {
if err := unix.SetNonblock(fd, true); err != nil {
unix.Close(fd)
return nil, err
}
}
s := &NetlinkSocket{ s := &NetlinkSocket{
fd: int32(fd), fd: int32(fd),
} }

View File

@@ -148,6 +148,9 @@ func ProcEventMonitor(ch chan<- ProcEvent, done <-chan struct{}, errorChan chan<
for { for {
msgs, from, err := s.Receive() msgs, from, err := s.Receive()
if err != nil { if err != nil {
if err == syscall.EAGAIN {
continue
}
errorChan <- err errorChan <- err
return return
} }

View File

@@ -1653,6 +1653,9 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
for { for {
msgs, from, err := s.Receive() msgs, from, err := s.Receive()
if err != nil { if err != nil {
if err == syscall.EAGAIN {
continue
}
if cberr != nil { if cberr != nil {
cberr(fmt.Errorf("Receive failed: %v", cberr(fmt.Errorf("Receive failed: %v",
err)) err))

View File

@@ -433,6 +433,9 @@ loop:
for { for {
msgs, from, err := s.Receive() msgs, from, err := s.Receive()
if err != nil { if err != nil {
if err == syscall.EAGAIN {
continue
}
return err return err
} }
if from.Pid != nl.PidKernel { if from.Pid != nl.PidKernel {

View File

@@ -2,6 +2,7 @@ package netlink
import ( import (
"fmt" "fmt"
"syscall"
"github.com/vishvananda/netlink/nl" "github.com/vishvananda/netlink/nl"
"github.com/vishvananda/netns" "github.com/vishvananda/netns"
@@ -56,6 +57,9 @@ func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error
for { for {
msgs, from, err := s.Receive() msgs, from, err := s.Receive()
if err != nil { if err != nil {
if err == syscall.EAGAIN {
continue
}
errorChan <- err errorChan <- err
return return
} }