diff --git a/pkg/tcpip/link/ethernet/BUILD b/pkg/tcpip/link/ethernet/BUILD index b2ad32ede..99abc8346 100644 --- a/pkg/tcpip/link/ethernet/BUILD +++ b/pkg/tcpip/link/ethernet/BUILD @@ -20,6 +20,7 @@ go_test( srcs = ["ethernet_test.go"], deps = [ ":ethernet", + "//pkg/buffer", "//pkg/refs", "//pkg/refsvfs2", "//pkg/tcpip", diff --git a/pkg/tcpip/link/ethernet/ethernet_test.go b/pkg/tcpip/link/ethernet/ethernet_test.go index b0a1ea7c3..8bb8540a1 100644 --- a/pkg/tcpip/link/ethernet/ethernet_test.go +++ b/pkg/tcpip/link/ethernet/ethernet_test.go @@ -19,10 +19,11 @@ import ( "os" "testing" + "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" + tcpipbuffer "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/link/channel" "gvisor.dev/gvisor/pkg/tcpip/link/ethernet" @@ -61,13 +62,13 @@ func TestDeliverNetworkPacket(t *testing.T) { // An ethernet frame with a destination link address that is not assigned to // our ethernet link endpoint should still be delivered to the network // dispatcher since the ethernet endpoint is not expected to filter frames. - eth := buffer.NewView(header.EthernetMinimumSize) + eth := make([]byte, header.EthernetMinimumSize) header.Ethernet(eth).Encode(&header.EthernetFields{ SrcAddr: otherLinkAddr1, DstAddr: otherLinkAddr2, Type: header.IPv4ProtocolNumber, }) - p := stack.NewPacketBuffer(stack.PacketBufferOptions{Data: eth.ToVectorisedView()}) + p := stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.NewWithData(eth)}) defer p.DecRef() e.DeliverNetworkPacket(0, p) if networkDispatcher.networkPackets != 1 { @@ -140,7 +141,9 @@ func TestWritePacketToRemoteAddHeader(t *testing.T) { t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err) } - if err := s.WritePacketToRemote(nicID, remoteLinkAddr, netProto, buffer.VectorisedView{}); err != nil { + // TODO(b/230896518): Remove tcpipbuffer once WritePacketToRemote API is + // changed. + if err := s.WritePacketToRemote(nicID, remoteLinkAddr, netProto, tcpipbuffer.VectorisedView{}); err != nil { t.Fatalf("s.WritePacketToRemote(%d, %s, _): %s", nicID, remoteLinkAddr, err) } diff --git a/pkg/tcpip/link/loopback/BUILD b/pkg/tcpip/link/loopback/BUILD index 6bf3805b7..db3e6359c 100644 --- a/pkg/tcpip/link/loopback/BUILD +++ b/pkg/tcpip/link/loopback/BUILD @@ -8,7 +8,6 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/stack", ], diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 72e6dc176..fcebdc89e 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -22,7 +22,6 @@ package loopback import ( "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -77,8 +76,11 @@ func (*endpoint) Wait() {} // WritePackets implements stack.LinkEndpoint.WritePackets. func (e *endpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) { for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() { + // In order to properly loop back to the inbound side we must create a + // fresh packet that only contains the underlying payload with no headers + // or struct fields set. newPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: buffer.NewVectorisedView(pkt.Size(), pkt.Views()), + Payload: pkt.Buffer(), }) e.dispatcher.DeliverNetworkPacket(pkt.NetworkProtocolNumber, newPkt) newPkt.DecRef() diff --git a/pkg/tcpip/link/muxed/BUILD b/pkg/tcpip/link/muxed/BUILD index ba921548f..29e8d4b8d 100644 --- a/pkg/tcpip/link/muxed/BUILD +++ b/pkg/tcpip/link/muxed/BUILD @@ -19,10 +19,10 @@ go_test( srcs = ["injectable_test.go"], library = ":muxed", deps = [ + "//pkg/buffer", "//pkg/refs", "//pkg/refsvfs2", "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/link/fdbased", "//pkg/tcpip/network/ipv4", "//pkg/tcpip/stack", diff --git a/pkg/tcpip/link/muxed/injectable_test.go b/pkg/tcpip/link/muxed/injectable_test.go index 0cb66d2ab..14a42f61b 100644 --- a/pkg/tcpip/link/muxed/injectable_test.go +++ b/pkg/tcpip/link/muxed/injectable_test.go @@ -21,10 +21,10 @@ import ( "testing" "golang.org/x/sys/unix" + "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/link/fdbased" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" "gvisor.dev/gvisor/pkg/tcpip/stack" @@ -50,7 +50,7 @@ func TestInjectableEndpointDispatch(t *testing.T) { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: 1, - Data: buffer.NewViewFromBytes([]byte{0xFB}).ToVectorisedView(), + Payload: buffer.NewWithData([]byte{0xFB}), }) defer pkt.DecRef() pkt.TransportHeader().Push(1)[0] = 0xFA @@ -78,7 +78,6 @@ func TestInjectableEndpointDispatchHdrOnly(t *testing.T) { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: 1, - Data: buffer.NewView(0).ToVectorisedView(), }) defer pkt.DecRef() pkt.TransportHeader().Push(1)[0] = 0xFA diff --git a/pkg/tcpip/link/pipe/BUILD b/pkg/tcpip/link/pipe/BUILD index 9f31c1ffc..4b860b4fa 100644 --- a/pkg/tcpip/link/pipe/BUILD +++ b/pkg/tcpip/link/pipe/BUILD @@ -8,7 +8,6 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/stack", ], diff --git a/pkg/tcpip/link/pipe/pipe.go b/pkg/tcpip/link/pipe/pipe.go index e95f8b9a6..cb98797f4 100644 --- a/pkg/tcpip/link/pipe/pipe.go +++ b/pkg/tcpip/link/pipe/pipe.go @@ -18,7 +18,6 @@ package pipe import ( "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -54,8 +53,11 @@ func (e *Endpoint) deliverPackets(pkts stack.PacketBufferList) { } for pkt := pkts.Front(); pkt != nil; pkt = pkt.Next() { + // Create a fresh packet with pkt's payload but without struct fields + // or headers set so the next link protocol can properly set the link + // header. newPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: buffer.NewVectorisedView(pkt.Size(), pkt.Views()), + Payload: pkt.Buffer(), }) e.linked.dispatcher.DeliverNetworkPacket(pkt.NetworkProtocolNumber, newPkt) newPkt.DecRef() diff --git a/pkg/tcpip/link/qdisc/fifo/BUILD b/pkg/tcpip/link/qdisc/fifo/BUILD index 8d9ae6a16..4e809afc9 100644 --- a/pkg/tcpip/link/qdisc/fifo/BUILD +++ b/pkg/tcpip/link/qdisc/fifo/BUILD @@ -23,11 +23,11 @@ go_test( srcs = ["qdisc_test.go"], deps = [ ":fifo", + "//pkg/buffer", "//pkg/refs", "//pkg/refsvfs2", "//pkg/sync", "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/stack", ], ) diff --git a/pkg/tcpip/link/qdisc/fifo/qdisc_test.go b/pkg/tcpip/link/qdisc/fifo/qdisc_test.go index f707ced64..ae16557a3 100644 --- a/pkg/tcpip/link/qdisc/fifo/qdisc_test.go +++ b/pkg/tcpip/link/qdisc/fifo/qdisc_test.go @@ -20,11 +20,11 @@ import ( "testing" "time" + "gvisor.dev/gvisor/pkg/buffer" "gvisor.dev/gvisor/pkg/refs" "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/link/qdisc/fifo" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -56,7 +56,7 @@ func TestFastSimultaneousWrites(t *testing.T) { lower := &countWriter{} linkEP := fifo.New(lower, 16, 1000) - v := make(buffer.View, 1) + v := make([]byte, 1) // Simulate many simultaneous writes from various goroutines, similar to TCP's sendTCPBatch(). nWriters := 100 @@ -68,7 +68,7 @@ func TestFastSimultaneousWrites(t *testing.T) { defer wg.Done() for j := 0; j < nWrites; j++ { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: v.ToVectorisedView(), + Payload: buffer.NewWithData(v), }) pkt.Hash = rand.Uint32() linkEP.WritePacket(pkt) @@ -93,7 +93,7 @@ func TestWriteRefusedAfterClosed(t *testing.T) { func TestWriteMorePacketsThanBatchSize(t *testing.T) { tc := []int{fifo.BatchSize + 1, fifo.BatchSize*2 + 1} - v := make(buffer.View, 1) + v := make([]byte, 1) for _, want := range tc { done := make(chan struct{}) @@ -101,7 +101,7 @@ func TestWriteMorePacketsThanBatchSize(t *testing.T) { linkEp := fifo.New(lower, 1, 1000) for i := 0; i < want; i++ { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: v.ToVectorisedView(), + Payload: buffer.NewWithData(v), }) linkEp.WritePacket(pkt) pkt.DecRef() diff --git a/pkg/tcpip/link/sharedmem/BUILD b/pkg/tcpip/link/sharedmem/BUILD index bd8dfa218..b3e312139 100644 --- a/pkg/tcpip/link/sharedmem/BUILD +++ b/pkg/tcpip/link/sharedmem/BUILD @@ -19,13 +19,13 @@ go_library( ], deps = [ "//pkg/atomicbitops", + "//pkg/buffer", "//pkg/cleanup", "//pkg/eventfd", "//pkg/log", "//pkg/memutil", "//pkg/sync", "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/link/rawfile", "//pkg/tcpip/link/sharedmem/pipe", @@ -40,11 +40,11 @@ go_test( srcs = ["sharedmem_test.go"], library = ":sharedmem", deps = [ + "//pkg/buffer", "//pkg/refs", "//pkg/refsvfs2", "//pkg/sync", "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/link/sharedmem/pipe", "//pkg/tcpip/link/sharedmem/queue", diff --git a/pkg/tcpip/link/sharedmem/server_tx.go b/pkg/tcpip/link/sharedmem/server_tx.go index 3144187b3..f697135a4 100644 --- a/pkg/tcpip/link/sharedmem/server_tx.go +++ b/pkg/tcpip/link/sharedmem/server_tx.go @@ -22,7 +22,6 @@ import ( "gvisor.dev/gvisor/pkg/atomicbitops" "gvisor.dev/gvisor/pkg/cleanup" "gvisor.dev/gvisor/pkg/eventfd" - "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/link/sharedmem/pipe" "gvisor.dev/gvisor/pkg/tcpip/link/sharedmem/queue" ) @@ -114,7 +113,7 @@ func (s *serverTx) cleanup() { // acquireBuffers acquires enough buffers to hold all the data in views or // returns nil if not enough buffers are currently available. -func (s *serverTx) acquireBuffers(views []buffer.View, buffers []queue.RxBuffer) (acquiredBuffers []queue.RxBuffer) { +func (s *serverTx) acquireBuffers(views [][]byte, buffers []queue.RxBuffer) (acquiredBuffers []queue.RxBuffer) { acquiredBuffers = buffers[:0] wantBytes := 0 for i := range views { @@ -139,10 +138,10 @@ func (s *serverTx) acquireBuffers(views []buffer.View, buffers []queue.RxBuffer) // // To avoid allocations the filledBuffers are appended to the buffers slice // which will be grown as required. -func (s *serverTx) fillPacket(views []buffer.View, buffers []queue.RxBuffer) (filledBuffers []queue.RxBuffer, totalCopied uint32) { +func (s *serverTx) fillPacket(views [][]byte, buffers []queue.RxBuffer) (filledBuffers []queue.RxBuffer, totalCopied uint32) { // fillBuffer copies as much of the views as possible into the provided buffer // and returns any left over views (if any). - fillBuffer := func(buffer *queue.RxBuffer, views []buffer.View) (left []buffer.View) { + fillBuffer := func(buffer *queue.RxBuffer, views [][]byte) (left [][]byte) { if len(views) == 0 { return nil } @@ -152,8 +151,8 @@ func (s *serverTx) fillPacket(views []buffer.View, buffers []queue.RxBuffer) (fi n := copy(s.data[buffer.Offset+copied:][:uint64(buffer.Size)-copied], views[0]) copied += uint64(n) availBytes -= uint32(n) - views[0].TrimFront(n) - if !views[0].IsEmpty() { + views[0] = views[0][n:] + if len(views[0]) != 0 { break } views = views[1:] @@ -174,7 +173,7 @@ func (s *serverTx) fillPacket(views []buffer.View, buffers []queue.RxBuffer) (fi return bufs, totalCopied } -func (s *serverTx) transmit(views []buffer.View) bool { +func (s *serverTx) transmit(views [][]byte) bool { buffers := make([]queue.RxBuffer, 8) buffers, totalCopied := s.fillPacket(views, buffers) if totalCopied == 0 { diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 102b90019..d75dcd866 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -27,11 +27,11 @@ import ( "fmt" "gvisor.dev/gvisor/pkg/atomicbitops" + "gvisor.dev/gvisor/pkg/buffer" "gvisor.dev/gvisor/pkg/eventfd" "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/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/link/sharedmem/queue" @@ -343,8 +343,10 @@ func (e *endpoint) writePacketLocked(r stack.RouteInfo, protocol tcpip.NetworkPr e.AddVirtioNetHeader(pkt) } - views := pkt.Views() + views := pkt.Slices() // Transmit the packet. + // TODO(b/231582970): Change transmit() to take a buffer.Buffer instead of a + // collection of slices. ok := e.tx.transmit(views...) if !ok { return &tcpip.ErrWouldBlock{} @@ -411,7 +413,7 @@ func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) { } pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: buffer.View(b).ToVectorisedView(), + Payload: buffer.NewWithData(b), }) if e.virtioNetHeaderRequired { diff --git a/pkg/tcpip/link/sharedmem/sharedmem_server.go b/pkg/tcpip/link/sharedmem/sharedmem_server.go index ad8398172..317ccc43d 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_server.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_server.go @@ -19,9 +19,9 @@ package sharedmem import ( "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/link/rawfile" "gvisor.dev/gvisor/pkg/tcpip/stack" @@ -228,7 +228,7 @@ func (e *serverEndpoint) writePacketLocked(r stack.RouteInfo, protocol tcpip.Net e.AddVirtioNetHeader(pkt) } - views := pkt.Views() + views := pkt.Slices() ok := e.tx.transmit(views) if !ok { return &tcpip.ErrWouldBlock{} @@ -295,7 +295,7 @@ func (e *serverEndpoint) dispatchLoop(d stack.NetworkDispatcher) { } } pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ - Data: buffer.View(b).ToVectorisedView(), + Payload: buffer.NewWithData(b), }) if e.virtioNetHeaderRequired { _, ok := pkt.VirtioNetHeader().Consume(header.VirtioNetHeaderSize) diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index f9260d5aa..1e482beb0 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -26,11 +26,11 @@ import ( "time" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/buffer" "gvisor.dev/gvisor/pkg/refs" "gvisor.dev/gvisor/pkg/refsvfs2" "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/link/sharedmem/pipe" "gvisor.dev/gvisor/pkg/tcpip/link/sharedmem/queue" @@ -81,8 +81,8 @@ func (q *queueBuffers) cleanup() { type packetInfo struct { proto tcpip.NetworkProtocolNumber - data buffer.View - linkHeader buffer.View + data []byte + linkHeader []byte } type testContext struct { @@ -213,15 +213,15 @@ func TestSimpleSend(t *testing.T) { hdrLen, dataLen := rand.Intn(10000), rand.Intn(10000) // Prepare and send packet. - hdrBuf := buffer.NewView(hdrLen) + hdrBuf := make([]byte, hdrLen) randomFill(hdrBuf) - data := buffer.NewView(dataLen) + data := make([]byte, dataLen) randomFill(data) pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: hdrLen + int(c.ep.MaxHeaderLength()), - Data: data.ToVectorisedView(), + Payload: buffer.NewWithData(data), }) copy(pkt.NetworkHeader().Push(hdrLen), hdrBuf) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) @@ -350,7 +350,7 @@ func TestFillTxQueue(t *testing.T) { c := newTestContext(t, 20000, 1500, localLinkAddr) defer c.cleanup() - buf := buffer.NewView(100) + buf := make([]byte, 100) // Each packet is uses no more than 40 bytes, so write that many packets // until the tx queue if full. @@ -360,7 +360,7 @@ func TestFillTxQueue(t *testing.T) { for i := queuePipeSize / 40; i > 0; i-- { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber @@ -386,7 +386,7 @@ func TestFillTxQueue(t *testing.T) { // Next attempt to write must fail. pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber @@ -411,7 +411,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { queue.EncodeTxCompletion(c.txq.rx.Push(8), 1) c.txq.rx.Flush() - buf := buffer.NewView(100) + buf := make([]byte, 100) // Send two packets so that the id slice has at least two slots. { @@ -419,7 +419,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { for i := 2; i > 0; i-- { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkts.PushBack(pkt) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr @@ -448,7 +448,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { for i := queuePipeSize / 40; i > 0; i-- { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber @@ -473,7 +473,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Next attempt to write must fail. pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber @@ -494,7 +494,7 @@ func TestFillTxMemory(t *testing.T) { c := newTestContext(t, 20000, bufferSize, localLinkAddr) defer c.cleanup() - buf := buffer.NewView(100) + buf := make([]byte, 100) // Each packet is uses up one buffer, so write as many as possible until // we fill the memory. @@ -502,7 +502,7 @@ func TestFillTxMemory(t *testing.T) { for i := queueDataSize / bufferSize; i > 0; i-- { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber @@ -528,7 +528,7 @@ func TestFillTxMemory(t *testing.T) { // Next attempt to write must fail. pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr @@ -549,14 +549,14 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { c := newTestContext(t, 20000, bufferSize, localLinkAddr) defer c.cleanup() - buf := buffer.NewView(100) + buf := make([]byte, 100) // Each packet is uses up one buffer, so write as many as possible // until there is only one buffer left. for i := queueDataSize/bufferSize - 1; i > 0; i-- { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) var pkts stack.PacketBufferList pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr @@ -577,7 +577,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { var pkts stack.PacketBufferList pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buffer.NewView(bufferSize).ToVectorisedView(), + Payload: buffer.NewWithData(make([]byte, bufferSize)), }) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber @@ -596,7 +596,7 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { var pkts stack.PacketBufferList pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: int(c.ep.MaxHeaderLength()), - Data: buf.ToVectorisedView(), + Payload: buffer.NewWithData(buf), }) pkt.EgressRoute.RemoteLinkAddress = remoteLinkAddr pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber diff --git a/pkg/tcpip/link/sharedmem/tx.go b/pkg/tcpip/link/sharedmem/tx.go index ab7d47e8b..3c4b94412 100644 --- a/pkg/tcpip/link/sharedmem/tx.go +++ b/pkg/tcpip/link/sharedmem/tx.go @@ -19,7 +19,6 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/eventfd" - "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/link/sharedmem/queue" ) @@ -93,7 +92,7 @@ func (t *tx) cleanup() { // transmit sends a packet made of bufs. Returns a boolean that specifies // whether the packet was successfully transmitted. -func (t *tx) transmit(bufs ...buffer.View) bool { +func (t *tx) transmit(bufs ...[]byte) bool { // Pull completions from the tx queue and add their buffers back to the // pool so that we can reuse them. for { diff --git a/pkg/tcpip/link/sniffer/BUILD b/pkg/tcpip/link/sniffer/BUILD index 006196294..74b7d2f30 100644 --- a/pkg/tcpip/link/sniffer/BUILD +++ b/pkg/tcpip/link/sniffer/BUILD @@ -13,7 +13,6 @@ go_library( "//pkg/atomicbitops", "//pkg/log", "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/header/parse", "//pkg/tcpip/link/nested", diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 36c0ac99a..cd72c9ba5 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -29,7 +29,6 @@ import ( "gvisor.dev/gvisor/pkg/atomicbitops" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/buffer" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/header/parse" "gvisor.dev/gvisor/pkg/tcpip/link/nested" @@ -194,10 +193,10 @@ func logPacket(prefix string, dir direction, protocol tcpip.NetworkProtocolNumbe // // We trim the link headers from the cloned buffer as the sniffer doesn't // handle link headers. - vv := buffer.NewVectorisedView(pkt.Size(), pkt.Views()) - vv.TrimFront(len(pkt.VirtioNetHeader().View())) - vv.TrimFront(len(pkt.LinkHeader().View())) - pkt = stack.NewPacketBuffer(stack.PacketBufferOptions{Data: vv}) + buf := pkt.Buffer() + buf.TrimFront(int64(len(pkt.VirtioNetHeader().View()))) + buf.TrimFront(int64(len(pkt.LinkHeader().View()))) + pkt = stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buf}) defer pkt.DecRef() switch protocol { case header.IPv4ProtocolNumber: diff --git a/pkg/tcpip/link/tun/BUILD b/pkg/tcpip/link/tun/BUILD index eca872d48..7ab9a8dc2 100644 --- a/pkg/tcpip/link/tun/BUILD +++ b/pkg/tcpip/link/tun/BUILD @@ -26,6 +26,7 @@ go_library( deps = [ "//pkg/abi/linux", "//pkg/atomicbitops", + "//pkg/buffer", "//pkg/context", "//pkg/errors/linuxerr", "//pkg/log", @@ -33,7 +34,6 @@ go_library( "//pkg/refsvfs2", "//pkg/sync", "//pkg/tcpip", - "//pkg/tcpip/buffer", "//pkg/tcpip/header", "//pkg/tcpip/link/channel", "//pkg/tcpip/link/packetsocket", diff --git a/pkg/tcpip/link/tun/device.go b/pkg/tcpip/link/tun/device.go index 8c32037b9..6585a064d 100644 --- a/pkg/tcpip/link/tun/device.go +++ b/pkg/tcpip/link/tun/device.go @@ -17,11 +17,11 @@ package tun import ( "fmt" + "gvisor.dev/gvisor/pkg/buffer" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/errors/linuxerr" "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/link/channel" "gvisor.dev/gvisor/pkg/tcpip/link/packetsocket" @@ -236,7 +236,7 @@ func (d *Device) Write(data []byte) (int64, error) { pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{ ReserveHeaderBytes: len(ethHdr), - Data: buffer.View(data).ToVectorisedView(), + Payload: buffer.NewWithData(data), }) defer pkt.DecRef() copy(pkt.LinkHeader().Push(len(ethHdr)), ethHdr) @@ -270,8 +270,8 @@ func (d *Device) Read() ([]byte, error) { } // encodePkt encodes packet for fd side. -func (d *Device) encodePkt(pkt *stack.PacketBuffer) (buffer.View, bool) { - var vv buffer.VectorisedView +func (d *Device) encodePkt(pkt *stack.PacketBuffer) ([]byte, bool) { + var buf buffer.Buffer // Packet information. if !d.flags.NoPacketInfo { @@ -279,12 +279,13 @@ func (d *Device) encodePkt(pkt *stack.PacketBuffer) (buffer.View, bool) { hdr.Encode(&PacketInfoFields{ Protocol: pkt.NetworkProtocolNumber, }) - vv.AppendView(buffer.View(hdr)) + buf.AppendOwned(hdr) } - vv.AppendViews(pkt.Views()) + pktBuf := pkt.Buffer() + buf.Merge(&pktBuf) - return vv.ToView(), true + return buf.Flatten(), true } // Name returns the name of the attached network interface. Empty string if diff --git a/pkg/tcpip/stack/packet_buffer.go b/pkg/tcpip/stack/packet_buffer.go index 6a037f807..c12777174 100644 --- a/pkg/tcpip/stack/packet_buffer.go +++ b/pkg/tcpip/stack/packet_buffer.go @@ -286,6 +286,7 @@ func (pk *PacketBuffer) Data() PacketData { } // Views returns the underlying storage of the whole packet. +// TODO(b/230896518): Remove this. func (pk *PacketBuffer) Views() []tcpipbuffer.View { var views []tcpipbuffer.View offset := pk.headerOffset() @@ -295,6 +296,23 @@ func (pk *PacketBuffer) Views() []tcpipbuffer.View { return views } +// Slices returns the underlying storage of the whole packet. +func (pk *PacketBuffer) Slices() [][]byte { + var views [][]byte + offset := pk.headerOffset() + pk.buf.SubApply(offset, int(pk.buf.Size())-offset, func(v []byte) { + views = append(views, v) + }) + return views +} + +// Buffer returns the underlying storage of the whole packet. +func (pk *PacketBuffer) Buffer() buffer.Buffer { + b := pk.buf.Clone() + b.TrimFront(int64(pk.headerOffset())) + return b +} + func (pk *PacketBuffer) headerOffset() int { return pk.reserved - pk.pushed } @@ -565,6 +583,15 @@ func (d PacketData) Views() []tcpipbuffer.View { return views } +// AsBuffer returns the underlying storage of d in a buffer.Buffer. Caller +// should not modify the returned buffer. +func (d PacketData) AsBuffer() buffer.Buffer { + buf := d.pk.buf.Clone() + offset := d.pk.dataOffset() + buf.TrimFront(int64(offset)) + return buf +} + // AppendView appends v into d, taking the ownership of v. func (d PacketData) AppendView(v tcpipbuffer.View) { d.pk.buf.AppendOwned(v)