From d59375d82e6301c08634e5d38c424fcf728ccda5 Mon Sep 17 00:00:00 2001 From: Etienne Perot Date: Sat, 29 Jun 2024 05:08:21 -0700 Subject: [PATCH] Break `//pkg/tcpip/link/rawfile`'s dep on `//pkg/tcpip` & move it to `//pkg`. `//pkg/tcpip/link/rawfile` is a package to deal with raw socket and file FDs. It is not only used for Netstack, but rather just generally useful raw file manipulation stuff. This change removes the Unix-error-to-`//pkg/tcpip`-error translation step from its functions; this is now the responsibility of its callers. Callers within Netstack now do the translation by themselves; the translation function is moved to `//pkg/tcpip`. This allows the `//pkg/tcpip/link/rawfile` package to not depend on `//pkg/tcpip`, which in turn means the `//pkg/eventfd` package (which depends on `rawfile`) no longer transitively depends on `//pkg/tcpip`, which in turns means the `//pkg/unet` package (which depends on `//pkg/eventfd`) no longer transitively depends on `//pkg/tcpip`, which in turns means that the `//pkg/eventchannel` package (which depends on `//pkg/unet`) no longer transitively depends on `//pkg/tcpip`, which in turns means that the `//pkg/metric` package (which depends on `//pkg/eventchannel`) no longer transitively depends on `//pkg/tcpip`, which finally means that the `//pkg/metric` package can be used within `//pkg/tcpip`. \o/ This changes does not make it use it, it just moves `rawfile`. PiperOrigin-RevId: 647943618 --- pkg/eventfd/BUILD | 2 +- pkg/eventfd/eventfd.go | 8 +-- pkg/rawfile/BUILD | 19 ++++++ .../link => }/rawfile/blockingpoll_amd64.s | 0 .../link => }/rawfile/blockingpoll_arm64.s | 0 .../rawfile/blockingpoll_noyield_unsafe.go | 0 .../rawfile/blockingpoll_yield_unsafe.go | 0 .../link => }/rawfile/rawfile_unsafe.go | 65 ++++++------------- pkg/tcpip/BUILD | 13 +++- pkg/tcpip/errors.go | 2 + .../rawfile/errors.go => errors_linux.go} | 55 ++++++++-------- pkg/tcpip/{link/rawfile => }/errors_test.go | 15 ++--- pkg/tcpip/link/fdbased/BUILD | 2 +- pkg/tcpip/link/fdbased/endpoint.go | 18 +++-- pkg/tcpip/link/fdbased/mmap.go | 4 +- pkg/tcpip/link/fdbased/packet_dispatchers.go | 17 +++-- pkg/tcpip/link/rawfile/BUILD | 36 ---------- pkg/tcpip/link/sharedmem/BUILD | 2 +- pkg/tcpip/link/sharedmem/sharedmem.go | 10 ++- pkg/tcpip/link/sharedmem/sharedmem_server.go | 10 ++- pkg/tcpip/link/xdp/BUILD | 2 +- pkg/tcpip/link/xdp/endpoint.go | 4 +- pkg/tcpip/sample/tun_tcp_connect/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_connect/main.go | 2 +- pkg/tcpip/sample/tun_tcp_echo/BUILD | 2 +- pkg/tcpip/sample/tun_tcp_echo/main.go | 2 +- 26 files changed, 137 insertions(+), 155 deletions(-) create mode 100644 pkg/rawfile/BUILD rename pkg/{tcpip/link => }/rawfile/blockingpoll_amd64.s (100%) rename pkg/{tcpip/link => }/rawfile/blockingpoll_arm64.s (100%) rename pkg/{tcpip/link => }/rawfile/blockingpoll_noyield_unsafe.go (100%) rename pkg/{tcpip/link => }/rawfile/blockingpoll_yield_unsafe.go (100%) rename pkg/{tcpip/link => }/rawfile/rawfile_unsafe.go (82%) rename pkg/tcpip/{link/rawfile/errors.go => errors_linux.go} (55%) rename pkg/tcpip/{link/rawfile => }/errors_test.go (79%) delete mode 100644 pkg/tcpip/link/rawfile/BUILD diff --git a/pkg/eventfd/BUILD b/pkg/eventfd/BUILD index bb8cb18ce..f4197109b 100644 --- a/pkg/eventfd/BUILD +++ b/pkg/eventfd/BUILD @@ -17,7 +17,7 @@ go_library( ], deps = [ "//pkg/hostarch", - "//pkg/tcpip/link/rawfile", + "//pkg/rawfile", "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/eventfd/eventfd.go b/pkg/eventfd/eventfd.go index 3a5197ea4..1e80be502 100644 --- a/pkg/eventfd/eventfd.go +++ b/pkg/eventfd/eventfd.go @@ -21,7 +21,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/hostarch" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" + "gvisor.dev/gvisor/pkg/rawfile" ) const sizeofUint64 = 8 @@ -95,9 +95,9 @@ func (ev Eventfd) Wait() error { // and returns the value read. func (ev Eventfd) Read() (uint64, error) { var tmp [sizeofUint64]byte - n, err := rawfile.BlockingReadUntranslated(ev.fd, tmp[:]) - if err != 0 { - return 0, err + n, errno := rawfile.BlockingRead(ev.fd, tmp[:]) + if errno != 0 { + return 0, errno } if n == 0 { return 0, io.EOF diff --git a/pkg/rawfile/BUILD b/pkg/rawfile/BUILD new file mode 100644 index 000000000..e6fbedb31 --- /dev/null +++ b/pkg/rawfile/BUILD @@ -0,0 +1,19 @@ +load("//tools:defs.bzl", "go_library") + +package( + default_applicable_licenses = ["//:license"], + licenses = ["notice"], +) + +go_library( + name = "rawfile", + srcs = [ + "blockingpoll_amd64.s", + "blockingpoll_arm64.s", + "blockingpoll_noyield_unsafe.go", + "blockingpoll_yield_unsafe.go", + "rawfile_unsafe.go", + ], + visibility = ["//visibility:public"], + deps = ["@org_golang_x_sys//unix:go_default_library"], +) diff --git a/pkg/tcpip/link/rawfile/blockingpoll_amd64.s b/pkg/rawfile/blockingpoll_amd64.s similarity index 100% rename from pkg/tcpip/link/rawfile/blockingpoll_amd64.s rename to pkg/rawfile/blockingpoll_amd64.s diff --git a/pkg/tcpip/link/rawfile/blockingpoll_arm64.s b/pkg/rawfile/blockingpoll_arm64.s similarity index 100% rename from pkg/tcpip/link/rawfile/blockingpoll_arm64.s rename to pkg/rawfile/blockingpoll_arm64.s diff --git a/pkg/tcpip/link/rawfile/blockingpoll_noyield_unsafe.go b/pkg/rawfile/blockingpoll_noyield_unsafe.go similarity index 100% rename from pkg/tcpip/link/rawfile/blockingpoll_noyield_unsafe.go rename to pkg/rawfile/blockingpoll_noyield_unsafe.go diff --git a/pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go b/pkg/rawfile/blockingpoll_yield_unsafe.go similarity index 100% rename from pkg/tcpip/link/rawfile/blockingpoll_yield_unsafe.go rename to pkg/rawfile/blockingpoll_yield_unsafe.go diff --git a/pkg/tcpip/link/rawfile/rawfile_unsafe.go b/pkg/rawfile/rawfile_unsafe.go similarity index 82% rename from pkg/tcpip/link/rawfile/rawfile_unsafe.go rename to pkg/rawfile/rawfile_unsafe.go index 6fd17a0bd..4ec671ae4 100644 --- a/pkg/tcpip/link/rawfile/rawfile_unsafe.go +++ b/pkg/rawfile/rawfile_unsafe.go @@ -15,8 +15,7 @@ //go:build linux // +build linux -// Package rawfile contains utilities for using the netstack with raw host -// files on Linux hosts. +// Package rawfile contains utilities for using raw host files on Linux hosts. package rawfile import ( @@ -24,7 +23,6 @@ import ( "unsafe" "golang.org/x/sys/unix" - "gvisor.dev/gvisor/pkg/tcpip" ) // SizeofIovec is the size of a unix.Iovec in bytes. @@ -106,39 +104,28 @@ func GetMTU(name string) (uint32, error) { // NonBlockingWrite writes the given buffer to a file descriptor. It fails if // partial data is written. -func NonBlockingWrite(fd int, buf []byte) tcpip.Error { +func NonBlockingWrite(fd int, buf []byte) unix.Errno { var ptr unsafe.Pointer if len(buf) > 0 { ptr = unsafe.Pointer(&buf[0]) } _, _, e := unix.RawSyscall(unix.SYS_WRITE, uintptr(fd), uintptr(ptr), uintptr(len(buf))) - if e != 0 { - return TranslateErrno(e) - } - - return nil + return e } // NonBlockingWriteIovec writes iovec to a file descriptor in a single unix. // It fails if partial data is written. -func NonBlockingWriteIovec(fd int, iovec []unix.Iovec) tcpip.Error { +func NonBlockingWriteIovec(fd int, iovec []unix.Iovec) unix.Errno { iovecLen := uintptr(len(iovec)) _, _, e := unix.RawSyscall(unix.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovec[0])), iovecLen) - if e != 0 { - return TranslateErrno(e) - } - return nil + return e } // NonBlockingSendMMsg sends multiple messages on a socket. -func NonBlockingSendMMsg(fd int, msgHdrs []MMsgHdr) (int, tcpip.Error) { +func NonBlockingSendMMsg(fd int, msgHdrs []MMsgHdr) (int, unix.Errno) { n, _, e := unix.RawSyscall6(unix.SYS_SENDMMSG, uintptr(fd), uintptr(unsafe.Pointer(&msgHdrs[0])), uintptr(len(msgHdrs)), unix.MSG_DONTWAIT, 0, 0) - if e != 0 { - return 0, TranslateErrno(e) - } - - return int(n), nil + return int(n), e } // PollEvent represents the pollfd structure passed to a poll() system call. @@ -148,22 +135,10 @@ type PollEvent struct { Revents int16 } -// BlockingRead reads from a file descriptor that is set up as non-blocking. If -// no data is available, it will block in a poll() syscall until the file +// BlockingRead reads from a file descriptor that is set up as non-blocking. +// If no data is available, it will block in a poll() syscall until the file // descriptor becomes readable. -func BlockingRead(fd int, b []byte) (int, tcpip.Error) { - n, err := BlockingReadUntranslated(fd, b) - if err != 0 { - return n, TranslateErrno(err) - } - return n, nil -} - -// BlockingReadUntranslated reads from a file descriptor that is set up as -// non-blocking. If no data is available, it will block in a poll() syscall -// until the file descriptor becomes readable. It returns the raw unix.Errno -// value returned by the underlying syscalls. -func BlockingReadUntranslated(fd int, b []byte) (int, unix.Errno) { +func BlockingRead(fd int, b []byte) (int, unix.Errno) { for { n, _, e := unix.RawSyscall(unix.SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))) if e == 0 { @@ -187,21 +162,21 @@ func BlockingReadUntranslated(fd int, b []byte) (int, unix.Errno) { // available, it will block in a poll() syscall until the file descriptor // becomes readable or stop is signalled (efd becomes readable). Returns -1 in // the latter case. -func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, tcpip.Error) { +func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, unix.Errno) { for { n, _, e := unix.RawSyscall(unix.SYS_READV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs))) if e == 0 { - return int(n), nil + return int(n), 0 } if e != 0 && e != unix.EWOULDBLOCK { - return 0, TranslateErrno(e) + return 0, e } stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN) if stopped { - return -1, nil + return -1, e } if e != 0 && e != unix.EINTR { - return 0, TranslateErrno(e) + return 0, e } } } @@ -211,23 +186,23 @@ func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, tcpip // structures. If no data is available, it will block in a poll() syscall until // the file descriptor becomes readable or stop is signalled (efd becomes // readable). Returns -1 in the latter case. -func BlockingRecvMMsgUntilStopped(efd int, fd int, msgHdrs []MMsgHdr) (int, tcpip.Error) { +func BlockingRecvMMsgUntilStopped(efd int, fd int, msgHdrs []MMsgHdr) (int, unix.Errno) { for { n, _, e := unix.RawSyscall6(unix.SYS_RECVMMSG, uintptr(fd), uintptr(unsafe.Pointer(&msgHdrs[0])), uintptr(len(msgHdrs)), unix.MSG_DONTWAIT, 0, 0) if e == 0 { - return int(n), nil + return int(n), e } if e != 0 && e != unix.EWOULDBLOCK { - return 0, TranslateErrno(e) + return 0, e } stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN) if stopped { - return -1, nil + return -1, e } if e != 0 && e != unix.EINTR { - return 0, TranslateErrno(e) + return 0, e } } } diff --git a/pkg/tcpip/BUILD b/pkg/tcpip/BUILD index 33baa5ff9..9e4e0b8cf 100644 --- a/pkg/tcpip/BUILD +++ b/pkg/tcpip/BUILD @@ -35,6 +35,7 @@ go_library( name = "tcpip", srcs = [ "errors.go", + "errors_linux.go", "route_list.go", "sock_err_list.go", "socketops.go", @@ -50,6 +51,7 @@ go_library( "//pkg/buffer", "//pkg/sync", "//pkg/waiter", + "@org_golang_x_sys//unix:go_default_library", ], ) @@ -75,6 +77,7 @@ deps_test( "//pkg/log", "//pkg/pool", "//pkg/rand", + "//pkg/rawfile", "//pkg/refs", "//pkg/sleep", "//pkg/state", @@ -117,9 +120,15 @@ deps_test( go_test( name = "tcpip_test", size = "small", - srcs = ["tcpip_test.go"], + srcs = [ + "errors_test.go", + "tcpip_test.go", + ], library = ":tcpip", - deps = ["@com_github_google_go_cmp//cmp:go_default_library"], + deps = [ + "@com_github_google_go_cmp//cmp:go_default_library", + "@org_golang_x_sys//unix:go_default_library", + ], ) go_test( diff --git a/pkg/tcpip/errors.go b/pkg/tcpip/errors.go index 8d11bba76..0df3d8857 100644 --- a/pkg/tcpip/errors.go +++ b/pkg/tcpip/errors.go @@ -32,6 +32,8 @@ type Error interface { fmt.Stringer } +const maxErrno = 134 + // LINT.IfChange // ErrAborted indicates the operation was aborted. diff --git a/pkg/tcpip/link/rawfile/errors.go b/pkg/tcpip/errors_linux.go similarity index 55% rename from pkg/tcpip/link/rawfile/errors.go rename to pkg/tcpip/errors_linux.go index e21b4bf28..0073568b2 100644 --- a/pkg/tcpip/link/rawfile/errors.go +++ b/pkg/tcpip/errors_linux.go @@ -1,4 +1,4 @@ -// Copyright 2018 The gVisor Authors. +// Copyright 2024 The gVisor Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,63 +15,60 @@ //go:build linux // +build linux -package rawfile +package tcpip import ( "golang.org/x/sys/unix" - "gvisor.dev/gvisor/pkg/tcpip" ) -const maxErrno = 134 - // TranslateErrno translate an errno from the syscall package into a -// tcpip.Error. +// tcpip Error. // // Valid, but unrecognized errnos will be translated to -// *tcpip.ErrInvalidEndpointState (EINVAL). -func TranslateErrno(e unix.Errno) tcpip.Error { +// *ErrInvalidEndpointState (EINVAL). This includes the "zero" value. +func TranslateErrno(e unix.Errno) Error { switch e { case unix.EEXIST: - return &tcpip.ErrDuplicateAddress{} + return &ErrDuplicateAddress{} case unix.ENETUNREACH: - return &tcpip.ErrHostUnreachable{} + return &ErrHostUnreachable{} case unix.EINVAL: - return &tcpip.ErrInvalidEndpointState{} + return &ErrInvalidEndpointState{} case unix.EALREADY: - return &tcpip.ErrAlreadyConnecting{} + return &ErrAlreadyConnecting{} case unix.EISCONN: - return &tcpip.ErrAlreadyConnected{} + return &ErrAlreadyConnected{} case unix.EADDRINUSE: - return &tcpip.ErrPortInUse{} + return &ErrPortInUse{} case unix.EADDRNOTAVAIL: - return &tcpip.ErrBadLocalAddress{} + return &ErrBadLocalAddress{} case unix.EPIPE: - return &tcpip.ErrClosedForSend{} + return &ErrClosedForSend{} case unix.EWOULDBLOCK: - return &tcpip.ErrWouldBlock{} + return &ErrWouldBlock{} case unix.ECONNREFUSED: - return &tcpip.ErrConnectionRefused{} + return &ErrConnectionRefused{} case unix.ETIMEDOUT: - return &tcpip.ErrTimeout{} + return &ErrTimeout{} case unix.EINPROGRESS: - return &tcpip.ErrConnectStarted{} + return &ErrConnectStarted{} case unix.EDESTADDRREQ: - return &tcpip.ErrDestinationRequired{} + return &ErrDestinationRequired{} case unix.ENOTSUP: - return &tcpip.ErrNotSupported{} + return &ErrNotSupported{} case unix.ENOTTY: - return &tcpip.ErrQueueSizeNotSupported{} + return &ErrQueueSizeNotSupported{} case unix.ENOTCONN: - return &tcpip.ErrNotConnected{} + return &ErrNotConnected{} case unix.ECONNRESET: - return &tcpip.ErrConnectionReset{} + return &ErrConnectionReset{} case unix.ECONNABORTED: - return &tcpip.ErrConnectionAborted{} + return &ErrConnectionAborted{} case unix.EMSGSIZE: - return &tcpip.ErrMessageTooLong{} + return &ErrMessageTooLong{} case unix.ENOBUFS: - return &tcpip.ErrNoBufferSpace{} + return &ErrNoBufferSpace{} default: - return &tcpip.ErrInvalidEndpointState{} + return &ErrInvalidEndpointState{} } } diff --git a/pkg/tcpip/link/rawfile/errors_test.go b/pkg/tcpip/errors_test.go similarity index 79% rename from pkg/tcpip/link/rawfile/errors_test.go rename to pkg/tcpip/errors_test.go index 1b88c309b..86233439a 100644 --- a/pkg/tcpip/link/rawfile/errors_test.go +++ b/pkg/tcpip/errors_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 The gVisor Authors. +// Copyright 2024 The gVisor Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,36 +15,35 @@ //go:build linux // +build linux -package rawfile +package tcpip import ( "testing" "github.com/google/go-cmp/cmp" "golang.org/x/sys/unix" - "gvisor.dev/gvisor/pkg/tcpip" ) func TestTranslateErrno(t *testing.T) { for _, test := range []struct { errno unix.Errno - translated tcpip.Error + translated Error }{ { errno: unix.Errno(0), - translated: &tcpip.ErrInvalidEndpointState{}, + translated: &ErrInvalidEndpointState{}, }, { errno: unix.Errno(maxErrno), - translated: &tcpip.ErrInvalidEndpointState{}, + translated: &ErrInvalidEndpointState{}, }, { errno: unix.Errno(514), - translated: &tcpip.ErrInvalidEndpointState{}, + translated: &ErrInvalidEndpointState{}, }, { errno: unix.EEXIST, - translated: &tcpip.ErrDuplicateAddress{}, + translated: &ErrDuplicateAddress{}, }, } { got := TranslateErrno(test.errno) diff --git a/pkg/tcpip/link/fdbased/BUILD b/pkg/tcpip/link/fdbased/BUILD index 8bb1ca63d..0f82177ce 100644 --- a/pkg/tcpip/link/fdbased/BUILD +++ b/pkg/tcpip/link/fdbased/BUILD @@ -21,12 +21,12 @@ go_library( "//pkg/atomicbitops", "//pkg/buffer", "//pkg/rand", + "//pkg/rawfile", "//pkg/sleep", "//pkg/sync", "//pkg/tcpip", "//pkg/tcpip/hash/jenkins", "//pkg/tcpip/header", - "//pkg/tcpip/link/rawfile", "//pkg/tcpip/link/stopfd", "//pkg/tcpip/stack", "//pkg/tcpip/stack/gro", diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 431c0fdeb..18cc40009 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -47,10 +47,10 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/atomicbitops" "gvisor.dev/gvisor/pkg/buffer" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -622,7 +622,10 @@ func (e *endpoint) writePacket(pkt *stack.PacketBuffer) tcpip.Error { for _, v := range views { iovecs = rawfile.AppendIovecFromBytes(iovecs, v, numIovecs) } - return rawfile.NonBlockingWriteIovec(fd, iovecs) + if errno := rawfile.NonBlockingWriteIovec(fd, iovecs); errno != 0 { + return tcpip.TranslateErrno(errno) + } + return nil } func (e *endpoint) sendBatch(batchFDInfo fdInfo, pkts []*stack.PacketBuffer) (int, tcpip.Error) { @@ -729,9 +732,9 @@ func (e *endpoint) sendBatch(batchFDInfo fdInfo, pkts []*stack.PacketBuffer) (in packets++ } else { for len(mmsgHdrs) > 0 { - sent, err := rawfile.NonBlockingSendMMsg(batchFD, mmsgHdrs) - if err != nil { - return packets, err + sent, errno := rawfile.NonBlockingSendMMsg(batchFD, mmsgHdrs) + if errno != 0 { + return packets, tcpip.TranslateErrno(errno) } packets += sent mmsgHdrs = mmsgHdrs[sent:] @@ -786,7 +789,10 @@ func (e *endpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) // InjectOutbound implements stack.InjectableEndpoint.InjectOutbound. func (e *endpoint) InjectOutbound(dest tcpip.Address, packet *buffer.View) tcpip.Error { - return rawfile.NonBlockingWrite(e.fds[0].fd, packet.AsSlice()) + if errno := rawfile.NonBlockingWrite(e.fds[0].fd, packet.AsSlice()); errno != 0 { + return tcpip.TranslateErrno(errno) + } + return nil } // dispatchLoop reads packets from the file descriptor in a loop and dispatches diff --git a/pkg/tcpip/link/fdbased/mmap.go b/pkg/tcpip/link/fdbased/mmap.go index 6473e95a3..802d36cc7 100644 --- a/pkg/tcpip/link/fdbased/mmap.go +++ b/pkg/tcpip/link/fdbased/mmap.go @@ -23,9 +23,9 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/buffer" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/stopfd" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -148,7 +148,7 @@ func (d *packetMMapDispatcher) readMMappedPackets() (stack.PacketBufferList, boo if errno == unix.EINTR { continue } - return pkts, stopped, rawfile.TranslateErrno(errno) + return pkts, stopped, tcpip.TranslateErrno(errno) } if stopped { return pkts, true, nil diff --git a/pkg/tcpip/link/fdbased/packet_dispatchers.go b/pkg/tcpip/link/fdbased/packet_dispatchers.go index 95d19dd97..b2883b838 100644 --- a/pkg/tcpip/link/fdbased/packet_dispatchers.go +++ b/pkg/tcpip/link/fdbased/packet_dispatchers.go @@ -20,9 +20,9 @@ package fdbased import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/buffer" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/stopfd" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/stack/gro" @@ -184,9 +184,9 @@ func (d *readVDispatcher) release() { // dispatch reads one packet from the file descriptor and dispatches it. func (d *readVDispatcher) dispatch() (bool, tcpip.Error) { - n, err := rawfile.BlockingReadvUntilStopped(d.EFD, d.fd, d.buf.nextIovecs()) - if n <= 0 || err != nil { - return false, err + n, errno := rawfile.BlockingReadvUntilStopped(d.EFD, d.fd, d.buf.nextIovecs()) + if n <= 0 || errno != 0 { + return false, tcpip.TranslateErrno(errno) } pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ @@ -285,9 +285,12 @@ func (d *recvMMsgDispatcher) dispatch() (bool, tcpip.Error) { d.msgHdrs[k].Msg.SetIovlen(iovLen) } - nMsgs, err := rawfile.BlockingRecvMMsgUntilStopped(d.EFD, d.fd, d.msgHdrs) - if nMsgs == -1 || err != nil { - return false, err + nMsgs, errno := rawfile.BlockingRecvMMsgUntilStopped(d.EFD, d.fd, d.msgHdrs) + if errno != 0 { + return false, tcpip.TranslateErrno(errno) + } + if nMsgs == -1 { + return false, nil } // Process each of received packets. diff --git a/pkg/tcpip/link/rawfile/BUILD b/pkg/tcpip/link/rawfile/BUILD deleted file mode 100644 index 3d7d142ce..000000000 --- a/pkg/tcpip/link/rawfile/BUILD +++ /dev/null @@ -1,36 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -package( - default_applicable_licenses = ["//:license"], - licenses = ["notice"], -) - -go_library( - name = "rawfile", - srcs = [ - "blockingpoll_amd64.s", - "blockingpoll_arm64.s", - "blockingpoll_noyield_unsafe.go", - "blockingpoll_yield_unsafe.go", - "errors.go", - "rawfile_unsafe.go", - ], - visibility = ["//visibility:public"], - deps = [ - "//pkg/tcpip", - "@org_golang_x_sys//unix:go_default_library", - ], -) - -go_test( - name = "rawfile_test", - srcs = [ - "errors_test.go", - ], - library = "rawfile", - deps = [ - "//pkg/tcpip", - "@com_github_google_go_cmp//cmp:go_default_library", - "@org_golang_x_sys//unix:go_default_library", - ], -) diff --git a/pkg/tcpip/link/sharedmem/BUILD b/pkg/tcpip/link/sharedmem/BUILD index 3ff4dfcb8..79baff878 100644 --- a/pkg/tcpip/link/sharedmem/BUILD +++ b/pkg/tcpip/link/sharedmem/BUILD @@ -27,10 +27,10 @@ go_library( "//pkg/eventfd", "//pkg/log", "//pkg/memutil", + "//pkg/rawfile", "//pkg/sync", "//pkg/tcpip", "//pkg/tcpip/header", - "//pkg/tcpip/link/rawfile", "//pkg/tcpip/link/sharedmem/pipe", "//pkg/tcpip/link/sharedmem/queue", "//pkg/tcpip/stack", diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 3c6845fb2..751aa7ca2 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -30,10 +30,10 @@ import ( "gvisor.dev/gvisor/pkg/buffer" "gvisor.dev/gvisor/pkg/eventfd" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/sharedmem/queue" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -300,9 +300,13 @@ func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) { b := make([]byte, 1) // When sharedmem endpoint is in use the peerFD is never used for any data // transfer and this Read should only return if the peer is shutting down. - _, err := rawfile.BlockingRead(e.peerFD, b) + _, errno := rawfile.BlockingRead(e.peerFD, b) if e.onClosed != nil { - e.onClosed(err) + if errno == 0 { + e.onClosed(nil) + } else { + e.onClosed(tcpip.TranslateErrno(errno)) + } } }() } diff --git a/pkg/tcpip/link/sharedmem/sharedmem_server.go b/pkg/tcpip/link/sharedmem/sharedmem_server.go index 82f8d452a..53bfcfbaf 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_server.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_server.go @@ -20,10 +20,10 @@ package sharedmem import ( "gvisor.dev/gvisor/pkg/atomicbitops" "gvisor.dev/gvisor/pkg/buffer" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -158,9 +158,13 @@ func (e *serverEndpoint) Attach(dispatcher stack.NetworkDispatcher) { // When sharedmem endpoint is in use the peerFD is never used for any // data transfer and this Read should only return if the peer is // shutting down. - _, err := rawfile.BlockingRead(e.peerFD, b) + _, errno := rawfile.BlockingRead(e.peerFD, b) if e.onClosed != nil { - e.onClosed(err) + if errno == 0 { + e.onClosed(nil) + } else { + e.onClosed(tcpip.TranslateErrno(errno)) + } } e.completed.Done() }() diff --git a/pkg/tcpip/link/xdp/BUILD b/pkg/tcpip/link/xdp/BUILD index cc3cf69f1..a8a309315 100644 --- a/pkg/tcpip/link/xdp/BUILD +++ b/pkg/tcpip/link/xdp/BUILD @@ -13,11 +13,11 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/buffer", + "//pkg/rawfile", "//pkg/sync", "//pkg/tcpip", "//pkg/tcpip/header", "//pkg/tcpip/link/qdisc/fifo", - "//pkg/tcpip/link/rawfile", "//pkg/tcpip/link/stopfd", "//pkg/tcpip/stack", "//pkg/xdp", diff --git a/pkg/tcpip/link/xdp/endpoint.go b/pkg/tcpip/link/xdp/endpoint.go index a9edc966f..df47588f8 100644 --- a/pkg/tcpip/link/xdp/endpoint.go +++ b/pkg/tcpip/link/xdp/endpoint.go @@ -23,11 +23,11 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/buffer" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/link/qdisc/fifo" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/stopfd" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/xdp" @@ -351,7 +351,7 @@ func (ep *endpoint) dispatch() (bool, tcpip.Error) { if errno == unix.EINTR { continue } - return !stopped, rawfile.TranslateErrno(errno) + return !stopped, tcpip.TranslateErrno(errno) } if stopped { return true, nil diff --git a/pkg/tcpip/sample/tun_tcp_connect/BUILD b/pkg/tcpip/sample/tun_tcp_connect/BUILD index b2737716a..2cde413b8 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/BUILD +++ b/pkg/tcpip/sample/tun_tcp_connect/BUILD @@ -10,10 +10,10 @@ go_binary( srcs = ["main.go"], visibility = ["//:sandbox"], deps = [ + "//pkg/rawfile", "//pkg/tcpip", "//pkg/tcpip/header", "//pkg/tcpip/link/fdbased", - "//pkg/tcpip/link/rawfile", "//pkg/tcpip/link/sniffer", "//pkg/tcpip/link/tun", "//pkg/tcpip/network/ipv4", diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go index 6f600e64e..fa47c233e 100644 --- a/pkg/tcpip/sample/tun_tcp_connect/main.go +++ b/pkg/tcpip/sample/tun_tcp_connect/main.go @@ -51,10 +51,10 @@ import ( "strconv" "time" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/link/fdbased" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/sniffer" "gvisor.dev/gvisor/pkg/tcpip/link/tun" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" diff --git a/pkg/tcpip/sample/tun_tcp_echo/BUILD b/pkg/tcpip/sample/tun_tcp_echo/BUILD index 5268dbe28..6af02a7cb 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/BUILD +++ b/pkg/tcpip/sample/tun_tcp_echo/BUILD @@ -10,9 +10,9 @@ go_binary( srcs = ["main.go"], visibility = ["//:sandbox"], deps = [ + "//pkg/rawfile", "//pkg/tcpip", "//pkg/tcpip/link/fdbased", - "//pkg/tcpip/link/rawfile", "//pkg/tcpip/link/tun", "//pkg/tcpip/network/arp", "//pkg/tcpip/network/ipv4", diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go index 8644df376..e53c7948d 100644 --- a/pkg/tcpip/sample/tun_tcp_echo/main.go +++ b/pkg/tcpip/sample/tun_tcp_echo/main.go @@ -32,9 +32,9 @@ import ( "strings" "time" + "gvisor.dev/gvisor/pkg/rawfile" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/link/fdbased" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/tun" "gvisor.dev/gvisor/pkg/tcpip/network/arp" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4"