mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Replace VectorisedView in transport endpoints.
PiperOrigin-RevId: 452186398
This commit is contained in:
committed by
gVisor bot
parent
ad3f841aad
commit
d9cb55b00c
+1
-2
@@ -48,8 +48,8 @@ deps_test(
|
||||
allowed = [
|
||||
# gVisor deps.
|
||||
"//pkg/atomicbitops",
|
||||
"//pkg/buffer",
|
||||
"//pkg/context",
|
||||
"//pkg/buffer",
|
||||
"//pkg/cpuid",
|
||||
"//pkg/gohacks",
|
||||
"//pkg/goid",
|
||||
@@ -77,7 +77,6 @@ deps_test(
|
||||
targets = [
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/adapters/gonet",
|
||||
"//pkg/tcpip/buffer",
|
||||
"//pkg/tcpip/link/channel",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/link/fdbased",
|
||||
|
||||
@@ -30,6 +30,7 @@ go_library(
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/buffer",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/buffer",
|
||||
"//pkg/tcpip/seqnum",
|
||||
|
||||
@@ -20,8 +20,9 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
tcpipbuffer "gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
)
|
||||
|
||||
// ChecksumSize is the size of a checksum.
|
||||
@@ -196,7 +197,7 @@ func Checksum(buf []byte, initial uint16) uint16 {
|
||||
// the given VectorizedView.
|
||||
//
|
||||
// The initial checksum must have been computed on an even number of bytes.
|
||||
func ChecksumVV(vv buffer.VectorisedView, initial uint16) uint16 {
|
||||
func ChecksumVV(vv tcpipbuffer.VectorisedView, initial uint16) uint16 {
|
||||
var c Checksumer
|
||||
for _, v := range vv.Views() {
|
||||
c.Add([]byte(v))
|
||||
@@ -204,6 +205,18 @@ func ChecksumVV(vv buffer.VectorisedView, initial uint16) uint16 {
|
||||
return ChecksumCombine(initial, c.Checksum())
|
||||
}
|
||||
|
||||
// ChecksumBuffer calculates the checksum (as defined in RFC 1071) of the
|
||||
// bytes in the given Buffer.
|
||||
//
|
||||
// The initial checksum must have been computed on an even number of bytes.
|
||||
func ChecksumBuffer(buf buffer.Buffer, initial uint16) uint16 {
|
||||
var c Checksumer
|
||||
buf.Apply(func(b []byte) {
|
||||
c.Add(b)
|
||||
})
|
||||
return ChecksumCombine(initial, c.Checksum())
|
||||
}
|
||||
|
||||
// Checksumer calculates checksum defined in RFC 1071.
|
||||
type Checksumer struct {
|
||||
sum uint16
|
||||
|
||||
@@ -591,6 +591,7 @@ func TestLinkResolution(t *testing.T) {
|
||||
// doesn't provoke NDP discovery.
|
||||
var wq waiter.Queue
|
||||
ep, err := c.s0.NewEndpoint(header.ICMPv6ProtocolNumber, ProtocolNumber, &wq)
|
||||
defer ep.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint(_) = (_, %s), want = (_, nil)", err)
|
||||
}
|
||||
|
||||
@@ -586,6 +586,11 @@ func (d PacketData) AppendView(v tcpipbuffer.View) {
|
||||
d.pk.buf.AppendOwned(v)
|
||||
}
|
||||
|
||||
// MergeBuffer merges b into d and clears b.
|
||||
func (d PacketData) MergeBuffer(b buffer.Buffer) {
|
||||
d.pk.buf.Merge(&b)
|
||||
}
|
||||
|
||||
// MergeFragment appends the data portion of frag to dst. It modifies
|
||||
// frag and frag should not be used again.
|
||||
func MergeFragment(dst, frag *PacketBuffer) {
|
||||
|
||||
@@ -19,7 +19,6 @@ go_test(
|
||||
deps = [
|
||||
":transport",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/buffer",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/link/loopback",
|
||||
"//pkg/tcpip/network/ipv4",
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/loopback"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
|
||||
@@ -184,7 +183,7 @@ func (e *mockEndpoint) pktsSize() int {
|
||||
func TestSndBuf(t *testing.T) {
|
||||
const nicID = 1
|
||||
|
||||
buf := buffer.NewView(header.ICMPv4MinimumSize)
|
||||
buf := make([]byte, header.ICMPv4MinimumSize)
|
||||
header.ICMPv4(buf).SetType(header.ICMPv4Echo)
|
||||
|
||||
for _, test := range []struct {
|
||||
@@ -363,15 +362,15 @@ func TestDeviceReturnErrNoBufferSpace(t *testing.T) {
|
||||
netProto tcpip.NetworkProtocolNumber
|
||||
localAddr tcpip.Address
|
||||
remoteAddr tcpip.Address
|
||||
buf buffer.View
|
||||
buf []byte
|
||||
}{
|
||||
{
|
||||
name: "IPv4",
|
||||
netProto: ipv4.ProtocolNumber,
|
||||
localAddr: testutil.MustParse4("1.2.3.4"),
|
||||
remoteAddr: testutil.MustParse4("1.0.0.1"),
|
||||
buf: func() buffer.View {
|
||||
buf := buffer.NewView(header.ICMPv4MinimumSize)
|
||||
buf: func() []byte {
|
||||
buf := make([]byte, header.ICMPv4MinimumSize)
|
||||
header.ICMPv4(buf).SetType(header.ICMPv4Echo)
|
||||
return buf
|
||||
}(),
|
||||
@@ -381,8 +380,8 @@ func TestDeviceReturnErrNoBufferSpace(t *testing.T) {
|
||||
netProto: ipv6.ProtocolNumber,
|
||||
localAddr: testutil.MustParse6("a::1"),
|
||||
remoteAddr: testutil.MustParse6("a::2"),
|
||||
buf: func() buffer.View {
|
||||
buf := buffer.NewView(header.ICMPv6MinimumSize)
|
||||
buf: func() []byte {
|
||||
buf := make([]byte, header.ICMPv6MinimumSize)
|
||||
header.ICMPv6(buf).SetType(header.ICMPv6EchoRequest)
|
||||
return buf
|
||||
}(),
|
||||
|
||||
@@ -26,6 +26,7 @@ go_library(
|
||||
imports = ["gvisor.dev/gvisor/pkg/tcpip/buffer"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/buffer",
|
||||
"//pkg/log",
|
||||
"//pkg/sleep",
|
||||
"//pkg/sync",
|
||||
@@ -51,7 +52,6 @@ go_test(
|
||||
"//pkg/refs",
|
||||
"//pkg/refsvfs2",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/buffer",
|
||||
"//pkg/tcpip/checker",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/link/channel",
|
||||
|
||||
@@ -19,10 +19,10 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/buffer"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/ports"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
@@ -36,8 +36,8 @@ type icmpPacket struct {
|
||||
icmpPacketEntry
|
||||
senderAddress tcpip.FullAddress
|
||||
packetInfo tcpip.IPPacketInfo
|
||||
data buffer.VectorisedView `state:".(buffer.VectorisedView)"`
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
data *stack.PacketBuffer
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
|
||||
// tosOrTClass stores either the Type of Service for IPv4 or the Traffic Class
|
||||
// for IPv6.
|
||||
@@ -149,6 +149,7 @@ func (e *endpoint) Close() {
|
||||
for !e.rcvList.Empty() {
|
||||
p := e.rcvList.Front()
|
||||
e.rcvList.Remove(p)
|
||||
p.data.DecRef()
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -184,7 +185,8 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
|
||||
p := e.rcvList.Front()
|
||||
if !opts.Peek {
|
||||
e.rcvList.Remove(p)
|
||||
e.rcvBufSize -= p.data.Size()
|
||||
defer p.data.DecRef()
|
||||
e.rcvBufSize -= p.data.Data().Size()
|
||||
}
|
||||
|
||||
e.rcvMu.Unlock()
|
||||
@@ -232,14 +234,14 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
|
||||
}
|
||||
|
||||
res := tcpip.ReadResult{
|
||||
Total: p.data.Size(),
|
||||
Total: p.data.Data().Size(),
|
||||
ControlMessages: cm,
|
||||
}
|
||||
if opts.NeedRemoteAddr {
|
||||
res.RemoteAddr = p.senderAddress
|
||||
}
|
||||
|
||||
n, err := p.data.ReadTo(dst, opts.Peek)
|
||||
n, err := p.data.Data().ReadTo(dst, opts.Peek)
|
||||
if n == 0 && err != nil {
|
||||
return res, &tcpip.ErrBadBuffer{}
|
||||
}
|
||||
@@ -383,7 +385,7 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error) {
|
||||
e.rcvMu.Lock()
|
||||
if !e.rcvList.Empty() {
|
||||
p := e.rcvList.Front()
|
||||
v = p.data.Size()
|
||||
v = p.data.Data().Size()
|
||||
}
|
||||
e.rcvMu.Unlock()
|
||||
return v, nil
|
||||
@@ -398,13 +400,13 @@ func (e *endpoint) GetSockOpt(opt tcpip.GettableSocketOption) tcpip.Error {
|
||||
return e.net.GetSockOpt(opt)
|
||||
}
|
||||
|
||||
func send4(s *stack.Stack, ctx *network.WriteContext, ident uint16, data buffer.View, maxHeaderLength uint16) tcpip.Error {
|
||||
func send4(s *stack.Stack, ctx *network.WriteContext, ident uint16, data []byte, maxHeaderLength uint16) tcpip.Error {
|
||||
if len(data) < header.ICMPv4MinimumSize {
|
||||
log.Infof("len(data) is smaller than min size")
|
||||
return &tcpip.ErrInvalidEndpointState{}
|
||||
}
|
||||
|
||||
pkt := ctx.TryNewPacketBuffer(header.ICMPv4MinimumSize+int(maxHeaderLength), buffer.VectorisedView{})
|
||||
pkt := ctx.TryNewPacketBuffer(header.ICMPv4MinimumSize+int(maxHeaderLength), buffer.Buffer{})
|
||||
if pkt == nil {
|
||||
return &tcpip.ErrWouldBlock{}
|
||||
}
|
||||
@@ -441,12 +443,12 @@ func send4(s *stack.Stack, ctx *network.WriteContext, ident uint16, data buffer.
|
||||
return nil
|
||||
}
|
||||
|
||||
func send6(s *stack.Stack, ctx *network.WriteContext, ident uint16, data buffer.View, src, dst tcpip.Address, maxHeaderLength uint16) tcpip.Error {
|
||||
func send6(s *stack.Stack, ctx *network.WriteContext, ident uint16, data []byte, src, dst tcpip.Address, maxHeaderLength uint16) tcpip.Error {
|
||||
if len(data) < header.ICMPv6EchoMinimumSize {
|
||||
return &tcpip.ErrInvalidEndpointState{}
|
||||
}
|
||||
|
||||
pkt := ctx.TryNewPacketBuffer(header.ICMPv6MinimumSize+int(maxHeaderLength), buffer.VectorisedView{})
|
||||
pkt := ctx.TryNewPacketBuffer(header.ICMPv6MinimumSize+int(maxHeaderLength), buffer.Buffer{})
|
||||
if pkt == nil {
|
||||
return &tcpip.ErrWouldBlock{}
|
||||
}
|
||||
@@ -757,12 +759,14 @@ func (e *endpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketB
|
||||
packet.ttlOrHopLimit = header.IPv6(pkt.NetworkHeader().View()).HopLimit()
|
||||
}
|
||||
|
||||
// ICMP socket's data includes ICMP header.
|
||||
packet.data = pkt.TransportHeader().View().ToVectorisedView()
|
||||
packet.data.Append(pkt.Data().ExtractVV())
|
||||
// ICMP socket's data includes ICMP header but no others. Trim all other
|
||||
// headers from the front of the packet.
|
||||
pktBuf := pkt.Buffer()
|
||||
pktBuf.TrimFront(int64(pkt.HeaderSize() - len(pkt.TransportHeader().View())))
|
||||
packet.data = stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: pktBuf})
|
||||
|
||||
e.rcvList.PushBack(packet)
|
||||
e.rcvBufSize += packet.data.Size()
|
||||
e.rcvBufSize += packet.data.Data().Size()
|
||||
|
||||
packet.receivedAt = e.stack.Clock().Now()
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport"
|
||||
)
|
||||
@@ -34,22 +33,6 @@ func (p *icmpPacket) loadReceivedAt(nsec int64) {
|
||||
p.receivedAt = time.Unix(0, nsec)
|
||||
}
|
||||
|
||||
// saveData saves icmpPacket.data field.
|
||||
func (p *icmpPacket) saveData() buffer.VectorisedView {
|
||||
// We cannot save p.data directly as p.data.views may alias to p.views,
|
||||
// which is not allowed by state framework (in-struct pointer).
|
||||
return p.data.Clone(nil)
|
||||
}
|
||||
|
||||
// loadData loads icmpPacket.data field.
|
||||
func (p *icmpPacket) loadData(data buffer.VectorisedView) {
|
||||
// NOTE: We cannot do the p.data = data.Clone(p.views[:]) optimization
|
||||
// here because data.views is not guaranteed to be loaded by now. Plus,
|
||||
// data.views will be allocated anyway so there really is little point
|
||||
// of utilizing p.views for data.views.
|
||||
p.data = data
|
||||
}
|
||||
|
||||
// afterLoad is invoked by stateify.
|
||||
func (e *endpoint) afterLoad() {
|
||||
stack.StackFromEnv.RegisterRestoredEndpoint(e)
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
package icmp_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/refs"
|
||||
"gvisor.dev/gvisor/pkg/refsvfs2"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/checker"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/link/channel"
|
||||
@@ -111,8 +111,8 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
|
||||
echoPayloadSize := defaultEP.MTU() - header.IPv4MinimumSize - header.ICMPv4MinimumSize
|
||||
|
||||
newICMPv4EchoRequest := func() buffer.View {
|
||||
buf := buffer.NewView(header.ICMPv4MinimumSize + int(echoPayloadSize))
|
||||
newICMPv4EchoRequest := func() []byte {
|
||||
buf := make([]byte, header.ICMPv4MinimumSize+int(echoPayloadSize))
|
||||
writePayload(buf[header.ICMPv4MinimumSize:])
|
||||
|
||||
icmp := header.ICMPv4(buf)
|
||||
@@ -127,7 +127,8 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
// to be added is the default NIC to send packets when not explicitly bound.
|
||||
{
|
||||
buf := newICMPv4EchoRequest()
|
||||
r := buf.Reader()
|
||||
var r bytes.Reader
|
||||
r.Reset(buf)
|
||||
n, err := socket.Write(&r, tcpip.WriteOptions{
|
||||
To: &tcpip.FullAddress{Addr: remoteV4Addr},
|
||||
})
|
||||
@@ -144,9 +145,9 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
t.Fatalf("got defaultEP.Read(_) = _, false; want = _, true (packet wasn't written out)")
|
||||
}
|
||||
|
||||
vv := buffer.NewVectorisedView(p.Size(), p.Views())
|
||||
pkbuf := p.Buffer()
|
||||
b := pkbuf.Flatten()
|
||||
p.DecRef()
|
||||
b := vv.ToView()
|
||||
|
||||
checker.IPv4(t, b, []checker.NetworkChecker{
|
||||
checker.SrcAddr(localV4Addr1),
|
||||
@@ -170,7 +171,8 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
socket.SocketOptions().SetBindToDevice(2)
|
||||
|
||||
buf := newICMPv4EchoRequest()
|
||||
r := buf.Reader()
|
||||
var r bytes.Reader
|
||||
r.Reset(buf)
|
||||
n, err := socket.Write(&r, tcpip.WriteOptions{
|
||||
To: &tcpip.FullAddress{Addr: remoteV4Addr},
|
||||
})
|
||||
@@ -192,9 +194,9 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
t.Fatalf("got alternateEP.Read(_) = _, false; want = _, true (packet wasn't written out)")
|
||||
}
|
||||
|
||||
vv := buffer.NewVectorisedView(p.Size(), p.Views())
|
||||
pkbuf := p.Buffer()
|
||||
b := pkbuf.Flatten()
|
||||
p.DecRef()
|
||||
b := vv.ToView()
|
||||
|
||||
checker.IPv4(t, b, []checker.NetworkChecker{
|
||||
checker.SrcAddr(localV4Addr2),
|
||||
@@ -213,7 +215,8 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
socket.SocketOptions().SetBindToDevice(0)
|
||||
|
||||
buf := newICMPv4EchoRequest()
|
||||
r := buf.Reader()
|
||||
var r bytes.Reader
|
||||
r.Reset(buf)
|
||||
n, err := socket.Write(&r, tcpip.WriteOptions{
|
||||
To: &tcpip.FullAddress{Addr: remoteV4Addr},
|
||||
})
|
||||
@@ -230,9 +233,9 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
t.Fatalf("got defaultEP.Read(_) = _, false; want = _, true (packet wasn't written out)")
|
||||
}
|
||||
|
||||
vv := buffer.NewVectorisedView(p.Size(), p.Views())
|
||||
pkbuf := p.Buffer()
|
||||
b := pkbuf.Flatten()
|
||||
p.DecRef()
|
||||
b := vv.ToView()
|
||||
|
||||
checker.IPv4(t, b, []checker.NetworkChecker{
|
||||
checker.SrcAddr(localV4Addr1),
|
||||
@@ -250,9 +253,9 @@ func TestWriteUnboundWithBindToDevice(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func buildV4EchoReplyPacket(payload []byte, h context.Header4Tuple) (buffer.View, buffer.View) {
|
||||
func buildV4EchoReplyPacket(payload []byte, h context.Header4Tuple) ([]byte, []byte) {
|
||||
// Allocate a buffer for data and headers.
|
||||
buf := buffer.NewView(header.IPv4MinimumSize + header.ICMPv4MinimumSize + len(payload))
|
||||
buf := make([]byte, header.IPv4MinimumSize+header.ICMPv4MinimumSize+len(payload))
|
||||
payloadStart := len(buf) - len(payload)
|
||||
copy(buf[payloadStart:], payload)
|
||||
|
||||
@@ -275,12 +278,12 @@ func buildV4EchoReplyPacket(payload []byte, h context.Header4Tuple) (buffer.View
|
||||
icmp.SetIdent(h.Dst.Port)
|
||||
icmp.SetChecksum(^header.Checksum(icmp, 0))
|
||||
|
||||
return buf, buffer.View(icmp)
|
||||
return buf, icmp
|
||||
}
|
||||
|
||||
func buildV6EchoReplyPacket(payload []byte, h context.Header4Tuple) (buffer.View, buffer.View) {
|
||||
func buildV6EchoReplyPacket(payload []byte, h context.Header4Tuple) ([]byte, []byte) {
|
||||
// Allocate a buffer for data and headers.
|
||||
buf := buffer.NewView(header.IPv6MinimumSize + header.ICMPv6EchoMinimumSize + len(payload))
|
||||
buf := make([]byte, header.IPv6MinimumSize+header.ICMPv6EchoMinimumSize+len(payload))
|
||||
payloadStart := len(buf) - len(payload)
|
||||
copy(buf[payloadStart:], payload)
|
||||
|
||||
@@ -308,12 +311,12 @@ func buildV6EchoReplyPacket(payload []byte, h context.Header4Tuple) (buffer.View
|
||||
PayloadLen: len(payload),
|
||||
}))
|
||||
|
||||
return buf, buffer.View(icmpv6)
|
||||
return buf, icmpv6
|
||||
}
|
||||
|
||||
// buildEchoReplyPacket builds an ICMPv4 or ICMPv6 echo reply packet, and
|
||||
// returns the full packet and the ICMP portion of the packet.
|
||||
func buildEchoReplyPacket(payload []byte, flow context.TestFlow) (buffer.View, buffer.View) {
|
||||
func buildEchoReplyPacket(payload []byte, flow context.TestFlow) ([]byte, []byte) {
|
||||
h := flow.MakeHeader4Tuple(context.Incoming)
|
||||
if flow.IsV4() {
|
||||
return buildV4EchoReplyPacket(payload, h)
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
tcpipbuffer "gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport/raw"
|
||||
@@ -87,7 +87,7 @@ func (p *protocol) MinimumPacketSize() int {
|
||||
}
|
||||
|
||||
// ParsePorts in case of ICMP sets src to 0, dst to ICMP ID, and err to nil.
|
||||
func (p *protocol) ParsePorts(v buffer.View) (src, dst uint16, err tcpip.Error) {
|
||||
func (p *protocol) ParsePorts(v tcpipbuffer.View) (src, dst uint16, err tcpip.Error) {
|
||||
switch p.number {
|
||||
case ProtocolNumber4:
|
||||
hdr := header.ICMPv4(v)
|
||||
|
||||
@@ -15,9 +15,9 @@ go_library(
|
||||
],
|
||||
deps = [
|
||||
"//pkg/atomicbitops",
|
||||
"//pkg/buffer",
|
||||
"//pkg/sync",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/buffer",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/stack",
|
||||
"//pkg/tcpip/transport",
|
||||
@@ -31,10 +31,10 @@ go_test(
|
||||
srcs = ["endpoint_test.go"],
|
||||
deps = [
|
||||
":network",
|
||||
"//pkg/buffer",
|
||||
"//pkg/refs",
|
||||
"//pkg/refsvfs2",
|
||||
"//pkg/tcpip",
|
||||
"//pkg/tcpip/buffer",
|
||||
"//pkg/tcpip/checker",
|
||||
"//pkg/tcpip/faketime",
|
||||
"//pkg/tcpip/header",
|
||||
|
||||
@@ -20,9 +20,9 @@ import (
|
||||
"fmt"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/buffer"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport"
|
||||
@@ -265,7 +265,7 @@ func (c *WriteContext) PacketInfo() WritePacketInfo {
|
||||
//
|
||||
// If this method returns nil, the caller should wait for the endpoint to become
|
||||
// writable.
|
||||
func (c *WriteContext) TryNewPacketBuffer(reserveHdrBytes int, data buffer.VectorisedView) *stack.PacketBuffer {
|
||||
func (c *WriteContext) TryNewPacketBuffer(reserveHdrBytes int, data buffer.Buffer) *stack.PacketBuffer {
|
||||
e := c.e
|
||||
|
||||
e.sendBufferSizeInUseMu.Lock()
|
||||
@@ -288,7 +288,7 @@ func (c *WriteContext) TryNewPacketBuffer(reserveHdrBytes int, data buffer.Vecto
|
||||
|
||||
return stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
ReserveHeaderBytes: reserveHdrBytes,
|
||||
Data: data,
|
||||
Payload: data,
|
||||
OnRelease: func() {
|
||||
e.sendBufferSizeInUseMu.Lock()
|
||||
if got := e.sendBufferSizeInUse; got < pktSize {
|
||||
|
||||
@@ -20,10 +20,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"gvisor.dev/gvisor/pkg/buffer"
|
||||
"gvisor.dev/gvisor/pkg/refs"
|
||||
"gvisor.dev/gvisor/pkg/refsvfs2"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/checker"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/faketime"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
@@ -49,8 +49,8 @@ var (
|
||||
func TestEndpointStateTransitions(t *testing.T) {
|
||||
const nicID = 1
|
||||
|
||||
data := buffer.View([]byte{1, 2, 4, 5})
|
||||
v4Checker := func(t *testing.T, b buffer.View) {
|
||||
data := []byte{1, 2, 4, 5}
|
||||
v4Checker := func(t *testing.T, b []byte) {
|
||||
checker.IPv4(t, b,
|
||||
checker.SrcAddr(ipv4NICAddr),
|
||||
checker.DstAddr(ipv4RemoteAddr),
|
||||
@@ -58,7 +58,7 @@ func TestEndpointStateTransitions(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
v6Checker := func(t *testing.T, b buffer.View) {
|
||||
v6Checker := func(t *testing.T, b []byte) {
|
||||
checker.IPv6(t, b,
|
||||
checker.SrcAddr(ipv6NICAddr),
|
||||
checker.DstAddr(ipv6RemoteAddr),
|
||||
@@ -76,7 +76,7 @@ func TestEndpointStateTransitions(t *testing.T) {
|
||||
expectedBoundAddr tcpip.Address
|
||||
remoteAddr tcpip.Address
|
||||
expectedRemoteAddr tcpip.Address
|
||||
checker func(*testing.T, buffer.View)
|
||||
checker func(*testing.T, []byte)
|
||||
}{
|
||||
{
|
||||
name: "IPv4",
|
||||
@@ -205,7 +205,7 @@ func TestEndpointStateTransitions(t *testing.T) {
|
||||
}
|
||||
injectPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
ReserveHeaderBytes: int(info.MaxHeaderLength),
|
||||
Data: data.ToVectorisedView(),
|
||||
Payload: buffer.NewWithData(data),
|
||||
})
|
||||
defer injectPkt.DecRef()
|
||||
if err := ctx.WritePacket(injectPkt, false /* headerIncluded */); err != nil {
|
||||
|
||||
@@ -39,10 +39,9 @@ import (
|
||||
// +stateify savable
|
||||
type packet struct {
|
||||
packetEntry
|
||||
// data holds the actual packet data, including any headers and
|
||||
// payload.
|
||||
data buffer.VectorisedView `state:".(buffer.VectorisedView)"`
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
// data holds the actual packet data, including any headers and payload.
|
||||
data *stack.PacketBuffer
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
// senderAddr is the network address of the sender.
|
||||
senderAddr tcpip.FullAddress
|
||||
// packetInfo holds additional information like the protocol
|
||||
@@ -145,7 +144,9 @@ func (ep *endpoint) Close() {
|
||||
ep.rcvClosed = true
|
||||
ep.rcvBufSize = 0
|
||||
for !ep.rcvList.Empty() {
|
||||
ep.rcvList.Remove(ep.rcvList.Front())
|
||||
p := ep.rcvList.Front()
|
||||
ep.rcvList.Remove(p)
|
||||
p.data.DecRef()
|
||||
}
|
||||
|
||||
ep.closed = true
|
||||
@@ -174,6 +175,7 @@ func (ep *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResul
|
||||
packet := ep.rcvList.Front()
|
||||
if !opts.Peek {
|
||||
ep.rcvList.Remove(packet)
|
||||
defer packet.data.DecRef()
|
||||
ep.rcvBufSize -= packet.data.Size()
|
||||
}
|
||||
|
||||
@@ -193,7 +195,7 @@ func (ep *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResul
|
||||
res.LinkPacketInfo = packet.packetInfo
|
||||
}
|
||||
|
||||
n, err := packet.data.ReadTo(dst, opts.Peek)
|
||||
n, err := packet.data.Data().ReadTo(dst, opts.Peek)
|
||||
if n == 0 && err != nil {
|
||||
return res, &tcpip.ErrBadBuffer{}
|
||||
}
|
||||
@@ -447,20 +449,14 @@ func (ep *endpoint) HandlePacket(nicID tcpip.NICID, netProto tcpip.NetworkProtoc
|
||||
rcvdPkt.senderAddr.Addr = tcpip.Address(hdr.SourceAddress())
|
||||
}
|
||||
|
||||
// Raw packet endpoints include link-headers in received packets.
|
||||
pktBuf := pkt.Buffer()
|
||||
if ep.cooked {
|
||||
// Cooked packet endpoints don't include the link-headers in received
|
||||
// packets.
|
||||
if v := pkt.NetworkHeader().View(); !v.IsEmpty() {
|
||||
rcvdPkt.data.AppendView(v)
|
||||
}
|
||||
if v := pkt.TransportHeader().View(); !v.IsEmpty() {
|
||||
rcvdPkt.data.AppendView(v)
|
||||
}
|
||||
rcvdPkt.data.Append(pkt.Data().ExtractVV())
|
||||
} else {
|
||||
// Raw packet endpoints include link-headers in received packets.
|
||||
rcvdPkt.data = buffer.NewVectorisedView(pkt.Size(), pkt.Views())
|
||||
pktBuf.TrimFront(int64(len(pkt.LinkHeader().View()) + len(pkt.VirtioNetHeader().View())))
|
||||
}
|
||||
rcvdPkt.data = stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: pktBuf})
|
||||
|
||||
ep.rcvList.PushBack(&rcvdPkt)
|
||||
ep.rcvBufSize += rcvdPkt.data.Size()
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
@@ -33,16 +32,6 @@ func (p *packet) loadReceivedAt(nsec int64) {
|
||||
p.receivedAt = time.Unix(0, nsec)
|
||||
}
|
||||
|
||||
// saveData saves packet.data field.
|
||||
func (p *packet) saveData() buffer.VectorisedView {
|
||||
return p.data.Clone(nil)
|
||||
}
|
||||
|
||||
// loadData loads packet.data field.
|
||||
func (p *packet) loadData(data buffer.VectorisedView) {
|
||||
p.data = data
|
||||
}
|
||||
|
||||
// beforeSave is invoked by stateify.
|
||||
func (ep *endpoint) beforeSave() {
|
||||
ep.rcvMu.Lock()
|
||||
|
||||
@@ -26,6 +26,7 @@ go_library(
|
||||
imports = ["gvisor.dev/gvisor/pkg/tcpip/buffer"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/buffer",
|
||||
"//pkg/log",
|
||||
"//pkg/sleep",
|
||||
"//pkg/sync",
|
||||
|
||||
@@ -30,9 +30,9 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/buffer"
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/transport"
|
||||
@@ -45,8 +45,8 @@ type rawPacket struct {
|
||||
rawPacketEntry
|
||||
// data holds the actual packet data, including any headers and
|
||||
// payload.
|
||||
data buffer.VectorisedView `state:".(buffer.VectorisedView)"`
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
data *stack.PacketBuffer
|
||||
receivedAt time.Time `state:".(int64)"`
|
||||
// senderAddr is the network address of the sender.
|
||||
senderAddr tcpip.FullAddress
|
||||
packetInfo tcpip.IPPacketInfo
|
||||
@@ -203,7 +203,9 @@ func (e *endpoint) Close() {
|
||||
e.rcvClosed = true
|
||||
e.rcvBufSize = 0
|
||||
for !e.rcvList.Empty() {
|
||||
e.rcvList.Remove(e.rcvList.Front())
|
||||
p := e.rcvList.Front()
|
||||
e.rcvList.Remove(p)
|
||||
p.data.DecRef()
|
||||
}
|
||||
|
||||
e.waiterQueue.Notify(waiter.EventHUp | waiter.EventErr | waiter.ReadableEvents | waiter.WritableEvents)
|
||||
@@ -235,7 +237,8 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
|
||||
pkt := e.rcvList.Front()
|
||||
if !opts.Peek {
|
||||
e.rcvList.Remove(pkt)
|
||||
e.rcvBufSize -= pkt.data.Size()
|
||||
defer pkt.data.DecRef()
|
||||
e.rcvBufSize -= pkt.data.Data().Size()
|
||||
}
|
||||
|
||||
e.rcvMu.Unlock()
|
||||
@@ -283,14 +286,14 @@ func (e *endpoint) Read(dst io.Writer, opts tcpip.ReadOptions) (tcpip.ReadResult
|
||||
}
|
||||
|
||||
res := tcpip.ReadResult{
|
||||
Total: pkt.data.Size(),
|
||||
Total: pkt.data.Data().Size(),
|
||||
ControlMessages: cm,
|
||||
}
|
||||
if opts.NeedRemoteAddr {
|
||||
res.RemoteAddr = pkt.senderAddr
|
||||
}
|
||||
|
||||
n, err := pkt.data.ReadTo(dst, opts.Peek)
|
||||
n, err := pkt.data.Data().ReadTo(dst, opts.Peek)
|
||||
if n == 0 && err != nil {
|
||||
return res, &tcpip.ErrBadBuffer{}
|
||||
}
|
||||
@@ -360,7 +363,7 @@ func (e *endpoint) write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcp
|
||||
header.PutChecksum(payloadBytes[ipv6ChecksumOffset:], ^xsum)
|
||||
}
|
||||
|
||||
pkt := ctx.TryNewPacketBuffer(int(ctx.PacketInfo().MaxHeaderLength), buffer.View(payloadBytes).ToVectorisedView())
|
||||
pkt := ctx.TryNewPacketBuffer(int(ctx.PacketInfo().MaxHeaderLength), buffer.NewWithData(payloadBytes))
|
||||
if pkt == nil {
|
||||
return 0, &tcpip.ErrWouldBlock{}
|
||||
}
|
||||
@@ -550,7 +553,7 @@ func (e *endpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error) {
|
||||
e.rcvMu.Lock()
|
||||
if !e.rcvList.Empty() {
|
||||
p := e.rcvList.Front()
|
||||
v = p.data.Size()
|
||||
v = p.data.Data().Size()
|
||||
}
|
||||
e.rcvMu.Unlock()
|
||||
return v, nil
|
||||
@@ -664,15 +667,16 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
|
||||
// TODO(https://gvisor.dev/issue/6517): Avoid the copy once S/R supports
|
||||
// overlapping slices.
|
||||
transportHeader := pkt.TransportHeader().View()
|
||||
var combinedVV buffer.VectorisedView
|
||||
var combinedBuf buffer.Buffer
|
||||
switch info.NetProto {
|
||||
case header.IPv4ProtocolNumber:
|
||||
networkHeader := pkt.NetworkHeader().View()
|
||||
headers := make(buffer.View, 0, len(networkHeader)+len(transportHeader))
|
||||
headers := make([]byte, 0, len(networkHeader)+len(transportHeader))
|
||||
headers = append(headers, networkHeader...)
|
||||
headers = append(headers, transportHeader...)
|
||||
combinedVV = headers.ToVectorisedView()
|
||||
combinedVV.Append(pkt.Data().ExtractVV())
|
||||
combinedBuf = buffer.NewWithData(headers)
|
||||
pktBuf := pkt.Data().AsBuffer()
|
||||
combinedBuf.Merge(&pktBuf)
|
||||
case header.IPv6ProtocolNumber:
|
||||
if e.transProto == header.ICMPv6ProtocolNumber {
|
||||
if len(transportHeader) < header.ICMPv6MinimumSize {
|
||||
@@ -684,18 +688,19 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
|
||||
}
|
||||
}
|
||||
|
||||
combinedVV = append(buffer.View(nil), transportHeader...).ToVectorisedView()
|
||||
combinedVV.Append(pkt.Data().ExtractVV())
|
||||
combinedBuf = buffer.NewWithData(transportHeader)
|
||||
pktBuf := pkt.Data().AsBuffer()
|
||||
combinedBuf.Merge(&pktBuf)
|
||||
|
||||
if checksumOffset := e.ipv6ChecksumOffset; checksumOffset >= 0 {
|
||||
vvSize := combinedVV.Size()
|
||||
if vvSize < checksumOffset+header.ChecksumSize {
|
||||
bufSize := int(combinedBuf.Size())
|
||||
if bufSize < checksumOffset+header.ChecksumSize {
|
||||
// Message too small to fit checksum.
|
||||
return false
|
||||
}
|
||||
|
||||
xsum := header.PseudoHeaderChecksum(e.transProto, srcAddr, dstAddr, uint16(vvSize))
|
||||
xsum = header.ChecksumVV(combinedVV, xsum)
|
||||
xsum := header.PseudoHeaderChecksum(e.transProto, srcAddr, dstAddr, uint16(bufSize))
|
||||
xsum = header.ChecksumBuffer(combinedBuf, xsum)
|
||||
if xsum != 0xFFFF {
|
||||
// Invalid checksum.
|
||||
return false
|
||||
@@ -705,11 +710,11 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
|
||||
panic(fmt.Sprintf("unrecognized protocol number = %d", info.NetProto))
|
||||
}
|
||||
|
||||
packet.data = combinedVV
|
||||
packet.data = stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: combinedBuf})
|
||||
packet.receivedAt = e.stack.Clock().Now()
|
||||
|
||||
e.rcvList.PushBack(packet)
|
||||
e.rcvBufSize += packet.data.Size()
|
||||
e.rcvBufSize += packet.data.Data().Size()
|
||||
e.stats.PacketsReceived.Increment()
|
||||
|
||||
// Notify waiters that there is data to be read now.
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
@@ -33,22 +32,6 @@ func (p *rawPacket) loadReceivedAt(nsec int64) {
|
||||
p.receivedAt = time.Unix(0, nsec)
|
||||
}
|
||||
|
||||
// saveData saves rawPacket.data field.
|
||||
func (p *rawPacket) saveData() buffer.VectorisedView {
|
||||
// We cannot save p.data directly as p.data.views may alias to p.views,
|
||||
// which is not allowed by state framework (in-struct pointer).
|
||||
return p.data.Clone(nil)
|
||||
}
|
||||
|
||||
// loadData loads rawPacket.data field.
|
||||
func (p *rawPacket) loadData(data buffer.VectorisedView) {
|
||||
// NOTE: We cannot do the p.data = data.Clone(p.views[:]) optimization
|
||||
// here because data.views is not guaranteed to be loaded by now. Plus,
|
||||
// data.views will be allocated anyway so there really is little point
|
||||
// of utilizing p.views for data.views.
|
||||
p.data = data
|
||||
}
|
||||
|
||||
// afterLoad is invoked by stateify.
|
||||
func (e *endpoint) afterLoad() {
|
||||
stack.StackFromEnv.RegisterRestoredEndpoint(e)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user