mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Use PacketBuffers for outgoing packets.
PiperOrigin-RevId: 280455453
This commit is contained in:
committed by
gVisor bot
parent
1e55eb3800
commit
3f7d937090
@@ -77,3 +77,9 @@ func (p *Prependable) Prepend(size int) []byte {
|
||||
p.usedIdx -= size
|
||||
return p.View()[:size:size]
|
||||
}
|
||||
|
||||
// DeepCopy copies p and the bytes backing it.
|
||||
func (p Prependable) DeepCopy() Prependable {
|
||||
p.buf = append(View(nil), p.buf...)
|
||||
return p
|
||||
}
|
||||
|
||||
@@ -25,10 +25,9 @@ import (
|
||||
|
||||
// PacketInfo holds all the information about an outbound packet.
|
||||
type PacketInfo struct {
|
||||
Header buffer.View
|
||||
Payload buffer.View
|
||||
Proto tcpip.NetworkProtocolNumber
|
||||
GSO *stack.GSO
|
||||
Pkt tcpip.PacketBuffer
|
||||
Proto tcpip.NetworkProtocolNumber
|
||||
GSO *stack.GSO
|
||||
}
|
||||
|
||||
// Endpoint is link layer endpoint that stores outbound packets in a channel
|
||||
@@ -118,12 +117,11 @@ func (e *Endpoint) LinkAddress() tcpip.LinkAddress {
|
||||
}
|
||||
|
||||
// WritePacket stores outbound packets into the channel.
|
||||
func (e *Endpoint) WritePacket(_ *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (e *Endpoint) WritePacket(_ *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
p := PacketInfo{
|
||||
Header: hdr.View(),
|
||||
Proto: protocol,
|
||||
Payload: payload.ToView(),
|
||||
GSO: gso,
|
||||
Pkt: pkt,
|
||||
Proto: protocol,
|
||||
GSO: gso,
|
||||
}
|
||||
|
||||
select {
|
||||
@@ -139,15 +137,16 @@ func (e *Endpoint) WritePackets(_ *stack.Route, gso *stack.GSO, hdrs []stack.Pac
|
||||
payloadView := payload.ToView()
|
||||
n := 0
|
||||
packetLoop:
|
||||
for i := range hdrs {
|
||||
hdr := &hdrs[i].Hdr
|
||||
off := hdrs[i].Off
|
||||
size := hdrs[i].Size
|
||||
for _, hdr := range hdrs {
|
||||
off := hdr.Off
|
||||
size := hdr.Size
|
||||
p := PacketInfo{
|
||||
Header: hdr.View(),
|
||||
Proto: protocol,
|
||||
Payload: buffer.NewViewFromBytes(payloadView[off : off+size]),
|
||||
GSO: gso,
|
||||
Pkt: tcpip.PacketBuffer{
|
||||
Header: hdr.Hdr,
|
||||
Data: buffer.NewViewFromBytes(payloadView[off : off+size]).ToVectorisedView(),
|
||||
},
|
||||
Proto: protocol,
|
||||
GSO: gso,
|
||||
}
|
||||
|
||||
select {
|
||||
@@ -162,12 +161,11 @@ packetLoop:
|
||||
}
|
||||
|
||||
// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
|
||||
func (e *Endpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
func (e *Endpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
|
||||
p := PacketInfo{
|
||||
Header: packet.ToView(),
|
||||
Proto: 0,
|
||||
Payload: buffer.View{},
|
||||
GSO: nil,
|
||||
Pkt: tcpip.PacketBuffer{Data: vv},
|
||||
Proto: 0,
|
||||
GSO: nil,
|
||||
}
|
||||
|
||||
select {
|
||||
|
||||
@@ -386,10 +386,11 @@ const (
|
||||
|
||||
// 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, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
if e.hdrSize > 0 {
|
||||
// Add ethernet header if needed.
|
||||
eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize))
|
||||
eth := header.Ethernet(pkt.Header.Prepend(header.EthernetMinimumSize))
|
||||
pkt.LinkHeader = buffer.View(eth)
|
||||
ethHdr := &header.EthernetFields{
|
||||
DstAddr: r.RemoteLinkAddress,
|
||||
Type: protocol,
|
||||
@@ -408,13 +409,13 @@ func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prepen
|
||||
vnetHdr := virtioNetHdr{}
|
||||
vnetHdrBuf := vnetHdrToByteSlice(&vnetHdr)
|
||||
if gso != nil {
|
||||
vnetHdr.hdrLen = uint16(hdr.UsedLength())
|
||||
vnetHdr.hdrLen = uint16(pkt.Header.UsedLength())
|
||||
if gso.NeedsCsum {
|
||||
vnetHdr.flags = _VIRTIO_NET_HDR_F_NEEDS_CSUM
|
||||
vnetHdr.csumStart = header.EthernetMinimumSize + gso.L3HdrLen
|
||||
vnetHdr.csumOffset = gso.CsumOffset
|
||||
}
|
||||
if gso.Type != stack.GSONone && uint16(payload.Size()) > gso.MSS {
|
||||
if gso.Type != stack.GSONone && uint16(pkt.Data.Size()) > gso.MSS {
|
||||
switch gso.Type {
|
||||
case stack.GSOTCPv4:
|
||||
vnetHdr.gsoType = _VIRTIO_NET_HDR_GSO_TCPV4
|
||||
@@ -427,14 +428,14 @@ func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prepen
|
||||
}
|
||||
}
|
||||
|
||||
return rawfile.NonBlockingWrite3(e.fds[0], vnetHdrBuf, hdr.View(), payload.ToView())
|
||||
return rawfile.NonBlockingWrite3(e.fds[0], vnetHdrBuf, pkt.Header.View(), pkt.Data.ToView())
|
||||
}
|
||||
|
||||
if payload.Size() == 0 {
|
||||
return rawfile.NonBlockingWrite(e.fds[0], hdr.View())
|
||||
if pkt.Data.Size() == 0 {
|
||||
return rawfile.NonBlockingWrite(e.fds[0], pkt.Header.View())
|
||||
}
|
||||
|
||||
return rawfile.NonBlockingWrite3(e.fds[0], hdr.View(), payload.ToView(), nil)
|
||||
return rawfile.NonBlockingWrite3(e.fds[0], pkt.Header.View(), pkt.Data.ToView(), nil)
|
||||
}
|
||||
|
||||
// WritePackets writes outbound packets to the file descriptor. If it is not
|
||||
@@ -555,8 +556,8 @@ func (e *endpoint) WritePackets(r *stack.Route, gso *stack.GSO, hdrs []stack.Pac
|
||||
}
|
||||
|
||||
// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
|
||||
func (e *endpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
return rawfile.NonBlockingWrite(e.fds[0], packet.ToView())
|
||||
func (e *endpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
|
||||
return rawfile.NonBlockingWrite(e.fds[0], vv.ToView())
|
||||
}
|
||||
|
||||
// InjectOutobund implements stack.InjectableEndpoint.InjectOutbound.
|
||||
|
||||
@@ -168,7 +168,10 @@ func testWritePacket(t *testing.T, plen int, eth bool, gsoMaxSize uint32) {
|
||||
L3HdrLen: header.IPv4MaximumHeaderSize,
|
||||
}
|
||||
}
|
||||
if err := c.ep.WritePacket(r, gso, hdr, payload.ToVectorisedView(), proto); err != nil {
|
||||
if err := c.ep.WritePacket(r, gso, proto, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: payload.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -258,7 +261,10 @@ func TestPreserveSrcAddress(t *testing.T) {
|
||||
// WritePacket panics given a prependable with anything less than
|
||||
// the minimum size of the ethernet header.
|
||||
hdr := buffer.NewPrependable(header.EthernetMinimumSize)
|
||||
if err := c.ep.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, proto); err != nil {
|
||||
if err := c.ep.WritePacket(r, nil /* gso */, proto, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buffer.VectorisedView{},
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,16 +76,16 @@ func (*endpoint) Wait() {}
|
||||
|
||||
// WritePacket implements stack.LinkEndpoint.WritePacket. It delivers outbound
|
||||
// packets to the network-layer dispatcher.
|
||||
func (e *endpoint) WritePacket(_ *stack.Route, _ *stack.GSO, 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()...)
|
||||
func (e *endpoint) WritePacket(_ *stack.Route, _ *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
views := make([]buffer.View, 1, 1+len(pkt.Data.Views()))
|
||||
views[0] = pkt.Header.View()
|
||||
views = append(views, pkt.Data.Views()...)
|
||||
|
||||
// Because we're immediately turning around and writing the packet back to the
|
||||
// rx path, we intentionally don't preserve the remote and local link
|
||||
// addresses from the stack.Route we're passed.
|
||||
// Because we're immediately turning around and writing the packet back
|
||||
// to the rx path, we intentionally don't preserve the remote and local
|
||||
// link addresses from the stack.Route we're passed.
|
||||
e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, protocol, tcpip.PacketBuffer{
|
||||
Data: buffer.NewVectorisedView(len(views[0])+payload.Size(), views),
|
||||
Data: buffer.NewVectorisedView(len(views[0])+pkt.Data.Size(), views),
|
||||
})
|
||||
|
||||
return nil
|
||||
@@ -97,17 +97,17 @@ func (e *endpoint) WritePackets(_ *stack.Route, _ *stack.GSO, hdrs []stack.Packe
|
||||
}
|
||||
|
||||
// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
|
||||
func (e *endpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
func (e *endpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
|
||||
// Reject the packet if it's shorter than an ethernet header.
|
||||
if packet.Size() < header.EthernetMinimumSize {
|
||||
if vv.Size() < header.EthernetMinimumSize {
|
||||
return tcpip.ErrBadAddress
|
||||
}
|
||||
|
||||
// There should be an ethernet header at the beginning of packet.
|
||||
linkHeader := header.Ethernet(packet.First()[:header.EthernetMinimumSize])
|
||||
packet.TrimFront(len(linkHeader))
|
||||
// There should be an ethernet header at the beginning of vv.
|
||||
linkHeader := header.Ethernet(vv.First()[:header.EthernetMinimumSize])
|
||||
vv.TrimFront(len(linkHeader))
|
||||
e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, linkHeader.Type(), tcpip.PacketBuffer{
|
||||
Data: packet,
|
||||
Data: vv,
|
||||
LinkHeader: buffer.View(linkHeader),
|
||||
})
|
||||
|
||||
|
||||
@@ -98,15 +98,15 @@ func (m *InjectableEndpoint) WritePackets(r *stack.Route, gso *stack.GSO, hdrs [
|
||||
// WritePacket writes outbound packets to the appropriate LinkInjectableEndpoint
|
||||
// based on the RemoteAddress. HandleLocal only works if r.RemoteAddress has a
|
||||
// route registered in this endpoint.
|
||||
func (m *InjectableEndpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (m *InjectableEndpoint) WritePacket(r *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
if endpoint, ok := m.routes[r.RemoteAddress]; ok {
|
||||
return endpoint.WritePacket(r, gso, hdr, payload, protocol)
|
||||
return endpoint.WritePacket(r, gso, protocol, pkt)
|
||||
}
|
||||
return tcpip.ErrNoRoute
|
||||
}
|
||||
|
||||
// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
|
||||
func (m *InjectableEndpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
func (m *InjectableEndpoint) WriteRawPacket(buffer.VectorisedView) *tcpip.Error {
|
||||
// WriteRawPacket doesn't get a route or network address, so there's
|
||||
// nowhere to write this.
|
||||
return tcpip.ErrNoRoute
|
||||
|
||||
@@ -50,8 +50,10 @@ func TestInjectableEndpointDispatch(t *testing.T) {
|
||||
hdr.Prepend(1)[0] = 0xFA
|
||||
packetRoute := stack.Route{RemoteAddress: dstIP}
|
||||
|
||||
endpoint.WritePacket(&packetRoute, nil /* gso */, hdr,
|
||||
buffer.NewViewFromBytes([]byte{0xFB}).ToVectorisedView(), ipv4.ProtocolNumber)
|
||||
endpoint.WritePacket(&packetRoute, nil /* gso */, ipv4.ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buffer.NewViewFromBytes([]byte{0xFB}).ToVectorisedView(),
|
||||
})
|
||||
|
||||
buf := make([]byte, 6500)
|
||||
bytesRead, err := sock.Read(buf)
|
||||
@@ -68,8 +70,10 @@ func TestInjectableEndpointDispatchHdrOnly(t *testing.T) {
|
||||
hdr := buffer.NewPrependable(1)
|
||||
hdr.Prepend(1)[0] = 0xFA
|
||||
packetRoute := stack.Route{RemoteAddress: dstIP}
|
||||
endpoint.WritePacket(&packetRoute, nil /* gso */, hdr,
|
||||
buffer.NewView(0).ToVectorisedView(), ipv4.ProtocolNumber)
|
||||
endpoint.WritePacket(&packetRoute, nil /* gso */, ipv4.ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buffer.NewView(0).ToVectorisedView(),
|
||||
})
|
||||
buf := make([]byte, 6500)
|
||||
bytesRead, err := sock.Read(buf)
|
||||
if err != nil {
|
||||
|
||||
@@ -185,9 +185,10 @@ 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, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (e *endpoint) WritePacket(r *stack.Route, _ *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
// Add the ethernet header here.
|
||||
eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize))
|
||||
eth := header.Ethernet(pkt.Header.Prepend(header.EthernetMinimumSize))
|
||||
pkt.LinkHeader = buffer.View(eth)
|
||||
ethHdr := &header.EthernetFields{
|
||||
DstAddr: r.RemoteLinkAddress,
|
||||
Type: protocol,
|
||||
@@ -199,10 +200,10 @@ func (e *endpoint) WritePacket(r *stack.Route, _ *stack.GSO, hdr buffer.Prependa
|
||||
}
|
||||
eth.Encode(ethHdr)
|
||||
|
||||
v := payload.ToView()
|
||||
v := pkt.Data.ToView()
|
||||
// Transmit the packet.
|
||||
e.mu.Lock()
|
||||
ok := e.tx.transmit(hdr.View(), v)
|
||||
ok := e.tx.transmit(pkt.Header.View(), v)
|
||||
e.mu.Unlock()
|
||||
|
||||
if !ok {
|
||||
@@ -218,8 +219,8 @@ func (e *endpoint) WritePackets(r *stack.Route, _ *stack.GSO, hdrs []stack.Packe
|
||||
}
|
||||
|
||||
// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
|
||||
func (e *endpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
v := packet.ToView()
|
||||
func (e *endpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
|
||||
v := vv.ToView()
|
||||
// Transmit the packet.
|
||||
e.mu.Lock()
|
||||
ok := e.tx.transmit(v, buffer.View{})
|
||||
|
||||
@@ -273,7 +273,10 @@ func TestSimpleSend(t *testing.T) {
|
||||
randomFill(buf)
|
||||
|
||||
proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000))
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), proto); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, proto, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -342,7 +345,9 @@ func TestPreserveSrcAddressInSend(t *testing.T) {
|
||||
hdr := buffer.NewPrependable(header.EthernetMinimumSize)
|
||||
|
||||
proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000))
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buffer.VectorisedView{}, proto); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, proto, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -396,7 +401,10 @@ func TestFillTxQueue(t *testing.T) {
|
||||
for i := queuePipeSize / 40; i > 0; i-- {
|
||||
hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()))
|
||||
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed unexpectedly: %v", err)
|
||||
}
|
||||
|
||||
@@ -411,7 +419,10 @@ func TestFillTxQueue(t *testing.T) {
|
||||
|
||||
// Next attempt to write must fail.
|
||||
hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()))
|
||||
if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want {
|
||||
if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != want {
|
||||
t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want)
|
||||
}
|
||||
}
|
||||
@@ -436,7 +447,10 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) {
|
||||
// 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, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed unexpectedly: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -456,7 +470,10 @@ 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, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed unexpectedly: %v", err)
|
||||
}
|
||||
|
||||
@@ -471,7 +488,10 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) {
|
||||
|
||||
// Next attempt to write must fail.
|
||||
hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()))
|
||||
if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != want {
|
||||
if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != want {
|
||||
t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want)
|
||||
}
|
||||
}
|
||||
@@ -494,7 +514,10 @@ func TestFillTxMemory(t *testing.T) {
|
||||
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, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed unexpectedly: %v", err)
|
||||
}
|
||||
|
||||
@@ -510,7 +533,10 @@ func TestFillTxMemory(t *testing.T) {
|
||||
|
||||
// Next attempt to write must fail.
|
||||
hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()))
|
||||
err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber)
|
||||
err := c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
})
|
||||
if want := tcpip.ErrWouldBlock; err != want {
|
||||
t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want)
|
||||
}
|
||||
@@ -535,7 +561,10 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) {
|
||||
// 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, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed unexpectedly: %v", err)
|
||||
}
|
||||
|
||||
@@ -548,7 +577,10 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) {
|
||||
{
|
||||
hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()))
|
||||
uu := buffer.NewView(bufferSize).ToVectorisedView()
|
||||
if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, hdr, uu, header.IPv4ProtocolNumber); err != want {
|
||||
if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: uu,
|
||||
}); err != want {
|
||||
t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want)
|
||||
}
|
||||
}
|
||||
@@ -556,7 +588,10 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) {
|
||||
// Attempt to write the one-buffer packet again. It must succeed.
|
||||
{
|
||||
hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength()))
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, hdr, buf.ToVectorisedView(), header.IPv4ProtocolNumber); err != nil {
|
||||
if err := c.ep.WritePacket(&r, nil /* gso */, header.IPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: buf.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed unexpectedly: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,19 +193,19 @@ func (e *endpoint) GSOMaxSize() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *endpoint) dumpPacket(gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) {
|
||||
func (e *endpoint) dumpPacket(gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil {
|
||||
logPacket("send", protocol, hdr.View(), gso)
|
||||
logPacket("send", protocol, pkt.Header.View(), gso)
|
||||
}
|
||||
if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 {
|
||||
hdrBuf := hdr.View()
|
||||
length := len(hdrBuf) + payload.Size()
|
||||
hdrBuf := pkt.Header.View()
|
||||
length := len(hdrBuf) + pkt.Data.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(len(hdrBuf)+payload.Size()))); err != nil {
|
||||
if err := binary.Write(buf, binary.BigEndian, newPCAPPacketHeader(uint32(length), uint32(len(hdrBuf)+pkt.Data.Size()))); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(hdrBuf) > length {
|
||||
@@ -215,7 +215,7 @@ func (e *endpoint) dumpPacket(gso *stack.GSO, hdr buffer.Prependable, payload bu
|
||||
panic(err)
|
||||
}
|
||||
length -= len(hdrBuf)
|
||||
logVectorisedView(payload, length, buf)
|
||||
logVectorisedView(pkt.Data, length, buf)
|
||||
if _, err := e.file.Write(buf.Bytes()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -225,9 +225,9 @@ func (e *endpoint) dumpPacket(gso *stack.GSO, hdr buffer.Prependable, payload bu
|
||||
// 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, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
e.dumpPacket(gso, hdr, payload, protocol)
|
||||
return e.lower.WritePacket(r, gso, hdr, payload, protocol)
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
e.dumpPacket(gso, protocol, pkt)
|
||||
return e.lower.WritePacket(r, gso, protocol, pkt)
|
||||
}
|
||||
|
||||
// WritePackets implements the stack.LinkEndpoint interface. It is called by
|
||||
@@ -236,32 +236,35 @@ func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prepen
|
||||
func (e *endpoint) WritePackets(r *stack.Route, gso *stack.GSO, hdrs []stack.PacketDescriptor, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) (int, *tcpip.Error) {
|
||||
view := payload.ToView()
|
||||
for _, d := range hdrs {
|
||||
e.dumpPacket(gso, d.Hdr, buffer.NewVectorisedView(d.Size, []buffer.View{view[d.Off:][:d.Size]}), protocol)
|
||||
e.dumpPacket(gso, protocol, tcpip.PacketBuffer{
|
||||
Header: d.Hdr,
|
||||
Data: view[d.Off:][:d.Size].ToVectorisedView(),
|
||||
})
|
||||
}
|
||||
return e.lower.WritePackets(r, gso, hdrs, payload, protocol)
|
||||
}
|
||||
|
||||
// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
|
||||
func (e *endpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
func (e *endpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
|
||||
if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil {
|
||||
logPacket("send", 0, buffer.View("[raw packet, no header available]"), nil /* gso */)
|
||||
}
|
||||
if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 {
|
||||
length := packet.Size()
|
||||
length := vv.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(packet.Size()))); err != nil {
|
||||
if err := binary.Write(buf, binary.BigEndian, newPCAPPacketHeader(uint32(length), uint32(vv.Size()))); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logVectorisedView(packet, length, buf)
|
||||
logVectorisedView(vv, length, buf)
|
||||
if _, err := e.file.Write(buf.Bytes()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return e.lower.WriteRawPacket(packet)
|
||||
return e.lower.WriteRawPacket(vv)
|
||||
}
|
||||
|
||||
func logVectorisedView(vv buffer.VectorisedView, length int, buf *bytes.Buffer) {
|
||||
|
||||
@@ -99,12 +99,12 @@ 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, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (e *Endpoint) WritePacket(r *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
if !e.writeGate.Enter() {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := e.lower.WritePacket(r, gso, hdr, payload, protocol)
|
||||
err := e.lower.WritePacket(r, gso, protocol, pkt)
|
||||
e.writeGate.Leave()
|
||||
return err
|
||||
}
|
||||
@@ -123,12 +123,12 @@ func (e *Endpoint) WritePackets(r *stack.Route, gso *stack.GSO, hdrs []stack.Pac
|
||||
}
|
||||
|
||||
// WriteRawPacket implements stack.LinkEndpoint.WriteRawPacket.
|
||||
func (e *Endpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
func (e *Endpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
|
||||
if !e.writeGate.Enter() {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := e.lower.WriteRawPacket(packet)
|
||||
err := e.lower.WriteRawPacket(vv)
|
||||
e.writeGate.Leave()
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (e *countedEndpoint) LinkAddress() tcpip.LinkAddress {
|
||||
return e.linkAddr
|
||||
}
|
||||
|
||||
func (e *countedEndpoint) WritePacket(r *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (e *countedEndpoint) WritePacket(r *stack.Route, _ *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
e.writeCount++
|
||||
return nil
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func (e *countedEndpoint) WritePackets(r *stack.Route, _ *stack.GSO, hdrs []stac
|
||||
return len(hdrs), nil
|
||||
}
|
||||
|
||||
func (e *countedEndpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
func (e *countedEndpoint) WriteRawPacket(buffer.VectorisedView) *tcpip.Error {
|
||||
e.writeCount++
|
||||
return nil
|
||||
}
|
||||
@@ -89,21 +89,21 @@ func TestWaitWrite(t *testing.T) {
|
||||
wep := New(ep)
|
||||
|
||||
// Write and check that it goes through.
|
||||
wep.WritePacket(nil, nil /* gso */, buffer.Prependable{}, buffer.VectorisedView{}, 0)
|
||||
wep.WritePacket(nil, nil /* gso */, 0, tcpip.PacketBuffer{})
|
||||
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 /* gso */, buffer.Prependable{}, buffer.VectorisedView{}, 0)
|
||||
wep.WritePacket(nil, nil /* gso */, 0, tcpip.PacketBuffer{})
|
||||
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 /* gso */, buffer.Prependable{}, buffer.VectorisedView{}, 0)
|
||||
wep.WritePacket(nil, nil /* gso */, 0, tcpip.PacketBuffer{})
|
||||
if want := 2; ep.writeCount != want {
|
||||
t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want)
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ func (e *endpoint) MaxHeaderLength() uint16 {
|
||||
|
||||
func (e *endpoint) Close() {}
|
||||
|
||||
func (e *endpoint) WritePacket(*stack.Route, *stack.GSO, buffer.Prependable, buffer.VectorisedView, stack.NetworkHeaderParams, stack.PacketLooping) *tcpip.Error {
|
||||
func (e *endpoint) WritePacket(*stack.Route, *stack.GSO, stack.NetworkHeaderParams, stack.PacketLooping, tcpip.PacketBuffer) *tcpip.Error {
|
||||
return tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func (e *endpoint) WritePackets(*stack.Route, *stack.GSO, []stack.PacketDescript
|
||||
return 0, tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, payload buffer.VectorisedView, loop stack.PacketLooping) *tcpip.Error {
|
||||
func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, loop stack.PacketLooping, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
return tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
@@ -106,14 +106,16 @@ func (e *endpoint) HandlePacket(r *stack.Route, pkt tcpip.PacketBuffer) {
|
||||
return // we have no useful answer, ignore the request
|
||||
}
|
||||
hdr := buffer.NewPrependable(int(e.linkEP.MaxHeaderLength()) + header.ARPSize)
|
||||
pkt := header.ARP(hdr.Prepend(header.ARPSize))
|
||||
pkt.SetIPv4OverEthernet()
|
||||
pkt.SetOp(header.ARPReply)
|
||||
copy(pkt.HardwareAddressSender(), r.LocalLinkAddress[:])
|
||||
copy(pkt.ProtocolAddressSender(), h.ProtocolAddressTarget())
|
||||
copy(pkt.HardwareAddressTarget(), h.HardwareAddressSender())
|
||||
copy(pkt.ProtocolAddressTarget(), h.ProtocolAddressSender())
|
||||
e.linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber)
|
||||
packet := header.ARP(hdr.Prepend(header.ARPSize))
|
||||
packet.SetIPv4OverEthernet()
|
||||
packet.SetOp(header.ARPReply)
|
||||
copy(packet.HardwareAddressSender(), r.LocalLinkAddress[:])
|
||||
copy(packet.ProtocolAddressSender(), h.ProtocolAddressTarget())
|
||||
copy(packet.HardwareAddressTarget(), h.HardwareAddressSender())
|
||||
copy(packet.ProtocolAddressTarget(), h.ProtocolAddressSender())
|
||||
e.linkEP.WritePacket(r, nil /* gso */, ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
})
|
||||
fallthrough // also fill the cache from requests
|
||||
case header.ARPReply:
|
||||
addr := tcpip.Address(h.ProtocolAddressSender())
|
||||
@@ -165,7 +167,9 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.
|
||||
copy(h.ProtocolAddressSender(), localAddr)
|
||||
copy(h.ProtocolAddressTarget(), addr)
|
||||
|
||||
return linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber)
|
||||
return linkEP.WritePacket(r, nil /* gso */, ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
})
|
||||
}
|
||||
|
||||
// ResolveStaticAddress implements stack.LinkAddressResolver.
|
||||
|
||||
@@ -110,13 +110,13 @@ func TestDirectRequest(t *testing.T) {
|
||||
for i, address := range []tcpip.Address{stackAddr1, stackAddr2} {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
inject(address)
|
||||
pkt := <-c.linkEP.C
|
||||
if pkt.Proto != arp.ProtocolNumber {
|
||||
t.Fatalf("expected ARP response, got network protocol number %d", pkt.Proto)
|
||||
pi := <-c.linkEP.C
|
||||
if pi.Proto != arp.ProtocolNumber {
|
||||
t.Fatalf("expected ARP response, got network protocol number %d", pi.Proto)
|
||||
}
|
||||
rep := header.ARP(pkt.Header)
|
||||
rep := header.ARP(pi.Pkt.Header.View())
|
||||
if !rep.IsValid() {
|
||||
t.Fatalf("invalid ARP response len(pkt.Header)=%d", len(pkt.Header))
|
||||
t.Fatalf("invalid ARP response pi.Pkt.Header.UsedLength()=%d", pi.Pkt.Header.UsedLength())
|
||||
}
|
||||
if got, want := tcpip.LinkAddress(rep.HardwareAddressSender()), stackLinkAddr; got != want {
|
||||
t.Errorf("got HardwareAddressSender = %s, want = %s", got, want)
|
||||
|
||||
@@ -150,24 +150,24 @@ func (*testObject) Wait() {}
|
||||
// WritePacket is called by network endpoints after producing a packet and
|
||||
// writing it to the link endpoint. This is used by the test object to verify
|
||||
// that the produced packet is as expected.
|
||||
func (t *testObject) WritePacket(_ *stack.Route, _ *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (t *testObject) WritePacket(_ *stack.Route, _ *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
var prot tcpip.TransportProtocolNumber
|
||||
var srcAddr tcpip.Address
|
||||
var dstAddr tcpip.Address
|
||||
|
||||
if t.v4 {
|
||||
h := header.IPv4(hdr.View())
|
||||
h := header.IPv4(pkt.Header.View())
|
||||
prot = tcpip.TransportProtocolNumber(h.Protocol())
|
||||
srcAddr = h.SourceAddress()
|
||||
dstAddr = h.DestinationAddress()
|
||||
|
||||
} else {
|
||||
h := header.IPv6(hdr.View())
|
||||
h := header.IPv6(pkt.Header.View())
|
||||
prot = tcpip.TransportProtocolNumber(h.NextHeader())
|
||||
srcAddr = h.SourceAddress()
|
||||
dstAddr = h.DestinationAddress()
|
||||
}
|
||||
t.checkValues(prot, payload, srcAddr, dstAddr)
|
||||
t.checkValues(prot, pkt.Data, srcAddr, dstAddr)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -239,7 +239,10 @@ func TestIPv4Send(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("could not find route: %v", err)
|
||||
}
|
||||
if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), stack.NetworkHeaderParams{Protocol: 123, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketOut); err != nil {
|
||||
if err := ep.WritePacket(&r, nil /* gso */, stack.NetworkHeaderParams{Protocol: 123, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketOut, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: payload.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -477,7 +480,10 @@ func TestIPv6Send(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("could not find route: %v", err)
|
||||
}
|
||||
if err := ep.WritePacket(&r, nil /* gso */, hdr, payload.ToVectorisedView(), stack.NetworkHeaderParams{Protocol: 123, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketOut); err != nil {
|
||||
if err := ep.WritePacket(&r, nil /* gso */, stack.NetworkHeaderParams{Protocol: 123, TTL: 123, TOS: stack.DefaultTOS}, stack.PacketOut, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: payload.ToVectorisedView(),
|
||||
}); err != nil {
|
||||
t.Fatalf("WritePacket failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,11 @@ func (e *endpoint) handleICMP(r *stack.Route, pkt tcpip.PacketBuffer) {
|
||||
pkt.SetChecksum(0)
|
||||
pkt.SetChecksum(^header.Checksum(pkt, header.ChecksumVV(vv, 0)))
|
||||
sent := stats.ICMP.V4PacketsSent
|
||||
if err := r.WritePacket(nil /* gso */, hdr, vv, stack.NetworkHeaderParams{Protocol: header.ICMPv4ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}); err != nil {
|
||||
if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: header.ICMPv4ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: vv,
|
||||
TransportHeader: buffer.View(pkt),
|
||||
}); err != nil {
|
||||
sent.Dropped.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -117,13 +117,14 @@ func (e *endpoint) GSOMaxSize() uint32 {
|
||||
}
|
||||
|
||||
// writePacketFragments calls e.linkEP.WritePacket with each packet fragment to
|
||||
// write. It assumes that the IP header is entirely in hdr but does not assume
|
||||
// that only the IP header is in hdr. It assumes that the input packet's stated
|
||||
// length matches the length of the hdr+payload. mtu includes the IP header and
|
||||
// options. This does not support the DontFragment IP flag.
|
||||
func (e *endpoint) writePacketFragments(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, mtu int) *tcpip.Error {
|
||||
// write. It assumes that the IP header is entirely in pkt.Header but does not
|
||||
// assume that only the IP header is in pkt.Header. It assumes that the input
|
||||
// packet's stated length matches the length of the header+payload. mtu
|
||||
// includes the IP header and options. This does not support the DontFragment
|
||||
// IP flag.
|
||||
func (e *endpoint) writePacketFragments(r *stack.Route, gso *stack.GSO, mtu int, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
// This packet is too big, it needs to be fragmented.
|
||||
ip := header.IPv4(hdr.View())
|
||||
ip := header.IPv4(pkt.Header.View())
|
||||
flags := ip.Flags()
|
||||
|
||||
// Update mtu to take into account the header, which will exist in all
|
||||
@@ -137,62 +138,77 @@ func (e *endpoint) writePacketFragments(r *stack.Route, gso *stack.GSO, hdr buff
|
||||
|
||||
outerMTU := innerMTU + int(ip.HeaderLength())
|
||||
offset := ip.FragmentOffset()
|
||||
originalAvailableLength := hdr.AvailableLength()
|
||||
originalAvailableLength := pkt.Header.AvailableLength()
|
||||
for i := 0; i < n; i++ {
|
||||
// Where possible, the first fragment that is sent has the same
|
||||
// hdr.UsedLength() as the input packet. The link-layer endpoint may depends
|
||||
// on this for looking at, eg, L4 headers.
|
||||
// pkt.Header.UsedLength() as the input packet. The link-layer
|
||||
// endpoint may depend on this for looking at, eg, L4 headers.
|
||||
h := ip
|
||||
if i > 0 {
|
||||
hdr = buffer.NewPrependable(int(ip.HeaderLength()) + originalAvailableLength)
|
||||
h = header.IPv4(hdr.Prepend(int(ip.HeaderLength())))
|
||||
pkt.Header = buffer.NewPrependable(int(ip.HeaderLength()) + originalAvailableLength)
|
||||
h = header.IPv4(pkt.Header.Prepend(int(ip.HeaderLength())))
|
||||
copy(h, ip[:ip.HeaderLength()])
|
||||
}
|
||||
if i != n-1 {
|
||||
h.SetTotalLength(uint16(outerMTU))
|
||||
h.SetFlagsFragmentOffset(flags|header.IPv4FlagMoreFragments, offset)
|
||||
} else {
|
||||
h.SetTotalLength(uint16(h.HeaderLength()) + uint16(payload.Size()))
|
||||
h.SetTotalLength(uint16(h.HeaderLength()) + uint16(pkt.Data.Size()))
|
||||
h.SetFlagsFragmentOffset(flags, offset)
|
||||
}
|
||||
h.SetChecksum(0)
|
||||
h.SetChecksum(^h.CalculateChecksum())
|
||||
offset += uint16(innerMTU)
|
||||
if i > 0 {
|
||||
newPayload := payload.Clone([]buffer.View{})
|
||||
newPayload := pkt.Data.Clone(nil)
|
||||
newPayload.CapLength(innerMTU)
|
||||
if err := e.linkEP.WritePacket(r, gso, hdr, newPayload, ProtocolNumber); err != nil {
|
||||
if err := e.linkEP.WritePacket(r, gso, ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: pkt.Header,
|
||||
Data: newPayload,
|
||||
NetworkHeader: buffer.View(h),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Stats().IP.PacketsSent.Increment()
|
||||
payload.TrimFront(newPayload.Size())
|
||||
pkt.Data.TrimFront(newPayload.Size())
|
||||
continue
|
||||
}
|
||||
// Special handling for the first fragment because it comes from the hdr.
|
||||
if outerMTU >= hdr.UsedLength() {
|
||||
// This fragment can fit all of hdr and possibly some of payload, too.
|
||||
newPayload := payload.Clone([]buffer.View{})
|
||||
newPayloadLength := outerMTU - hdr.UsedLength()
|
||||
// Special handling for the first fragment because it comes
|
||||
// from the header.
|
||||
if outerMTU >= pkt.Header.UsedLength() {
|
||||
// This fragment can fit all of pkt.Header and possibly
|
||||
// some of pkt.Data, too.
|
||||
newPayload := pkt.Data.Clone(nil)
|
||||
newPayloadLength := outerMTU - pkt.Header.UsedLength()
|
||||
newPayload.CapLength(newPayloadLength)
|
||||
if err := e.linkEP.WritePacket(r, gso, hdr, newPayload, ProtocolNumber); err != nil {
|
||||
if err := e.linkEP.WritePacket(r, gso, ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: pkt.Header,
|
||||
Data: newPayload,
|
||||
NetworkHeader: buffer.View(h),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Stats().IP.PacketsSent.Increment()
|
||||
payload.TrimFront(newPayloadLength)
|
||||
pkt.Data.TrimFront(newPayloadLength)
|
||||
} else {
|
||||
// The fragment is too small to fit all of hdr.
|
||||
startOfHdr := hdr
|
||||
startOfHdr.TrimBack(hdr.UsedLength() - outerMTU)
|
||||
// The fragment is too small to fit all of pkt.Header.
|
||||
startOfHdr := pkt.Header
|
||||
startOfHdr.TrimBack(pkt.Header.UsedLength() - outerMTU)
|
||||
emptyVV := buffer.NewVectorisedView(0, []buffer.View{})
|
||||
if err := e.linkEP.WritePacket(r, gso, startOfHdr, emptyVV, ProtocolNumber); err != nil {
|
||||
if err := e.linkEP.WritePacket(r, gso, ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: startOfHdr,
|
||||
Data: emptyVV,
|
||||
NetworkHeader: buffer.View(h),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Stats().IP.PacketsSent.Increment()
|
||||
// Add the unused bytes of hdr into the payload that remains to be sent.
|
||||
restOfHdr := hdr.View()[outerMTU:]
|
||||
// Add the unused bytes of pkt.Header into the pkt.Data
|
||||
// that remains to be sent.
|
||||
restOfHdr := pkt.Header.View()[outerMTU:]
|
||||
tmp := buffer.NewVectorisedView(len(restOfHdr), []buffer.View{buffer.NewViewFromBytes(restOfHdr)})
|
||||
tmp.Append(payload)
|
||||
payload = tmp
|
||||
tmp.Append(pkt.Data)
|
||||
pkt.Data = tmp
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -222,17 +238,17 @@ func (e *endpoint) addIPHeader(r *stack.Route, hdr *buffer.Prependable, payloadS
|
||||
}
|
||||
|
||||
// WritePacket writes a packet to the given destination address and protocol.
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, params stack.NetworkHeaderParams, loop stack.PacketLooping) *tcpip.Error {
|
||||
ip := e.addIPHeader(r, &hdr, payload.Size(), params)
|
||||
func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, params stack.NetworkHeaderParams, loop stack.PacketLooping, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
ip := e.addIPHeader(r, &pkt.Header, pkt.Data.Size(), params)
|
||||
|
||||
if loop&stack.PacketLoop != 0 {
|
||||
views := make([]buffer.View, 1, 1+len(payload.Views()))
|
||||
views[0] = hdr.View()
|
||||
views = append(views, payload.Views()...)
|
||||
views := make([]buffer.View, 1, 1+len(pkt.Data.Views()))
|
||||
views[0] = pkt.Header.View()
|
||||
views = append(views, pkt.Data.Views()...)
|
||||
loopedR := r.MakeLoopedRoute()
|
||||
|
||||
e.HandlePacket(&loopedR, tcpip.PacketBuffer{
|
||||
Data: buffer.NewVectorisedView(len(views[0])+payload.Size(), views),
|
||||
Data: buffer.NewVectorisedView(len(views[0])+pkt.Data.Size(), views),
|
||||
NetworkHeader: buffer.View(ip),
|
||||
})
|
||||
|
||||
@@ -241,10 +257,10 @@ func (e *endpoint) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prepen
|
||||
if loop&stack.PacketOut == 0 {
|
||||
return nil
|
||||
}
|
||||
if hdr.UsedLength()+payload.Size() > int(e.linkEP.MTU()) && (gso == nil || gso.Type == stack.GSONone) {
|
||||
return e.writePacketFragments(r, gso, hdr, payload, int(e.linkEP.MTU()))
|
||||
if pkt.Header.UsedLength()+pkt.Data.Size() > int(e.linkEP.MTU()) && (gso == nil || gso.Type == stack.GSONone) {
|
||||
return e.writePacketFragments(r, gso, int(e.linkEP.MTU()), pkt)
|
||||
}
|
||||
if err := e.linkEP.WritePacket(r, gso, hdr, payload, ProtocolNumber); err != nil {
|
||||
if err := e.linkEP.WritePacket(r, gso, ProtocolNumber, pkt); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Stats().IP.PacketsSent.Increment()
|
||||
@@ -270,16 +286,16 @@ func (e *endpoint) WritePackets(r *stack.Route, gso *stack.GSO, hdrs []stack.Pac
|
||||
|
||||
// WriteHeaderIncludedPacket writes a packet already containing a network
|
||||
// header through the given route.
|
||||
func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, payload buffer.VectorisedView, loop stack.PacketLooping) *tcpip.Error {
|
||||
func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, loop stack.PacketLooping, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
// The packet already has an IP header, but there are a few required
|
||||
// checks.
|
||||
ip := header.IPv4(payload.First())
|
||||
if !ip.IsValid(payload.Size()) {
|
||||
ip := header.IPv4(pkt.Data.First())
|
||||
if !ip.IsValid(pkt.Data.Size()) {
|
||||
return tcpip.ErrInvalidOptionValue
|
||||
}
|
||||
|
||||
// Always set the total length.
|
||||
ip.SetTotalLength(uint16(payload.Size()))
|
||||
ip.SetTotalLength(uint16(pkt.Data.Size()))
|
||||
|
||||
// Set the source address when zero.
|
||||
if ip.SourceAddress() == tcpip.Address(([]byte{0, 0, 0, 0})) {
|
||||
@@ -293,7 +309,7 @@ func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, payload buffer.Vect
|
||||
// Set the packet ID when zero.
|
||||
if ip.ID() == 0 {
|
||||
id := uint32(0)
|
||||
if payload.Size() > header.IPv4MaximumHeaderSize+8 {
|
||||
if pkt.Data.Size() > header.IPv4MaximumHeaderSize+8 {
|
||||
// Packets of 68 bytes or less are required by RFC 791 to not be
|
||||
// fragmented, so we only assign ids to larger packets.
|
||||
id = atomic.AddUint32(&e.protocol.ids[hashRoute(r, 0 /* protocol */, e.protocol.hashIV)%buckets], 1)
|
||||
@@ -306,18 +322,18 @@ func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, payload buffer.Vect
|
||||
ip.SetChecksum(^ip.CalculateChecksum())
|
||||
|
||||
if loop&stack.PacketLoop != 0 {
|
||||
e.HandlePacket(r, tcpip.PacketBuffer{
|
||||
Data: payload,
|
||||
NetworkHeader: buffer.View(ip),
|
||||
})
|
||||
e.HandlePacket(r, pkt.Clone())
|
||||
}
|
||||
if loop&stack.PacketOut == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
hdr := buffer.NewPrependableFromView(payload.ToView())
|
||||
r.Stats().IP.PacketsSent.Increment()
|
||||
return e.linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber)
|
||||
|
||||
ip = ip[:ip.HeaderLength()]
|
||||
pkt.Header = buffer.NewPrependableFromView(buffer.View(ip))
|
||||
pkt.Data.TrimFront(int(ip.HeaderLength()))
|
||||
return e.linkEP.WritePacket(r, nil /* gso */, ProtocolNumber, pkt)
|
||||
}
|
||||
|
||||
// HandlePacket is called by the link layer when new ipv4 packets arrive for
|
||||
|
||||
@@ -113,12 +113,12 @@ func makeHdrAndPayload(hdrLength int, extraLength int, viewSizes []int) (buffer.
|
||||
|
||||
// comparePayloads compared the contents of all the packets against the contents
|
||||
// of the source packet.
|
||||
func compareFragments(t *testing.T, packets []packetInfo, sourcePacketInfo packetInfo, mtu uint32) {
|
||||
func compareFragments(t *testing.T, packets []tcpip.PacketBuffer, sourcePacketInfo tcpip.PacketBuffer, mtu uint32) {
|
||||
t.Helper()
|
||||
// Make a complete array of the sourcePacketInfo packet.
|
||||
source := header.IPv4(packets[0].Header.View()[:header.IPv4MinimumSize])
|
||||
source = append(source, sourcePacketInfo.Header.View()...)
|
||||
source = append(source, sourcePacketInfo.Payload.ToView()...)
|
||||
source = append(source, sourcePacketInfo.Data.ToView()...)
|
||||
|
||||
// Make a copy of the IP header, which will be modified in some fields to make
|
||||
// an expected header.
|
||||
@@ -132,7 +132,7 @@ func compareFragments(t *testing.T, packets []packetInfo, sourcePacketInfo packe
|
||||
for i, packet := range packets {
|
||||
// Confirm that the packet is valid.
|
||||
allBytes := packet.Header.View().ToVectorisedView()
|
||||
allBytes.Append(packet.Payload)
|
||||
allBytes.Append(packet.Data)
|
||||
ip := header.IPv4(allBytes.ToView())
|
||||
if !ip.IsValid(len(ip)) {
|
||||
t.Errorf("IP packet is invalid:\n%s", hex.Dump(ip))
|
||||
@@ -173,7 +173,7 @@ func compareFragments(t *testing.T, packets []packetInfo, sourcePacketInfo packe
|
||||
|
||||
type errorChannel struct {
|
||||
*channel.Endpoint
|
||||
Ch chan packetInfo
|
||||
Ch chan tcpip.PacketBuffer
|
||||
packetCollectorErrors []*tcpip.Error
|
||||
}
|
||||
|
||||
@@ -183,17 +183,11 @@ type errorChannel struct {
|
||||
func newErrorChannel(size int, mtu uint32, linkAddr tcpip.LinkAddress, packetCollectorErrors []*tcpip.Error) *errorChannel {
|
||||
return &errorChannel{
|
||||
Endpoint: channel.New(size, mtu, linkAddr),
|
||||
Ch: make(chan packetInfo, size),
|
||||
Ch: make(chan tcpip.PacketBuffer, size),
|
||||
packetCollectorErrors: packetCollectorErrors,
|
||||
}
|
||||
}
|
||||
|
||||
// packetInfo holds all the information about an outbound packet.
|
||||
type packetInfo struct {
|
||||
Header buffer.Prependable
|
||||
Payload buffer.VectorisedView
|
||||
}
|
||||
|
||||
// Drain removes all outbound packets from the channel and counts them.
|
||||
func (e *errorChannel) Drain() int {
|
||||
c := 0
|
||||
@@ -208,14 +202,9 @@ func (e *errorChannel) Drain() int {
|
||||
}
|
||||
|
||||
// WritePacket stores outbound packets into the channel.
|
||||
func (e *errorChannel) WritePacket(r *stack.Route, gso *stack.GSO, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
p := packetInfo{
|
||||
Header: hdr,
|
||||
Payload: payload,
|
||||
}
|
||||
|
||||
func (e *errorChannel) WritePacket(r *stack.Route, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) *tcpip.Error {
|
||||
select {
|
||||
case e.Ch <- p:
|
||||
case e.Ch <- pkt:
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -292,18 +281,21 @@ func TestFragmentation(t *testing.T) {
|
||||
for _, ft := range fragTests {
|
||||
t.Run(ft.description, func(t *testing.T) {
|
||||
hdr, payload := makeHdrAndPayload(ft.hdrLength, ft.extraLength, ft.payloadViewsSizes)
|
||||
source := packetInfo{
|
||||
source := tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
// Save the source payload because WritePacket will modify it.
|
||||
Payload: payload.Clone([]buffer.View{}),
|
||||
Data: payload.Clone(nil),
|
||||
}
|
||||
c := buildContext(t, nil, ft.mtu)
|
||||
err := c.Route.WritePacket(ft.gso, hdr, payload, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS})
|
||||
err := c.Route.WritePacket(ft.gso, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS}, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: payload,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("err got %v, want %v", err, nil)
|
||||
}
|
||||
|
||||
var results []packetInfo
|
||||
var results []tcpip.PacketBuffer
|
||||
L:
|
||||
for {
|
||||
select {
|
||||
@@ -345,7 +337,10 @@ func TestFragmentationErrors(t *testing.T) {
|
||||
t.Run(ft.description, func(t *testing.T) {
|
||||
hdr, payload := makeHdrAndPayload(ft.hdrLength, header.IPv4MinimumSize, ft.payloadViewsSizes)
|
||||
c := buildContext(t, ft.packetCollectorErrors, ft.mtu)
|
||||
err := c.Route.WritePacket(&stack.GSO{}, hdr, payload, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS})
|
||||
err := c.Route.WritePacket(&stack.GSO{}, stack.NetworkHeaderParams{Protocol: tcp.ProtocolNumber, TTL: 42, TOS: stack.DefaultTOS}, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: payload,
|
||||
})
|
||||
for i := 0; i < len(ft.packetCollectorErrors)-1; i++ {
|
||||
if got, want := ft.packetCollectorErrors[i], (*tcpip.Error)(nil); got != want {
|
||||
t.Errorf("ft.packetCollectorErrors[%d] got %v, want %v", i, got, want)
|
||||
|
||||
@@ -226,7 +226,9 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, pkt tcpip.P
|
||||
//
|
||||
// The IP Hop Limit field has a value of 255, i.e., the packet
|
||||
// could not possibly have been forwarded by a router.
|
||||
if err := r.WritePacket(nil /* gso */, hdr, buffer.VectorisedView{}, stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: header.NDPHopLimit, TOS: stack.DefaultTOS}); err != nil {
|
||||
if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: header.NDPHopLimit, TOS: stack.DefaultTOS}, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
}); err != nil {
|
||||
sent.Dropped.Increment()
|
||||
return
|
||||
}
|
||||
@@ -291,7 +293,10 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, pkt tcpip.P
|
||||
copy(packet, h)
|
||||
packet.SetType(header.ICMPv6EchoReply)
|
||||
packet.SetChecksum(header.ICMPv6Checksum(packet, r.LocalAddress, r.RemoteAddress, pkt.Data))
|
||||
if err := r.WritePacket(nil /* gso */, hdr, pkt.Data, stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}); err != nil {
|
||||
if err := r.WritePacket(nil /* gso */, stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
Data: pkt.Data,
|
||||
}); err != nil {
|
||||
sent.Dropped.Increment()
|
||||
return
|
||||
}
|
||||
@@ -417,7 +422,9 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack.
|
||||
})
|
||||
|
||||
// TODO(stijlist): count this in ICMP stats.
|
||||
return linkEP.WritePacket(r, nil /* gso */, hdr, buffer.VectorisedView{}, ProtocolNumber)
|
||||
return linkEP.WritePacket(r, nil /* gso */, ProtocolNumber, tcpip.PacketBuffer{
|
||||
Header: hdr,
|
||||
})
|
||||
}
|
||||
|
||||
// ResolveStaticAddress implements stack.LinkAddressResolver.
|
||||
|
||||
@@ -55,7 +55,7 @@ func (*stubLinkEndpoint) LinkAddress() tcpip.LinkAddress {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (*stubLinkEndpoint) WritePacket(*stack.Route, *stack.GSO, buffer.Prependable, buffer.VectorisedView, tcpip.NetworkProtocolNumber) *tcpip.Error {
|
||||
func (*stubLinkEndpoint) WritePacket(*stack.Route, *stack.GSO, tcpip.NetworkProtocolNumber, tcpip.PacketBuffer) *tcpip.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -276,22 +276,22 @@ type routeArgs struct {
|
||||
func routeICMPv6Packet(t *testing.T, args routeArgs, fn func(*testing.T, header.ICMPv6)) {
|
||||
t.Helper()
|
||||
|
||||
pkt := <-args.src.C
|
||||
pi := <-args.src.C
|
||||
|
||||
{
|
||||
views := []buffer.View{pkt.Header, pkt.Payload}
|
||||
size := len(pkt.Header) + len(pkt.Payload)
|
||||
views := []buffer.View{pi.Pkt.Header.View(), pi.Pkt.Data.ToView()}
|
||||
size := pi.Pkt.Header.UsedLength() + pi.Pkt.Data.Size()
|
||||
vv := buffer.NewVectorisedView(size, views)
|
||||
args.dst.InjectLinkAddr(pkt.Proto, args.dst.LinkAddress(), tcpip.PacketBuffer{
|
||||
args.dst.InjectLinkAddr(pi.Proto, args.dst.LinkAddress(), tcpip.PacketBuffer{
|
||||
Data: vv,
|
||||
})
|
||||
}
|
||||
|
||||
if pkt.Proto != ProtocolNumber {
|
||||
t.Errorf("unexpected protocol number %d", pkt.Proto)
|
||||
if pi.Proto != ProtocolNumber {
|
||||
t.Errorf("unexpected protocol number %d", pi.Proto)
|
||||
return
|
||||
}
|
||||
ipv6 := header.IPv6(pkt.Header)
|
||||
ipv6 := header.IPv6(pi.Pkt.Header.View())
|
||||
transProto := tcpip.TransportProtocolNumber(ipv6.NextHeader())
|
||||
if transProto != header.ICMPv6ProtocolNumber {
|
||||
t.Errorf("unexpected transport protocol number %d", transProto)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user