diff --git a/overlay/batch/tcp_coalesce.go b/overlay/batch/tcp_coalesce.go index 4cdd4eb3..35b4db8e 100644 --- a/overlay/batch/tcp_coalesce.go +++ b/overlay/batch/tcp_coalesce.go @@ -397,7 +397,7 @@ func (c *TCPCoalescer) flushSlot(s *coalesceSlot) error { tcsum := s.ipHdrLen + 16 binary.BigEndian.PutUint16(hdr[tcsum:tcsum+2], foldOnceNoInvert(psum)) - return c.gsoW.WriteGSO(hdr, s.payIovs, uint16(s.gsoSize), s.isV6, uint16(s.ipHdrLen)) + return c.gsoW.WriteGSO(hdr, s.payIovs, uint16(s.gsoSize), uint16(s.ipHdrLen)) } // headersMatch compares two IP+TCP header prefixes for byte-for-byte diff --git a/overlay/tio/tio.go b/overlay/tio/tio.go index 8be89ebf..e8a2d902 100644 --- a/overlay/tio/tio.go +++ b/overlay/tio/tio.go @@ -1,6 +1,8 @@ package tio -import "io" +import ( + "io" +) // defaultBatchBufSize is the per-Queue scratch size for Read on backends // that don't do TSO segmentation. 65535 covers any single IP packet. @@ -53,6 +55,6 @@ type Queue interface { // hdr's TCP checksum field must already hold the pseudo-header partial // sum (single-fold, not inverted), per virtio NEEDS_CSUM semantics. type GSOWriter interface { - WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool, csumStart uint16) error + WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, csumStart uint16) error GSOSupported() bool } diff --git a/overlay/tio/tio_gso_linux.go b/overlay/tio/tio_gso_linux.go index 896ba0d7..b85e2e30 100644 --- a/overlay/tio/tio_gso_linux.go +++ b/overlay/tio/tio_gso_linux.go @@ -298,7 +298,7 @@ func (r *Offload) GSOSupported() bool { return true } // slice is read-only and must stay valid until return. gsoSize is the MSS; // every segment except possibly the last is exactly gsoSize bytes. // csumStart is the byte offset where the TCP header begins within hdr. -func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool, csumStart uint16) error { +func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, csumStart uint16) error { if len(hdr) == 0 || len(pays) == 0 { return nil } @@ -309,7 +309,7 @@ func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool, vhdr := VirtioNetHdr{ Flags: unix.VIRTIO_NET_HDR_F_NEEDS_CSUM, HdrLen: uint16(len(hdr)), - GSOSize: gsoSize, + GSOSize: uint16(len(pays[0])), CsumStart: csumStart, CsumOffset: 16, // TCP checksum field lives 16 bytes into the TCP header } @@ -318,10 +318,14 @@ func (r *Offload) WriteGSO(hdr []byte, pays [][]byte, gsoSize uint16, isV6 bool, totalPay += len(p) } if totalPay > int(gsoSize) { - if isV6 { + ipVer := hdr[0] >> 4 + if ipVer == 6 { vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_TCPV6 - } else { + } else if ipVer == 4 { vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_TCPV4 + } else { + vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_NONE + vhdr.GSOSize = 0 } } else { vhdr.GSOType = unix.VIRTIO_NET_HDR_GSO_NONE