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
|
||||
}
|
||||
|
||||
// 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
|
||||
// specified by ns. If ns=netns.None(), current network namespace
|
||||
// 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) {
|
||||
var (
|
||||
tr syscall.Timeval
|
||||
|
|
Loading…
Reference in New Issue