Raise netlink buffers for large batches; restore snapshot when try apply fails
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package nftables
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mdlayher/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestLargeBuffersRaisesSocketBuffers(t *testing.T) {
|
||||
c, err := netlink.Dial(unix.NETLINK_NETFILTER, nil)
|
||||
if err != nil {
|
||||
t.Skipf("netlink unavailable: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
if err := largeBuffers(c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Without CAP_NET_ADMIN the kernel caps at the sysctl max; it doubles either way.
|
||||
for opt, sysctl := range map[int]string{unix.SO_RCVBUF: "rmem_max", unix.SO_SNDBUF: "wmem_max"} {
|
||||
want := 2 * min(batchBufSize, procInt(t, "/proc/sys/net/core/"+sysctl))
|
||||
if got := sockBuf(t, c, opt); got < want {
|
||||
t.Errorf("%s-bounded buffer = %d, want >= %d", sysctl, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func procInt(t *testing.T, path string) int {
|
||||
t.Helper()
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Skipf("reading %s: %v", path, err)
|
||||
}
|
||||
v, err := strconv.Atoi(strings.TrimSpace(string(b)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func sockBuf(t *testing.T, c *netlink.Conn, opt int) int {
|
||||
t.Helper()
|
||||
rc, err := c.SyscallConn()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var v int
|
||||
var serr error
|
||||
if err := rc.Control(func(fd uintptr) { v, serr = unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, opt) }); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if serr != nil {
|
||||
t.Fatal(serr)
|
||||
}
|
||||
return v
|
||||
}
|
||||
Reference in New Issue
Block a user