diff options
Diffstat (limited to 'pkg/tcpip')
-rw-r--r-- | pkg/tcpip/link/channel/channel.go | 18 | ||||
-rw-r--r-- | pkg/tcpip/link/fdbased/endpoint_test.go | 1 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/dual_stack_test.go | 12 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint.go | 2 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/testing/context/context.go | 9 |
5 files changed, 38 insertions, 4 deletions
diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index 8c0d11288..f7501a1bc 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -28,6 +28,7 @@ type PacketInfo struct { Header buffer.View Payload buffer.View Proto tcpip.NetworkProtocolNumber + GSO *stack.GSO } // Endpoint is link layer endpoint that stores outbound packets in a channel @@ -36,6 +37,7 @@ type Endpoint struct { dispatcher stack.NetworkDispatcher mtu uint32 linkAddr tcpip.LinkAddress + GSO bool // C is where outbound packets are queued. C chan PacketInfo @@ -93,8 +95,17 @@ func (e *Endpoint) MTU() uint32 { } // Capabilities implements stack.LinkEndpoint.Capabilities. -func (*Endpoint) Capabilities() stack.LinkEndpointCapabilities { - return 0 +func (e *Endpoint) Capabilities() stack.LinkEndpointCapabilities { + caps := stack.LinkEndpointCapabilities(0) + if e.GSO { + caps |= stack.CapabilityGSO + } + return caps +} + +// GSOMaxSize returns the maximum GSO packet size. +func (*Endpoint) GSOMaxSize() uint32 { + return 1 << 15 } // MaxHeaderLength returns the maximum size of the link layer header. Given it @@ -109,11 +120,12 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { } // WritePacket stores outbound packets into the channel. -func (e *Endpoint) WritePacket(_ *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(_ *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { p := PacketInfo{ Header: hdr.View(), Proto: protocol, Payload: payload.ToView(), + GSO: gso, } select { diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 5a06c6387..c8b037d57 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -166,6 +166,7 @@ func testWritePacket(t *testing.T, plen int, eth bool, gsoMaxSize uint32) { CsumOffset: csumOffset, MSS: gsoMSS, MaxSize: gsoMaxSize, + L3HdrLen: header.IPv4MaximumHeaderSize, } } if err := c.ep.WritePacket(r, gso, hdr, payload.ToVectorisedView(), proto); err != nil { diff --git a/pkg/tcpip/transport/tcp/dual_stack_test.go b/pkg/tcpip/transport/tcp/dual_stack_test.go index 52f20bef1..2886cc707 100644 --- a/pkg/tcpip/transport/tcp/dual_stack_test.go +++ b/pkg/tcpip/transport/tcp/dual_stack_test.go @@ -19,6 +19,7 @@ import ( "time" "gvisor.googlesource.com/gvisor/pkg/tcpip" + "gvisor.googlesource.com/gvisor/pkg/tcpip/buffer" "gvisor.googlesource.com/gvisor/pkg/tcpip/checker" "gvisor.googlesource.com/gvisor/pkg/tcpip/header" "gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4" @@ -330,6 +331,9 @@ func TestV6RefuseOnBoundToV4Mapped(t *testing.T) { } func testV4Accept(t *testing.T, c *context.Context) { + c.SetGSOEnabled(true) + defer c.SetGSOEnabled(false) + // Start listening. if err := c.EP.Listen(10); err != nil { t.Fatalf("Listen failed: %v", err) @@ -406,6 +410,14 @@ func testV4Accept(t *testing.T, c *context.Context) { if addr.Addr != context.TestAddr { t.Fatalf("Unexpected remote address: got %v, want %v", addr.Addr, context.TestAddr) } + + data := "Don't panic" + nep.Write(tcpip.SlicePayload(buffer.NewViewFromBytes([]byte(data))), tcpip.WriteOptions{}) + b = c.GetPacket() + tcp = header.TCP(header.IPv4(b).Payload()) + if string(tcp.Payload()) != data { + t.Fatalf("Unexpected data: got %v, want %v", string(tcp.Payload()), data) + } } func TestV4AcceptOnV6(t *testing.T) { diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index b5d05af7d..c0b785431 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1717,7 +1717,7 @@ func (e *endpoint) initGSO() { } gso := &stack.GSO{} - switch e.netProto { + switch e.route.NetProto { case header.IPv4ProtocolNumber: gso.Type = stack.GSOTCPv4 gso.L3HdrLen = header.IPv4MinimumSize diff --git a/pkg/tcpip/transport/tcp/testing/context/context.go b/pkg/tcpip/transport/tcp/testing/context/context.go index 8ac411b1d..6e2fed880 100644 --- a/pkg/tcpip/transport/tcp/testing/context/context.go +++ b/pkg/tcpip/transport/tcp/testing/context/context.go @@ -234,6 +234,10 @@ func (c *Context) GetPacket() []byte { copy(b, p.Header) copy(b[len(p.Header):], p.Payload) + if p.GSO != nil && p.GSO.L3HdrLen != header.IPv4MinimumSize { + c.t.Errorf("L3HdrLen %v (expected %v)", p.GSO.L3HdrLen, header.IPv4MinimumSize) + } + checker.IPv4(c.t, b, checker.SrcAddr(StackAddr), checker.DstAddr(TestAddr)) return b @@ -956,3 +960,8 @@ func (c *Context) SACKEnabled() bool { } return bool(v) } + +// SetGSOEnabled enables or disables generic segmentation offload. +func (c *Context) SetGSOEnabled(enable bool) { + c.linkEP.GSO = enable +} |