summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/tcpip/link/channel/channel.go18
-rw-r--r--pkg/tcpip/link/fdbased/endpoint_test.go1
-rw-r--r--pkg/tcpip/transport/tcp/dual_stack_test.go12
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go2
-rw-r--r--pkg/tcpip/transport/tcp/testing/context/context.go9
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
+}