diff options
Diffstat (limited to 'pkg/tcpip/link')
-rw-r--r-- | pkg/tcpip/link/channel/channel.go | 12 | ||||
-rw-r--r-- | pkg/tcpip/link/fdbased/endpoint.go | 12 | ||||
-rw-r--r-- | pkg/tcpip/link/fdbased/endpoint_test.go | 7 | ||||
-rw-r--r-- | pkg/tcpip/link/loopback/loopback.go | 18 | ||||
-rw-r--r-- | pkg/tcpip/link/sharedmem/sharedmem.go | 5 | ||||
-rw-r--r-- | pkg/tcpip/link/sharedmem/sharedmem_test.go | 35 | ||||
-rw-r--r-- | pkg/tcpip/link/sniffer/sniffer.go | 30 | ||||
-rw-r--r-- | pkg/tcpip/link/waitable/waitable.go | 2 | ||||
-rw-r--r-- | pkg/tcpip/link/waitable/waitable_test.go | 8 |
9 files changed, 66 insertions, 63 deletions
diff --git a/pkg/tcpip/link/channel/channel.go b/pkg/tcpip/link/channel/channel.go index dd3fe7c87..6983fae3f 100644 --- a/pkg/tcpip/link/channel/channel.go +++ b/pkg/tcpip/link/channel/channel.go @@ -111,15 +111,11 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { } // WritePacket stores outbound packets into the channel. -func (e *Endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { p := PacketInfo{ - Header: hdr.View(), - Proto: protocol, - } - - if payload != nil { - p.Payload = make(buffer.View, len(payload)) - copy(p.Payload, payload) + Header: hdr.View(), + Proto: protocol, + Payload: payload.ToView(), } select { diff --git a/pkg/tcpip/link/fdbased/endpoint.go b/pkg/tcpip/link/fdbased/endpoint.go index 449acdfdd..12c249c0d 100644 --- a/pkg/tcpip/link/fdbased/endpoint.go +++ b/pkg/tcpip/link/fdbased/endpoint.go @@ -161,10 +161,12 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if e.handleLocal && r.LocalAddress != "" && r.LocalAddress == r.RemoteAddress { - hdrView := hdr.View() - vv := buffer.NewVectorisedView(len(hdrView)+len(payload), []buffer.View{hdrView, payload}) + views := make([]buffer.View, 1, 1+len(payload.Views())) + views[0] = hdr.View() + views = append(views, payload.Views()...) + vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) e.dispatcher.DeliverNetworkPacket(e, r.RemoteLinkAddress, protocol, &vv) return nil } @@ -178,11 +180,11 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload }) } - if len(payload) == 0 { + if payload.Size() == 0 { return rawfile.NonBlockingWrite(e.fd, hdr.UsedBytes()) } - return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload) + return rawfile.NonBlockingWrite2(e.fd, hdr.UsedBytes(), payload.ToView()) } func (e *endpoint) capViews(n int, buffers []int) int { diff --git a/pkg/tcpip/link/fdbased/endpoint_test.go b/pkg/tcpip/link/fdbased/endpoint_test.go index 89e791543..408169bbe 100644 --- a/pkg/tcpip/link/fdbased/endpoint_test.go +++ b/pkg/tcpip/link/fdbased/endpoint_test.go @@ -152,13 +152,14 @@ func TestWritePacket(t *testing.T) { b[i] = uint8(rand.Intn(256)) } - // Buiild payload and write. - payload := make([]byte, plen) + // Build payload and write. + payload := make(buffer.View, plen) for i := range payload { payload[i] = uint8(rand.Intn(256)) } want := append(hdr.UsedBytes(), payload...) - if err := c.ep.WritePacket(r, &hdr, payload, proto); err != nil { + vv := buffer.NewVectorisedView(len(payload), []buffer.View{payload}) + if err := c.ep.WritePacket(r, &hdr, vv, proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } diff --git a/pkg/tcpip/link/loopback/loopback.go b/pkg/tcpip/link/loopback/loopback.go index 015275721..4a750fa12 100644 --- a/pkg/tcpip/link/loopback/loopback.go +++ b/pkg/tcpip/link/loopback/loopback.go @@ -72,18 +72,12 @@ func (*endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It delivers outbound // packets to the network-layer dispatcher. -func (e *endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { - if len(payload) == 0 { - // We don't have a payload, so just use the buffer from the - // header as the full packet. - v := hdr.View() - vv := v.ToVectorisedView([1]buffer.View{}) - e.dispatcher.DeliverNetworkPacket(e, "", protocol, &vv) - } else { - views := []buffer.View{hdr.View(), payload} - vv := buffer.NewVectorisedView(len(views[0])+len(views[1]), views) - e.dispatcher.DeliverNetworkPacket(e, "", protocol, &vv) - } +func (e *endpoint) WritePacket(_ *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { + views := make([]buffer.View, 1, 1+len(payload.Views())) + views[0] = hdr.View() + views = append(views, payload.Views()...) + vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views) + e.dispatcher.DeliverNetworkPacket(e, "", protocol, &vv) return nil } diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 824cab093..6bd5441f6 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -184,7 +184,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { // Add the ethernet header here. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) eth.Encode(&header.EthernetFields{ @@ -193,9 +193,10 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload Type: protocol, }) + v := payload.ToView() // Transmit the packet. e.mu.Lock() - ok := e.tx.transmit(hdr.UsedBytes(), payload) + ok := e.tx.transmit(hdr.UsedBytes(), v) e.mu.Unlock() if !ok { diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 1e229279a..69d4ef29f 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -270,8 +270,8 @@ func TestSimpleSend(t *testing.T) { randomFill(buf) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - err := c.ep.WritePacket(&r, &hdr, buf, proto) - if err != nil { + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) + if err := c.ep.WritePacket(&r, &hdr, vv, proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } @@ -330,13 +330,15 @@ func TestFillTxQueue(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses no more than 40 bytes, so write that many packets // until the tx queue if full. ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -351,8 +353,7 @@ func TestFillTxQueue(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -373,11 +374,12 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Send two packets so that the id slice has at least two slots. for i := 2; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } @@ -397,7 +399,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -412,8 +414,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -430,13 +431,14 @@ func TestFillTxMemory(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses up one buffer, so write as many as possible until // we fill the memory. ids := make(map[uint64]struct{}) for i := queueDataSize / bufferSize; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -452,7 +454,7 @@ func TestFillTxMemory(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) + err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber) if want := tcpip.ErrWouldBlock; err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } @@ -472,12 +474,13 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // 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-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -488,14 +491,14 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { // Attempt to write a two-buffer packet. It must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buffer.NewView(bufferSize), header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + uu := buffer.NewVectorisedView(bufferSize, []buffer.View{buffer.NewView(bufferSize)}) + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, uu, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } - // Attempt to write a one-buffer packet. It must succeed. + // Attempt to write the one-buffer packet again. It must succeed. hdr = buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 1e302f557..3bdc85210 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -118,7 +118,7 @@ func NewWithFile(lower tcpip.LinkEndpointID, file *os.File, snapLen uint32) (tcp // logs the packet before forwarding to the actual dispatcher. func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remoteLinkAddr tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv *buffer.VectorisedView) { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { - logPacket("recv", protocol, vv.First(), nil) + logPacket("recv", protocol, vv.First()) } if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 { vs := vv.Views() @@ -188,19 +188,19 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements the stack.LinkEndpoint interface. It is called by // higher-level protocols to write packets; it just logs the packet and forwards // the request to the lower endpoint. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil { - logPacket("send", protocol, hdr.UsedBytes(), payload) + logPacket("send", protocol, hdr.UsedBytes()) } if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 { hdrBuf := hdr.UsedBytes() - length := len(hdrBuf) + len(payload) + length := len(hdrBuf) + payload.Size() if length > int(e.maxPCAPLen) { length = int(e.maxPCAPLen) } buf := bytes.NewBuffer(make([]byte, 0, pcapPacketHeaderLen+length)) - if err := binary.Write(buf, binary.BigEndian, newPCAPPacketHeader(uint32(length), uint32(hdr.UsedLength()+len(payload)))); err != nil { + if err := binary.Write(buf, binary.BigEndian, newPCAPPacketHeader(uint32(length), uint32(len(hdrBuf)+payload.Size()))); err != nil { panic(err) } if len(hdrBuf) > length { @@ -211,12 +211,18 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload } length -= len(hdrBuf) if length > 0 { - p := payload - if len(p) > length { - p = p[:length] - } - if _, err := buf.Write(p); err != nil { - panic(err) + for _, v := range payload.Views() { + if len(v) > length { + v = v[:length] + } + n, err := buf.Write(v) + if err != nil { + panic(err) + } + length -= n + if length == 0 { + break + } } } if _, err := e.file.Write(buf.Bytes()); err != nil { @@ -226,7 +232,7 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload return e.lower.WritePacket(r, hdr, payload, protocol) } -func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b, plb []byte) { +func logPacket(prefix string, protocol tcpip.NetworkProtocolNumber, b buffer.View) { // Figure out the network layer info. var transProto uint8 src := tcpip.Address("unknown") diff --git a/pkg/tcpip/link/waitable/waitable.go b/pkg/tcpip/link/waitable/waitable.go index 08b8d66e7..1c19a4509 100644 --- a/pkg/tcpip/link/waitable/waitable.go +++ b/pkg/tcpip/link/waitable/waitable.go @@ -100,7 +100,7 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket implements stack.LinkEndpoint.WritePacket. It is called by // higher-level protocols to write packets. It only forwards packets to the // lower endpoint if Wait or WaitWrite haven't been called. -func (e *Endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *Endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { if !e.writeGate.Enter() { return nil } diff --git a/pkg/tcpip/link/waitable/waitable_test.go b/pkg/tcpip/link/waitable/waitable_test.go index 37efa60d6..0719a95a9 100644 --- a/pkg/tcpip/link/waitable/waitable_test.go +++ b/pkg/tcpip/link/waitable/waitable_test.go @@ -65,7 +65,7 @@ func (e *countedEndpoint) LinkAddress() tcpip.LinkAddress { return e.linkAddr } -func (e *countedEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *countedEndpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { e.writeCount++ return nil } @@ -75,21 +75,21 @@ func TestWaitWrite(t *testing.T) { _, wep := New(stack.RegisterLinkEndpoint(ep)) // Write and check that it goes through. - wep.WritePacket(nil, nil, nil, 0) + wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) if want := 1; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on dispatches, then try to write. It must go through. wep.WaitDispatch() - wep.WritePacket(nil, nil, nil, 0) + wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } // Wait on writes, then try to write. It must not go through. wep.WaitWrite() - wep.WritePacket(nil, nil, nil, 0) + wep.WritePacket(nil, nil, buffer.VectorisedView{}, 0) if want := 2; ep.writeCount != want { t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) } |