60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
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
|
|
}
|