mirror of https://github.com/vishvananda/netlink
handle: get/set receive buffer size
When receiving a lot of route changes (10,000 routes are enough), the default receive buffer size (value of `/proc/sys/net/core/rmem_default`) is too small and we get a `ENOBUF` error. A user may want to increase the buffer size up to the value of `/proc/sys/net/core/rmem_max` (by default, this is the same value). A `SetSocketReceiveBufferSize()` function is provided to this destination. Possible improvements: 1. automatically increase receive buffer size in higher level functions until we hit a maximum (get an error and/or the current value is smaller than expected) 2. accept a "force" argument to use `SO_RCVBUFFORCE` to increase the value over `rmem_max` value
This commit is contained in:
parent
ef2b2c42e6
commit
ef84ebb87b
|
@ -55,6 +55,38 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSocketReceiveBufferSize sets the receive buffer size for each
|
||||||
|
// socket in the netlink handle. The maximum value is capped by
|
||||||
|
// /proc/sys/net/core/rmem_max.
|
||||||
|
func (h *Handle) SetSocketReceiveBufferSize(size int) error {
|
||||||
|
for _, sh := range h.sockets {
|
||||||
|
fd := sh.Socket.GetFd()
|
||||||
|
err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, size)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSocketReceiveBufferSize gets the receiver buffer size for each
|
||||||
|
// socket in the netlink handle. The retrieved value should be the
|
||||||
|
// double to the one set for SetSocketReceiveBufferSize.
|
||||||
|
func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
|
||||||
|
results := make([]int, len(h.sockets))
|
||||||
|
i := 0
|
||||||
|
for _, sh := range h.sockets {
|
||||||
|
fd := sh.Socket.GetFd()
|
||||||
|
size, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results[i] = size
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewHandle returns a netlink handle on the network namespace
|
// NewHandle returns a netlink handle on the network namespace
|
||||||
// specified by ns. If ns=netns.None(), current network namespace
|
// specified by ns. If ns=netns.None(), current network namespace
|
||||||
// will be assumed
|
// will be assumed
|
||||||
|
|
|
@ -132,6 +132,31 @@ func TestHandleTimeout(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandleReceiveBuffer(t *testing.T) {
|
||||||
|
h, err := NewHandle()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer h.Delete()
|
||||||
|
if err := h.SetSocketReceiveBufferSize(65536); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
sizes, err := h.GetSocketReceiveBufferSize()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(sizes) != len(h.sockets) {
|
||||||
|
t.Fatalf("Unexpected number of socket buffer sizes: %d (expected %d)",
|
||||||
|
len(sizes), len(h.sockets))
|
||||||
|
}
|
||||||
|
for _, s := range sizes {
|
||||||
|
if s < 65536 || s > 2*65536 {
|
||||||
|
t.Fatalf("Unexpected socket receive buffer size: %d (expected around %d)",
|
||||||
|
s, 65536)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func verifySockTimeVal(t *testing.T, fd int, tv syscall.Timeval) {
|
func verifySockTimeVal(t *testing.T, fd int, tv syscall.Timeval) {
|
||||||
var (
|
var (
|
||||||
tr syscall.Timeval
|
tr syscall.Timeval
|
||||||
|
|
Loading…
Reference in New Issue