sanity_linux.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. package netnsutils
  2. import (
  3. "errors"
  4. "syscall"
  5. "testing"
  6. "github.com/vishvananda/netns"
  7. "golang.org/x/sys/unix"
  8. "gotest.tools/v3/assert"
  9. )
  10. // AssertSocketSameNetNS makes a best-effort attempt to assert that conn is in
  11. // the same network namespace as the current goroutine's thread.
  12. func AssertSocketSameNetNS(t testing.TB, conn syscall.Conn) {
  13. t.Helper()
  14. sc, err := conn.SyscallConn()
  15. assert.NilError(t, err)
  16. sc.Control(func(fd uintptr) {
  17. srvnsfd, err := unix.IoctlRetInt(int(fd), unix.SIOCGSKNS)
  18. if err != nil {
  19. if errors.Is(err, unix.EPERM) {
  20. t.Log("Cannot determine socket's network namespace. Do we have CAP_NET_ADMIN?")
  21. return
  22. }
  23. if errors.Is(err, unix.ENOSYS) {
  24. t.Log("Cannot query socket's network namespace due to missing kernel support.")
  25. return
  26. }
  27. t.Fatal(err)
  28. }
  29. srvns := netns.NsHandle(srvnsfd)
  30. defer srvns.Close()
  31. curns, err := netns.Get()
  32. assert.NilError(t, err)
  33. defer curns.Close()
  34. if !srvns.Equal(curns) {
  35. t.Fatalf("Socket is in network namespace %s, but test goroutine is in %s", srvns, curns)
  36. }
  37. })
  38. }