summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/tcpip/link/fdbased/endpoint.go57
-rw-r--r--pkg/tcpip/link/fdbased/endpoint_test.go6
-rw-r--r--pkg/tcpip/sample/tun_tcp_connect/main.go5
-rw-r--r--pkg/tcpip/sample/tun_tcp_echo/main.go5
-rw-r--r--runsc/boot/network.go5
5 files changed, 48 insertions, 30 deletions
diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go
index 84439a9ed..6354688e2 100644
--- a/pkg/tcpip/link/fdbased/endpoint.go
+++ b/pkg/tcpip/link/fdbased/endpoint.go
@@ -136,10 +136,9 @@ type Options struct {
//
// Makes fd non-blocking, but does not take ownership of fd, which must remain
// open for the lifetime of the returned endpoint.
-func New(opts *Options) tcpip.LinkEndpointID {
+func New(opts *Options) (tcpip.LinkEndpointID, error) {
if err := syscall.SetNonblock(opts.FD, true); err != nil {
- // TODO : replace panic with an error return.
- panic(fmt.Sprintf("syscall.SetNonblock(%v) failed: %v", opts.FD, err))
+ return 0, fmt.Errorf("syscall.SetNonblock(%v) failed: %v", opts.FD, err)
}
caps := stack.LinkEndpointCapabilities(0)
@@ -175,27 +174,34 @@ func New(opts *Options) tcpip.LinkEndpointID {
packetDispatchMode: opts.PacketDispatchMode,
}
- if opts.GSOMaxSize != 0 && isSocketFD(opts.FD) {
- e.caps |= stack.CapabilityGSO
- e.gsoMaxSize = opts.GSOMaxSize
+ // For non-socket FDs we read one packet a time (e.g. TAP devices).
+ msgsPerRecv := 1
+ e.inboundDispatcher = e.dispatch
+
+ isSocket, err := isSocketFD(opts.FD)
+ if err != nil {
+ return 0, err
}
- if isSocketFD(opts.FD) && e.packetDispatchMode == PacketMMap {
- if err := e.setupPacketRXRing(); err != nil {
- // TODO: replace panic with an error return.
- panic(fmt.Sprintf("e.setupPacketRXRing failed: %v", err))
+ if isSocket {
+ if opts.GSOMaxSize != 0 {
+ e.caps |= stack.CapabilityGSO
+ e.gsoMaxSize = opts.GSOMaxSize
}
- e.inboundDispatcher = e.packetMMapDispatch
- return stack.RegisterLinkEndpoint(e)
- }
- // For non-socket FDs we read one packet a time (e.g. TAP devices)
- msgsPerRecv := 1
- e.inboundDispatcher = e.dispatch
- // If the provided FD is a socket then we optimize packet reads by
- // using recvmmsg() instead of read() to read packets in a batch.
- if isSocketFD(opts.FD) && e.packetDispatchMode == RecvMMsg {
- e.inboundDispatcher = e.recvMMsgDispatch
- msgsPerRecv = MaxMsgsPerRecv
+ switch e.packetDispatchMode {
+ case PacketMMap:
+ if err := e.setupPacketRXRing(); err != nil {
+ return 0, fmt.Errorf("e.setupPacketRXRing failed: %v", err)
+ }
+ e.inboundDispatcher = e.packetMMapDispatch
+ return stack.RegisterLinkEndpoint(e), nil
+
+ case RecvMMsg:
+ // If the provided FD is a socket then we optimize packet reads by
+ // using recvmmsg() instead of read() to read packets in a batch.
+ e.inboundDispatcher = e.recvMMsgDispatch
+ msgsPerRecv = MaxMsgsPerRecv
+ }
}
e.views = make([][]buffer.View, msgsPerRecv)
@@ -217,16 +223,15 @@ func New(opts *Options) tcpip.LinkEndpointID {
e.msgHdrs[i].Msg.Iovlen = uint64(iovLen)
}
- return stack.RegisterLinkEndpoint(e)
+ return stack.RegisterLinkEndpoint(e), nil
}
-func isSocketFD(fd int) bool {
+func isSocketFD(fd int) (bool, error) {
var stat syscall.Stat_t
if err := syscall.Fstat(fd, &stat); err != nil {
- // TODO : replace panic with an error return.
- panic(fmt.Sprintf("syscall.Fstat(%v,...) failed: %v", fd, err))
+ return false, fmt.Errorf("syscall.Fstat(%v,...) failed: %v", fd, err)
}
- return (stat.Mode & syscall.S_IFSOCK) == syscall.S_IFSOCK
+ return (stat.Mode & syscall.S_IFSOCK) == syscall.S_IFSOCK, nil
}
// Attach launches the goroutine that reads packets from the file descriptor and
diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go
index ecc5b73f3..5a06c6387 100644
--- a/pkg/tcpip/link/fdbased/endpoint_test.go
+++ b/pkg/tcpip/link/fdbased/endpoint_test.go
@@ -68,7 +68,11 @@ func newContext(t *testing.T, opt *Options) *context {
}
opt.FD = fds[1]
- ep := stack.FindLinkEndpoint(New(opt)).(*endpoint)
+ epID, err := New(opt)
+ if err != nil {
+ t.Fatalf("Failed to create FD endpoint: %v", err)
+ }
+ ep := stack.FindLinkEndpoint(epID).(*endpoint)
c := &context{
t: t,
diff --git a/pkg/tcpip/sample/tun_tcp_connect/main.go b/pkg/tcpip/sample/tun_tcp_connect/main.go
index 327a79f48..cf8900c4d 100644
--- a/pkg/tcpip/sample/tun_tcp_connect/main.go
+++ b/pkg/tcpip/sample/tun_tcp_connect/main.go
@@ -137,7 +137,10 @@ func main() {
log.Fatal(err)
}
- linkID := fdbased.New(&fdbased.Options{FD: fd, MTU: mtu})
+ linkID, err := fdbased.New(&fdbased.Options{FD: fd, MTU: mtu})
+ if err != nil {
+ log.Fatal(err)
+ }
if err := s.CreateNIC(1, sniffer.New(linkID)); err != nil {
log.Fatal(err)
}
diff --git a/pkg/tcpip/sample/tun_tcp_echo/main.go b/pkg/tcpip/sample/tun_tcp_echo/main.go
index b23dc13e7..da6202f97 100644
--- a/pkg/tcpip/sample/tun_tcp_echo/main.go
+++ b/pkg/tcpip/sample/tun_tcp_echo/main.go
@@ -128,12 +128,15 @@ func main() {
log.Fatal(err)
}
- linkID := fdbased.New(&fdbased.Options{
+ linkID, err := fdbased.New(&fdbased.Options{
FD: fd,
MTU: mtu,
EthernetHeader: *tap,
Address: tcpip.LinkAddress(maddr),
})
+ if err != nil {
+ log.Fatal(err)
+ }
if err := s.CreateNIC(1, linkID); err != nil {
log.Fatal(err)
}
diff --git a/runsc/boot/network.go b/runsc/boot/network.go
index 3915a021f..ceb00a858 100644
--- a/runsc/boot/network.go
+++ b/runsc/boot/network.go
@@ -135,7 +135,7 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
}
mac := tcpip.LinkAddress(generateRndMac())
- linkEP := fdbased.New(&fdbased.Options{
+ linkEP, err := fdbased.New(&fdbased.Options{
FD: newFD,
MTU: uint32(link.MTU),
EthernetHeader: true,
@@ -144,6 +144,9 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
GSOMaxSize: link.GSOMaxSize,
RXChecksumOffload: true,
})
+ if err != nil {
+ return err
+ }
log.Infof("Enabling interface %q with id %d on addresses %+v (%v)", link.Name, nicID, link.Addresses, mac)
if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses, false /* loopback */); err != nil {