mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Make dedicated methods for data operations in PacketBuffer
One of the preparation to decouple underlying buffer implementation. There are still some methods that tie to VectorisedView, and they will be changed gradually in later CLs. This CL also introduce a new ICMPv6ChecksumParams to replace long list of parameters when calling ICMPv6Checksum, aiming to be more descriptive. PiperOrigin-RevId: 360778149
This commit is contained in:
@@ -196,7 +196,7 @@ func (vv *VectorisedView) CapLength(length int) {
|
||||
// If the buffer argument is large enough to contain all the Views of this
|
||||
// VectorisedView, the method will avoid allocations and use the buffer to
|
||||
// store the Views of the clone.
|
||||
func (vv *VectorisedView) Clone(buffer []View) VectorisedView {
|
||||
func (vv VectorisedView) Clone(buffer []View) VectorisedView {
|
||||
return VectorisedView{views: append(buffer[:0], vv.views...), size: vv.size}
|
||||
}
|
||||
|
||||
@@ -290,6 +290,14 @@ func (vv *VectorisedView) AppendView(v View) {
|
||||
vv.size += len(v)
|
||||
}
|
||||
|
||||
// AppendViews appends views to vv.
|
||||
func (vv *VectorisedView) AppendViews(views []View) {
|
||||
vv.views = append(vv.views, views...)
|
||||
for _, v := range views {
|
||||
vv.size += len(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Readers returns a bytes.Reader for each of vv's views.
|
||||
func (vv *VectorisedView) Readers() []bytes.Reader {
|
||||
readers := make([]bytes.Reader, 0, len(vv.views))
|
||||
|
||||
@@ -45,6 +45,11 @@ func vv(size int, pieces ...string) buffer.VectorisedView {
|
||||
return buffer.NewVectorisedView(size, views)
|
||||
}
|
||||
|
||||
// v returns a buffer.View containing piece.
|
||||
func v(piece string) buffer.View {
|
||||
return buffer.View(piece)
|
||||
}
|
||||
|
||||
var capLengthTestCases = []struct {
|
||||
comment string
|
||||
in buffer.VectorisedView
|
||||
@@ -124,6 +129,12 @@ var trimFrontTestCases = []struct {
|
||||
count: 2,
|
||||
want: vv(1, "3"),
|
||||
},
|
||||
{
|
||||
comment: "Case with one empty Views",
|
||||
in: vv(3, "1", "", "23"),
|
||||
count: 2,
|
||||
want: vv(1, "3"),
|
||||
},
|
||||
{
|
||||
comment: "Corner case with negative count",
|
||||
in: vv(1, "1"),
|
||||
@@ -566,11 +577,11 @@ func TestAppendView(t *testing.T) {
|
||||
in buffer.View
|
||||
want buffer.VectorisedView
|
||||
}{
|
||||
{buffer.VectorisedView{}, nil, buffer.VectorisedView{}},
|
||||
{buffer.VectorisedView{}, buffer.View{}, buffer.VectorisedView{}},
|
||||
{buffer.NewVectorisedView(4, []buffer.View{{'a', 'b', 'c', 'd'}}), nil, buffer.NewVectorisedView(4, []buffer.View{{'a', 'b', 'c', 'd'}})},
|
||||
{buffer.NewVectorisedView(4, []buffer.View{{'a', 'b', 'c', 'd'}}), buffer.View{}, buffer.NewVectorisedView(4, []buffer.View{{'a', 'b', 'c', 'd'}})},
|
||||
{buffer.NewVectorisedView(4, []buffer.View{{'a', 'b', 'c', 'd'}}), buffer.View{'e'}, buffer.NewVectorisedView(5, []buffer.View{{'a', 'b', 'c', 'd'}, {'e'}})},
|
||||
{vv(0), nil, vv(0)},
|
||||
{vv(0), v(""), vv(0)},
|
||||
{vv(4, "abcd"), nil, vv(4, "abcd")},
|
||||
{vv(4, "abcd"), v(""), vv(4, "abcd")},
|
||||
{vv(4, "abcd"), v("e"), vv(5, "abcd", "e")},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc.vv.AppendView(tc.in)
|
||||
@@ -580,6 +591,31 @@ func TestAppendView(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendViews(t *testing.T) {
|
||||
testCases := []struct {
|
||||
vv buffer.VectorisedView
|
||||
in []buffer.View
|
||||
want buffer.VectorisedView
|
||||
}{
|
||||
{vv(0), nil, vv(0)},
|
||||
{vv(0), []buffer.View{}, vv(0)},
|
||||
{vv(0), []buffer.View{v("")}, vv(0, "")},
|
||||
{vv(4, "abcd"), nil, vv(4, "abcd")},
|
||||
{vv(4, "abcd"), []buffer.View{}, vv(4, "abcd")},
|
||||
{vv(4, "abcd"), []buffer.View{v("")}, vv(4, "abcd", "")},
|
||||
{vv(4, "abcd"), []buffer.View{v("")}, vv(4, "abcd", "")},
|
||||
{vv(4, "abcd"), []buffer.View{v("e")}, vv(5, "abcd", "e")},
|
||||
{vv(4, "abcd"), []buffer.View{v("e"), v("fg")}, vv(7, "abcd", "e", "fg")},
|
||||
{vv(4, "abcd"), []buffer.View{v(""), v("fg")}, vv(6, "abcd", "", "fg")},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
tc.vv.AppendViews(tc.in)
|
||||
if got, want := tc.vv, tc.want; !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("(%v).ToVectorisedView failed got: %+v, want: %+v", tc.in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMemSize(t *testing.T) {
|
||||
const perViewCap = 128
|
||||
views := make([]buffer.View, 2, 32)
|
||||
|
||||
@@ -985,7 +985,11 @@ func ICMPv6(checkers ...TransportChecker) NetworkChecker {
|
||||
}
|
||||
|
||||
icmp := header.ICMPv6(last.Payload())
|
||||
if got, want := icmp.Checksum(), header.ICMPv6Checksum(icmp, last.SourceAddress(), last.DestinationAddress(), buffer.VectorisedView{}); got != want {
|
||||
if got, want := icmp.Checksum(), header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
|
||||
Header: icmp,
|
||||
Src: last.SourceAddress(),
|
||||
Dst: last.DestinationAddress(),
|
||||
}); got != want {
|
||||
t.Fatalf("Bad ICMPv6 checksum; got %d, want %d", got, want)
|
||||
}
|
||||
|
||||
|
||||
@@ -186,42 +186,29 @@ func Checksum(buf []byte, initial uint16) uint16 {
|
||||
//
|
||||
// The initial checksum must have been computed on an even number of bytes.
|
||||
func ChecksumVV(vv buffer.VectorisedView, initial uint16) uint16 {
|
||||
return ChecksumVVWithOffset(vv, initial, 0, vv.Size())
|
||||
var c Checksumer
|
||||
for _, v := range vv.Views() {
|
||||
c.Add([]byte(v))
|
||||
}
|
||||
return ChecksumCombine(initial, c.Checksum())
|
||||
}
|
||||
|
||||
// ChecksumVVWithOffset calculates the checksum (as defined in RFC 1071) of the
|
||||
// bytes in the given VectorizedView.
|
||||
//
|
||||
// The initial checksum must have been computed on an even number of bytes.
|
||||
func ChecksumVVWithOffset(vv buffer.VectorisedView, initial uint16, off int, size int) uint16 {
|
||||
odd := false
|
||||
sum := initial
|
||||
for _, v := range vv.Views() {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
// Checksumer calculates checksum defined in RFC 1071.
|
||||
type Checksumer struct {
|
||||
sum uint16
|
||||
odd bool
|
||||
}
|
||||
|
||||
if off >= len(v) {
|
||||
off -= len(v)
|
||||
continue
|
||||
}
|
||||
v = v[off:]
|
||||
|
||||
l := len(v)
|
||||
if l > size {
|
||||
l = size
|
||||
}
|
||||
v = v[:l]
|
||||
|
||||
sum, odd = unrolledCalculateChecksum(v, odd, uint32(sum))
|
||||
|
||||
size -= len(v)
|
||||
if size == 0 {
|
||||
break
|
||||
}
|
||||
off = 0
|
||||
// Add adds b to checksum.
|
||||
func (c *Checksumer) Add(b []byte) {
|
||||
if len(b) > 0 {
|
||||
c.sum, c.odd = unrolledCalculateChecksum(b, c.odd, uint32(c.sum))
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// Checksum returns the latest checksum value.
|
||||
func (c *Checksumer) Checksum() uint16 {
|
||||
return c.sum
|
||||
}
|
||||
|
||||
// ChecksumCombine combines the two uint16 to form their checksum. This is done
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package header_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
@@ -26,86 +27,72 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
)
|
||||
|
||||
func TestChecksumVVWithOffset(t *testing.T) {
|
||||
func TestChecksumer(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
vv buffer.VectorisedView
|
||||
off, size int
|
||||
initial uint16
|
||||
want uint16
|
||||
name string
|
||||
data [][]byte
|
||||
want uint16
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
vv: buffer.NewVectorisedView(0, []buffer.View{
|
||||
buffer.NewViewFromBytes([]byte{1, 9, 0, 5, 4}),
|
||||
}),
|
||||
off: 0,
|
||||
size: 0,
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "OneView",
|
||||
vv: buffer.NewVectorisedView(0, []buffer.View{
|
||||
buffer.NewViewFromBytes([]byte{1, 9, 0, 5, 4}),
|
||||
}),
|
||||
off: 0,
|
||||
size: 5,
|
||||
name: "OneOddView",
|
||||
data: [][]byte{
|
||||
[]byte{1, 9, 0, 5, 4},
|
||||
},
|
||||
want: 1294,
|
||||
},
|
||||
{
|
||||
name: "TwoViews",
|
||||
vv: buffer.NewVectorisedView(0, []buffer.View{
|
||||
buffer.NewViewFromBytes([]byte{1, 9, 0, 5, 4}),
|
||||
buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123}),
|
||||
}),
|
||||
off: 0,
|
||||
size: 11,
|
||||
name: "TwoOddViews",
|
||||
data: [][]byte{
|
||||
[]byte{1, 9, 0, 5, 4},
|
||||
[]byte{4, 3, 7, 1, 2, 123},
|
||||
},
|
||||
want: 33819,
|
||||
},
|
||||
{
|
||||
name: "TwoViewsWithOffset",
|
||||
vv: buffer.NewVectorisedView(0, []buffer.View{
|
||||
buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
|
||||
buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123}),
|
||||
}),
|
||||
off: 1,
|
||||
size: 11,
|
||||
want: 33819,
|
||||
name: "OneEvenView",
|
||||
data: [][]byte{
|
||||
[]byte{1, 9, 0, 5},
|
||||
},
|
||||
want: 270,
|
||||
},
|
||||
{
|
||||
name: "ThreeViewsWithOffset",
|
||||
vv: buffer.NewVectorisedView(0, []buffer.View{
|
||||
buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
|
||||
buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
|
||||
buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123}),
|
||||
}),
|
||||
off: 7,
|
||||
size: 11,
|
||||
want: 33819,
|
||||
name: "TwoEvenViews",
|
||||
data: [][]byte{
|
||||
buffer.NewViewFromBytes([]byte{98, 1, 9, 0}),
|
||||
buffer.NewViewFromBytes([]byte{9, 0, 5, 4}),
|
||||
},
|
||||
want: 30981,
|
||||
},
|
||||
{
|
||||
name: "ThreeViewsWithInitial",
|
||||
vv: buffer.NewVectorisedView(0, []buffer.View{
|
||||
buffer.NewViewFromBytes([]byte{77, 11, 33, 0, 55, 44}),
|
||||
buffer.NewViewFromBytes([]byte{98, 1, 9, 0, 5, 4}),
|
||||
buffer.NewViewFromBytes([]byte{4, 3, 7, 1, 2, 123, 99}),
|
||||
}),
|
||||
initial: 77,
|
||||
off: 7,
|
||||
size: 11,
|
||||
want: 33896,
|
||||
name: "ThreeViews",
|
||||
data: [][]byte{
|
||||
[]byte{77, 11, 33, 0, 55, 44},
|
||||
[]byte{98, 1, 9, 0, 5, 4},
|
||||
[]byte{4, 3, 7, 1, 2, 123, 99},
|
||||
},
|
||||
want: 34236,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got, want := header.ChecksumVVWithOffset(tc.vv, tc.initial, tc.off, tc.size), tc.want; got != want {
|
||||
t.Errorf("header.ChecksumVVWithOffset(%v) = %v, want: %v", tc, got, tc.want)
|
||||
var all bytes.Buffer
|
||||
var c header.Checksumer
|
||||
for _, b := range tc.data {
|
||||
c.Add(b)
|
||||
// Append to the buffer. We will check the checksum as a whole later.
|
||||
if _, err := all.Write(b); err != nil {
|
||||
t.Fatalf("all.Write(b) = _, %s; want _, nil", err)
|
||||
}
|
||||
}
|
||||
v := tc.vv.ToView()
|
||||
v.TrimFront(tc.off)
|
||||
v.CapLength(tc.size)
|
||||
if got, want := header.Checksum(v, tc.initial), tc.want; got != want {
|
||||
t.Errorf("header.Checksum(%v) = %v, want: %v", tc, got, tc.want)
|
||||
if got, want := c.Checksum(), tc.want; got != want {
|
||||
t.Errorf("c.Checksum() = %d, want %d", got, want)
|
||||
}
|
||||
if got, want := header.Checksum(all.Bytes(), 0 /* initial */), tc.want; got != want {
|
||||
t.Errorf("Checksum(flatten tc.data) = %d, want %d", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -228,7 +215,7 @@ func TestICMPv4Checksum(t *testing.T) {
|
||||
h.SetChecksum(want)
|
||||
|
||||
testICMPChecksum(t, h.Checksum, func() uint16 {
|
||||
return header.ICMPv4Checksum(h, vv)
|
||||
return header.ICMPv4Checksum(h, header.ChecksumVV(vv, 0))
|
||||
}, want, fmt.Sprintf("header: {% x} data {% x}", h, vv.ToView()))
|
||||
}
|
||||
|
||||
@@ -260,6 +247,12 @@ func TestICMPv6Checksum(t *testing.T) {
|
||||
h.SetChecksum(want)
|
||||
|
||||
testICMPChecksum(t, h.Checksum, func() uint16 {
|
||||
return header.ICMPv6Checksum(h, src, dst, vv)
|
||||
return header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
|
||||
Header: h,
|
||||
Src: src,
|
||||
Dst: dst,
|
||||
PayloadCsum: header.ChecksumVV(vv, 0),
|
||||
PayloadLen: vv.Size(),
|
||||
})
|
||||
}, want, fmt.Sprintf("header: {% x} data {% x}", h, vv.ToView()))
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/binary"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
)
|
||||
|
||||
// ICMPv4 represents an ICMPv4 header stored in a byte array.
|
||||
@@ -198,8 +197,8 @@ func (b ICMPv4) SetSequence(sequence uint16) {
|
||||
|
||||
// ICMPv4Checksum calculates the ICMP checksum over the provided ICMP header,
|
||||
// and payload.
|
||||
func ICMPv4Checksum(h ICMPv4, vv buffer.VectorisedView) uint16 {
|
||||
xsum := ChecksumVV(vv, 0)
|
||||
func ICMPv4Checksum(h ICMPv4, payloadCsum uint16) uint16 {
|
||||
xsum := payloadCsum
|
||||
|
||||
// h[2:4] is the checksum itself, skip it to avoid checksumming the checksum.
|
||||
xsum = Checksum(h[:2], xsum)
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/binary"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
)
|
||||
|
||||
// ICMPv6 represents an ICMPv6 header stored in a byte array.
|
||||
@@ -262,12 +261,22 @@ func (b ICMPv6) Payload() []byte {
|
||||
return b[ICMPv6PayloadOffset:]
|
||||
}
|
||||
|
||||
// ICMPv6ChecksumParams contains parameters to calculate ICMPv6 checksum.
|
||||
type ICMPv6ChecksumParams struct {
|
||||
Header ICMPv6
|
||||
Src tcpip.Address
|
||||
Dst tcpip.Address
|
||||
PayloadCsum uint16
|
||||
PayloadLen int
|
||||
}
|
||||
|
||||
// ICMPv6Checksum calculates the ICMP checksum over the provided ICMPv6 header,
|
||||
// IPv6 src/dst addresses and the payload.
|
||||
func ICMPv6Checksum(h ICMPv6, src, dst tcpip.Address, vv buffer.VectorisedView) uint16 {
|
||||
xsum := PseudoHeaderChecksum(ICMPv6ProtocolNumber, src, dst, uint16(len(h)+vv.Size()))
|
||||
func ICMPv6Checksum(params ICMPv6ChecksumParams) uint16 {
|
||||
h := params.Header
|
||||
|
||||
xsum = ChecksumVV(vv, xsum)
|
||||
xsum := PseudoHeaderChecksum(ICMPv6ProtocolNumber, params.Src, params.Dst, uint16(len(h)+params.PayloadLen))
|
||||
xsum = ChecksumCombine(xsum, params.PayloadCsum)
|
||||
|
||||
// h[2:4] is the checksum itself, skip it to avoid checksumming the checksum.
|
||||
xsum = Checksum(h[:2], xsum)
|
||||
|
||||
@@ -41,7 +41,7 @@ func ARP(pkt *stack.PacketBuffer) bool {
|
||||
//
|
||||
// Returns true if the header was successfully parsed.
|
||||
func IPv4(pkt *stack.PacketBuffer) bool {
|
||||
hdr, ok := pkt.Data.PullUp(header.IPv4MinimumSize)
|
||||
hdr, ok := pkt.Data().PullUp(header.IPv4MinimumSize)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -62,27 +62,29 @@ func IPv4(pkt *stack.PacketBuffer) bool {
|
||||
ipHdr = header.IPv4(hdr)
|
||||
|
||||
pkt.NetworkProtocolNumber = header.IPv4ProtocolNumber
|
||||
pkt.Data.CapLength(int(ipHdr.TotalLength()) - len(hdr))
|
||||
pkt.Data().CapLength(int(ipHdr.TotalLength()) - len(hdr))
|
||||
return true
|
||||
}
|
||||
|
||||
// IPv6 parses an IPv6 packet found in pkt.Data and populates pkt's network
|
||||
// header with the IPv6 header.
|
||||
func IPv6(pkt *stack.PacketBuffer) (proto tcpip.TransportProtocolNumber, fragID uint32, fragOffset uint16, fragMore bool, ok bool) {
|
||||
hdr, ok := pkt.Data.PullUp(header.IPv6MinimumSize)
|
||||
hdr, ok := pkt.Data().PullUp(header.IPv6MinimumSize)
|
||||
if !ok {
|
||||
return 0, 0, 0, false, false
|
||||
}
|
||||
ipHdr := header.IPv6(hdr)
|
||||
|
||||
// dataClone consists of:
|
||||
// Create a VV to parse the packet. We don't plan to modify anything here.
|
||||
// dataVV consists of:
|
||||
// - Any IPv6 header bytes after the first 40 (i.e. extensions).
|
||||
// - The transport header, if present.
|
||||
// - Any other payload data.
|
||||
views := [8]buffer.View{}
|
||||
dataClone := pkt.Data.Clone(views[:])
|
||||
dataClone.TrimFront(header.IPv6MinimumSize)
|
||||
it := header.MakeIPv6PayloadIterator(header.IPv6ExtensionHeaderIdentifier(ipHdr.NextHeader()), dataClone)
|
||||
dataVV := buffer.NewVectorisedView(0, views[:0])
|
||||
dataVV.AppendViews(pkt.Data().Views())
|
||||
dataVV.TrimFront(header.IPv6MinimumSize)
|
||||
it := header.MakeIPv6PayloadIterator(header.IPv6ExtensionHeaderIdentifier(ipHdr.NextHeader()), dataVV)
|
||||
|
||||
// Iterate over the IPv6 extensions to find their length.
|
||||
var nextHdr tcpip.TransportProtocolNumber
|
||||
@@ -98,7 +100,7 @@ traverseExtensions:
|
||||
// If we exhaust the extension list, the entire packet is the IPv6 header
|
||||
// and (possibly) extensions.
|
||||
if done {
|
||||
extensionsSize = dataClone.Size()
|
||||
extensionsSize = dataVV.Size()
|
||||
break
|
||||
}
|
||||
|
||||
@@ -110,12 +112,12 @@ traverseExtensions:
|
||||
fragMore = extHdr.More()
|
||||
}
|
||||
rawPayload := it.AsRawHeader(true /* consume */)
|
||||
extensionsSize = dataClone.Size() - rawPayload.Buf.Size()
|
||||
extensionsSize = dataVV.Size() - rawPayload.Buf.Size()
|
||||
break traverseExtensions
|
||||
|
||||
case header.IPv6RawPayloadHeader:
|
||||
// We've found the payload after any extensions.
|
||||
extensionsSize = dataClone.Size() - extHdr.Buf.Size()
|
||||
extensionsSize = dataVV.Size() - extHdr.Buf.Size()
|
||||
nextHdr = tcpip.TransportProtocolNumber(extHdr.Identifier)
|
||||
break traverseExtensions
|
||||
|
||||
@@ -127,10 +129,10 @@ traverseExtensions:
|
||||
// Put the IPv6 header with extensions in pkt.NetworkHeader().
|
||||
hdr, ok = pkt.NetworkHeader().Consume(header.IPv6MinimumSize + extensionsSize)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("pkt.Data should have at least %d bytes, but only has %d.", header.IPv6MinimumSize+extensionsSize, pkt.Data.Size()))
|
||||
panic(fmt.Sprintf("pkt.Data should have at least %d bytes, but only has %d.", header.IPv6MinimumSize+extensionsSize, pkt.Data().Size()))
|
||||
}
|
||||
ipHdr = header.IPv6(hdr)
|
||||
pkt.Data.CapLength(int(ipHdr.PayloadLength()))
|
||||
pkt.Data().CapLength(int(ipHdr.PayloadLength()))
|
||||
pkt.NetworkProtocolNumber = header.IPv6ProtocolNumber
|
||||
|
||||
return nextHdr, fragID, fragOffset, fragMore, true
|
||||
@@ -153,13 +155,13 @@ func UDP(pkt *stack.PacketBuffer) bool {
|
||||
func TCP(pkt *stack.PacketBuffer) bool {
|
||||
// TCP header is variable length, peek at it first.
|
||||
hdrLen := header.TCPMinimumSize
|
||||
hdr, ok := pkt.Data.PullUp(hdrLen)
|
||||
hdr, ok := pkt.Data().PullUp(hdrLen)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// If the header has options, pull those up as well.
|
||||
if offset := int(header.TCP(hdr).DataOffset()); offset > header.TCPMinimumSize && offset <= pkt.Data.Size() {
|
||||
if offset := int(header.TCP(hdr).DataOffset()); offset > header.TCPMinimumSize && offset <= pkt.Data().Size() {
|
||||
// TODO(gvisor.dev/issue/2404): Figure out whether to reject this kind of
|
||||
// packets.
|
||||
hdrLen = offset
|
||||
|
||||
@@ -427,7 +427,7 @@ func (e *endpoint) WritePacket(r stack.RouteInfo, gso *stack.GSO, protocol tcpip
|
||||
vnetHdr.csumStart = header.EthernetMinimumSize + gso.L3HdrLen
|
||||
vnetHdr.csumOffset = gso.CsumOffset
|
||||
}
|
||||
if gso.Type != stack.GSONone && uint16(pkt.Data.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
|
||||
@@ -468,7 +468,7 @@ func (e *endpoint) sendBatch(batchFD int, batch []*stack.PacketBuffer) (int, tcp
|
||||
vnetHdr.csumStart = header.EthernetMinimumSize + pkt.GSOOptions.L3HdrLen
|
||||
vnetHdr.csumOffset = pkt.GSOOptions.CsumOffset
|
||||
}
|
||||
if pkt.GSOOptions.Type != stack.GSONone && uint16(pkt.Data.Size()) > pkt.GSOOptions.MSS {
|
||||
if pkt.GSOOptions.Type != stack.GSONone && uint16(pkt.Data().Size()) > pkt.GSOOptions.MSS {
|
||||
switch pkt.GSOOptions.Type {
|
||||
case stack.GSOTCPv4:
|
||||
vnetHdr.gsoType = _VIRTIO_NET_HDR_GSO_TCPV4
|
||||
|
||||
@@ -67,7 +67,7 @@ func checkPacketInfoEqual(t *testing.T, got, want packetInfo) {
|
||||
LinkHeader: pk.LinkHeader().View(),
|
||||
NetworkHeader: pk.NetworkHeader().View(),
|
||||
TransportHeader: pk.TransportHeader().View(),
|
||||
Data: pk.Data.ToView(),
|
||||
Data: pk.Data().AsRange().ToOwnedView(),
|
||||
}
|
||||
}),
|
||||
); diff != "" {
|
||||
@@ -616,8 +616,8 @@ func TestDispatchPacketFormat(t *testing.T) {
|
||||
if got, want := pkt.LinkHeader().View().Size(), header.EthernetMinimumSize; got != want {
|
||||
t.Errorf("pkt.LinkHeader().View().Size() = %d, want %d", got, want)
|
||||
}
|
||||
if got, want := pkt.Data.Size(), 4; got != want {
|
||||
t.Errorf("pkt.Data.Size() = %d, want %d", got, want)
|
||||
if got, want := pkt.Data().Size(), 4; got != want {
|
||||
t.Errorf("pkt.Data().Size() = %d, want %d", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ func (d *readVDispatcher) dispatch() (bool, tcpip.Error) {
|
||||
// We don't get any indication of what the packet is, so try to guess
|
||||
// if it's an IPv4 or IPv6 packet.
|
||||
// IP version information is at the first octet, so pulling up 1 byte.
|
||||
h, ok := pkt.Data.PullUp(1)
|
||||
h, ok := pkt.Data().PullUp(1)
|
||||
if !ok {
|
||||
return true, nil
|
||||
}
|
||||
@@ -270,7 +270,7 @@ func (d *recvMMsgDispatcher) dispatch() (bool, tcpip.Error) {
|
||||
// We don't get any indication of what the packet is, so try to guess
|
||||
// if it's an IPv4 or IPv6 packet.
|
||||
// IP version information is at the first octet, so pulling up 1 byte.
|
||||
h, ok := pkt.Data.PullUp(1)
|
||||
h, ok := pkt.Data().PullUp(1)
|
||||
if !ok {
|
||||
// Skip this packet.
|
||||
continue
|
||||
|
||||
@@ -80,7 +80,7 @@ func (q *queueBuffers) cleanup() {
|
||||
type packetInfo struct {
|
||||
addr tcpip.LinkAddress
|
||||
proto tcpip.NetworkProtocolNumber
|
||||
vv buffer.VectorisedView
|
||||
data buffer.View
|
||||
linkHeader buffer.View
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ func (c *testContext) DeliverNetworkPacket(remoteLinkAddr, localLinkAddr tcpip.L
|
||||
c.packets = append(c.packets, packetInfo{
|
||||
addr: remoteLinkAddr,
|
||||
proto: proto,
|
||||
vv: pkt.Data.Clone(nil),
|
||||
data: pkt.Data().AsRange().ToOwnedView(),
|
||||
})
|
||||
c.mu.Unlock()
|
||||
|
||||
@@ -676,7 +676,7 @@ func TestSimpleReceive(t *testing.T) {
|
||||
// Wait for packet to be received, then check it.
|
||||
c.waitForPackets(1, time.After(5*time.Second), "Timeout waiting for packet")
|
||||
c.mu.Lock()
|
||||
rcvd := []byte(c.packets[0].vv.ToView())
|
||||
rcvd := []byte(c.packets[0].data)
|
||||
c.packets = c.packets[:0]
|
||||
c.mu.Unlock()
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ func logPacket(prefix string, dir direction, protocol tcpip.NetworkProtocolNumbe
|
||||
switch tcpip.TransportProtocolNumber(transProto) {
|
||||
case header.ICMPv4ProtocolNumber:
|
||||
transName = "icmp"
|
||||
hdr, ok := pkt.Data.PullUp(header.ICMPv4MinimumSize)
|
||||
hdr, ok := pkt.Data().PullUp(header.ICMPv4MinimumSize)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
@@ -327,7 +327,7 @@ func logPacket(prefix string, dir direction, protocol tcpip.NetworkProtocolNumbe
|
||||
|
||||
case header.ICMPv6ProtocolNumber:
|
||||
transName = "icmp"
|
||||
hdr, ok := pkt.Data.PullUp(header.ICMPv6MinimumSize)
|
||||
hdr, ok := pkt.Data().PullUp(header.ICMPv6MinimumSize)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
@@ -387,7 +387,7 @@ func logPacket(prefix string, dir direction, protocol tcpip.NetworkProtocolNumbe
|
||||
details += fmt.Sprintf("invalid packet: tcp data offset too small %d", offset)
|
||||
break
|
||||
}
|
||||
if size := pkt.Data.Size() + len(tcp); offset > size && !moreFragments {
|
||||
if size := pkt.Data().Size() + len(tcp); offset > size && !moreFragments {
|
||||
details += fmt.Sprintf("invalid packet: tcp data offset %d larger than tcp packet length %d", offset, size)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ func (d *Device) encodePkt(info *channel.PacketInfo) (buffer.View, bool) {
|
||||
vv.AppendView(info.Pkt.NetworkHeader().View())
|
||||
vv.AppendView(info.Pkt.TransportHeader().View())
|
||||
// Append data payload.
|
||||
vv.Append(info.Pkt.Data)
|
||||
vv.Append(info.Pkt.Data().ExtractVV())
|
||||
|
||||
return vv.ToView(), true
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ func (f *Fragmentation) Process(
|
||||
return nil, 0, false, fmt.Errorf("fragment size=%d bytes is not a multiple of block size=%d on non-final fragment: %w", fragmentSize, f.blockSize, ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if l := pkt.Data.Size(); l != int(fragmentSize) {
|
||||
if l := pkt.Data().Size(); l != int(fragmentSize) {
|
||||
return nil, 0, false, fmt.Errorf("got fragment size=%d bytes not equal to the expected fragment size=%d bytes (first=%d last=%d): %w", l, fragmentSize, first, last, ErrInvalidArgs)
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ func MakePacketFragmenter(pkt *stack.PacketBuffer, fragmentPayloadLen uint32, re
|
||||
// these headers.
|
||||
var fragmentableData buffer.VectorisedView
|
||||
fragmentableData.AppendView(pkt.TransportHeader().View())
|
||||
fragmentableData.Append(pkt.Data)
|
||||
fragmentableData.Append(pkt.Data().ExtractVV())
|
||||
fragmentCount := (uint32(fragmentableData.Size()) + fragmentPayloadLen - 1) / fragmentPayloadLen
|
||||
|
||||
return PacketFragmenter{
|
||||
@@ -323,7 +323,7 @@ func (pf *PacketFragmenter) BuildNextFragment() (*stack.PacketBuffer, int, int,
|
||||
})
|
||||
|
||||
// Copy data for the fragment.
|
||||
copied := pf.data.ReadToVV(&fragPkt.Data, pf.fragmentPayloadLen)
|
||||
copied := fragPkt.Data().ReadFromVV(&pf.data, pf.fragmentPayloadLen)
|
||||
|
||||
offset := pf.fragmentOffset
|
||||
pf.fragmentOffset += copied
|
||||
|
||||
@@ -121,7 +121,7 @@ func TestFragmentationProcess(t *testing.T) {
|
||||
in.id, in.first, in.last, in.more, in.proto, done, c.out[i].done)
|
||||
}
|
||||
if c.out[i].done {
|
||||
if diff := cmp.Diff(c.out[i].vv.ToOwnedView(), resPkt.Data.ToOwnedView()); diff != "" {
|
||||
if diff := cmp.Diff(c.out[i].vv.ToOwnedView(), resPkt.Data().AsRange().ToOwnedView()); diff != "" {
|
||||
t.Errorf("got Process(%+v, %d, %d, %t, %d, %#v) result mismatch (-want, +got):\n%s",
|
||||
in.id, in.first, in.last, in.more, in.proto, in.pkt, diff)
|
||||
}
|
||||
@@ -470,9 +470,7 @@ func TestPacketFragmenter(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
pkt := testutil.MakeRandPkt(test.transportHeaderLen, reserve, []int{test.payloadSize}, proto)
|
||||
var originalPayload buffer.VectorisedView
|
||||
originalPayload.AppendView(pkt.TransportHeader().View())
|
||||
originalPayload.Append(pkt.Data)
|
||||
originalPayload := stack.PayloadSince(pkt.TransportHeader())
|
||||
var reassembledPayload buffer.VectorisedView
|
||||
pf := MakePacketFragmenter(pkt, test.fragmentPayloadLen, reserve)
|
||||
for i := 0; ; i++ {
|
||||
@@ -499,7 +497,7 @@ func TestPacketFragmenter(t *testing.T) {
|
||||
if got := fragPkt.TransportHeader().View().Size(); got != 0 {
|
||||
t.Errorf("(fragment #%d) got fragPkt.TransportHeader().View().Size() = %d, want = 0", i, got)
|
||||
}
|
||||
reassembledPayload.Append(fragPkt.Data)
|
||||
reassembledPayload.AppendViews(fragPkt.Data().Views())
|
||||
if !more {
|
||||
if i != len(test.wantFragments)-1 {
|
||||
t.Errorf("got fragment count = %d, want = %d", i, len(test.wantFragments)-1)
|
||||
@@ -507,7 +505,7 @@ func TestPacketFragmenter(t *testing.T) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if diff := cmp.Diff(reassembledPayload.ToView(), originalPayload.ToView()); diff != "" {
|
||||
if diff := cmp.Diff(reassembledPayload.ToView(), originalPayload); diff != "" {
|
||||
t.Errorf("reassembledPayload mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
@@ -625,11 +623,11 @@ func TestTimeoutHandler(t *testing.T) {
|
||||
}
|
||||
switch {
|
||||
case handler.pkt != nil && test.wantPkt == nil:
|
||||
t.Errorf("got handler.pkt = not nil (pkt.Data = %x), want = nil", handler.pkt.Data.ToView())
|
||||
t.Errorf("got handler.pkt = not nil (pkt.Data = %x), want = nil", handler.pkt.Data().AsRange().ToOwnedView())
|
||||
case handler.pkt == nil && test.wantPkt != nil:
|
||||
t.Errorf("got handler.pkt = nil, want = not nil (pkt.Data = %x)", test.wantPkt.Data.ToView())
|
||||
t.Errorf("got handler.pkt = nil, want = not nil (pkt.Data = %x)", test.wantPkt.Data().AsRange().ToOwnedView())
|
||||
case handler.pkt != nil && test.wantPkt != nil:
|
||||
if diff := cmp.Diff(test.wantPkt.Data.ToView(), handler.pkt.Data.ToView()); diff != "" {
|
||||
if diff := cmp.Diff(test.wantPkt.Data().AsRange().ToOwnedView(), handler.pkt.Data().AsRange().ToOwnedView()); diff != "" {
|
||||
t.Errorf("pkt.Data mismatch (-want, +got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,8 +167,8 @@ func (r *reassembler) process(first, last uint16, more bool, proto uint8, pkt *s
|
||||
|
||||
resPkt := r.holes[0].pkt
|
||||
for i := 1; i < len(r.holes); i++ {
|
||||
fragPkt := r.holes[i].pkt
|
||||
fragPkt.Data.ReadToVV(&resPkt.Data, fragPkt.Data.Size())
|
||||
fragData := r.holes[i].pkt.Data()
|
||||
resPkt.Data().ReadFromData(fragData, fragData.Size())
|
||||
}
|
||||
return resPkt, r.proto, true, memConsumed, nil
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ func TestReassemblerProcess(t *testing.T) {
|
||||
if a == nil || b == nil {
|
||||
return a == b
|
||||
}
|
||||
return bytes.Equal(a.Data.ToOwnedView(), b.Data.ToOwnedView())
|
||||
return bytes.Equal(a.Data().AsRange().ToOwnedView(), b.Data().AsRange().ToOwnedView())
|
||||
}
|
||||
|
||||
if isDone {
|
||||
|
||||
@@ -90,8 +90,7 @@ type testObject struct {
|
||||
// checkValues verifies that the transport protocol, data contents, src & dst
|
||||
// addresses of a packet match what's expected. If any field doesn't match, the
|
||||
// test fails.
|
||||
func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView, srcAddr, dstAddr tcpip.Address) {
|
||||
v := vv.ToView()
|
||||
func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, v buffer.View, srcAddr, dstAddr tcpip.Address) {
|
||||
if protocol != t.protocol {
|
||||
t.t.Errorf("protocol = %v, want %v", protocol, t.protocol)
|
||||
}
|
||||
@@ -120,7 +119,7 @@ func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv buff
|
||||
// parsing are expected.
|
||||
func (t *testObject) DeliverTransportPacket(protocol tcpip.TransportProtocolNumber, pkt *stack.PacketBuffer) stack.TransportPacketDisposition {
|
||||
netHdr := pkt.Network()
|
||||
t.checkValues(protocol, pkt.Data, netHdr.SourceAddress(), netHdr.DestinationAddress())
|
||||
t.checkValues(protocol, pkt.Data().AsRange().ToOwnedView(), netHdr.SourceAddress(), netHdr.DestinationAddress())
|
||||
t.dataCalls++
|
||||
return stack.TransportPacketHandled
|
||||
}
|
||||
@@ -129,7 +128,7 @@ func (t *testObject) DeliverTransportPacket(protocol tcpip.TransportProtocolNumb
|
||||
// incoming control (ICMP) packets. This is used by the test object to verify
|
||||
// that the results of the parsing are expected.
|
||||
func (t *testObject) DeliverTransportError(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, transErr stack.TransportError, pkt *stack.PacketBuffer) {
|
||||
t.checkValues(trans, pkt.Data, remote, local)
|
||||
t.checkValues(trans, pkt.Data().AsRange().ToOwnedView(), remote, local)
|
||||
if diff := cmp.Diff(
|
||||
t.transErr,
|
||||
transportError{
|
||||
@@ -198,7 +197,7 @@ func (t *testObject) WritePacket(_ *stack.Route, _ *stack.GSO, protocol tcpip.Ne
|
||||
srcAddr = h.SourceAddress()
|
||||
dstAddr = h.DestinationAddress()
|
||||
}
|
||||
t.checkValues(prot, pkt.Data, srcAddr, dstAddr)
|
||||
t.checkValues(prot, pkt.Data().AsRange().ToOwnedView(), srcAddr, dstAddr)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -371,7 +370,11 @@ func TestSourceAddressValidation(t *testing.T) {
|
||||
pkt.SetType(header.ICMPv6EchoRequest)
|
||||
pkt.SetCode(0)
|
||||
pkt.SetChecksum(0)
|
||||
pkt.SetChecksum(header.ICMPv6Checksum(pkt, src, localIPv6Addr, buffer.VectorisedView{}))
|
||||
pkt.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
|
||||
Header: pkt,
|
||||
Src: src,
|
||||
Dst: localIPv6Addr,
|
||||
}))
|
||||
ip := header.IPv6(hdr.Prepend(header.IPv6MinimumSize))
|
||||
ip.Encode(&header.IPv6Fields{
|
||||
PayloadLength: header.ICMPv6MinimumSize,
|
||||
@@ -1199,7 +1202,11 @@ func TestIPv6ReceiveControl(t *testing.T) {
|
||||
nic.testObject.transErr = c.transErr
|
||||
|
||||
// Set ICMPv6 checksum.
|
||||
icmp.SetChecksum(header.ICMPv6Checksum(icmp, outerSrcAddr, localIPv6Addr, buffer.VectorisedView{}))
|
||||
icmp.SetChecksum(header.ICMPv6Checksum(header.ICMPv6ChecksumParams{
|
||||
Header: icmp,
|
||||
Src: outerSrcAddr,
|
||||
Dst: localIPv6Addr,
|
||||
}))
|
||||
|
||||
addressableEndpoint, ok := ep.(stack.AddressableEndpoint)
|
||||
if !ok {
|
||||
|
||||
@@ -137,7 +137,7 @@ func (e *endpoint) checkLocalAddress(addr tcpip.Address) bool {
|
||||
// is used to find out which transport endpoint must be notified about the ICMP
|
||||
// packet. We only expect the payload, not the enclosing ICMP packet.
|
||||
func (e *endpoint) handleControl(errInfo stack.TransportError, pkt *stack.PacketBuffer) {
|
||||
h, ok := pkt.Data.PullUp(header.IPv4MinimumSize)
|
||||
h, ok := pkt.Data().PullUp(header.IPv4MinimumSize)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -156,7 +156,7 @@ func (e *endpoint) handleControl(errInfo stack.TransportError, pkt *stack.Packet
|
||||
}
|
||||
|
||||
hlen := int(hdr.HeaderLength())
|
||||
if pkt.Data.Size() < hlen || hdr.FragmentOffset() != 0 {
|
||||
if pkt.Data().Size() < hlen || hdr.FragmentOffset() != 0 {
|
||||
// We won't be able to handle this if it doesn't contain the
|
||||
// full IPv4 header, or if it's a fragment not at offset 0
|
||||
// (because it won't have the transport header).
|
||||
@@ -164,7 +164,7 @@ func (e *endpoint) handleControl(errInfo stack.TransportError, pkt *stack.Packet
|
||||
}
|
||||
|
||||
// Skip the ip header, then deliver the error.
|
||||
pkt.Data.TrimFront(hlen)
|
||||
pkt.Data().TrimFront(hlen)
|
||||
p := hdr.TransportProtocol()
|
||||
e.dispatcher.DeliverTransportError(srcAddr, hdr.DestinationAddress(), ProtocolNumber, p, errInfo, pkt)
|
||||
}
|
||||
@@ -174,7 +174,7 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer) {
|
||||
// TODO(gvisor.dev/issue/170): ICMP packets don't have their
|
||||
// TransportHeader fields set. See icmp/protocol.go:protocol.Parse for a
|
||||
// full explanation.
|
||||
v, ok := pkt.Data.PullUp(header.ICMPv4MinimumSize)
|
||||
v, ok := pkt.Data().PullUp(header.ICMPv4MinimumSize)
|
||||
if !ok {
|
||||
received.invalid.Increment()
|
||||
return
|
||||
@@ -182,7 +182,7 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer) {
|
||||
h := header.ICMPv4(v)
|
||||
|
||||
// Only do in-stack processing if the checksum is correct.
|
||||
if header.ChecksumVV(pkt.Data, 0 /* initial */) != 0xffff {
|
||||
if pkt.Data().AsRange().Checksum() != 0xffff {
|
||||
received.invalid.Increment()
|
||||
// It's possible that a raw socket expects to receive this regardless
|
||||
// of checksum errors. If it's an echo request we know it's safe because
|
||||
@@ -253,7 +253,7 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer) {
|
||||
// TODO(gvisor.dev/issue/4399): The copy may not be needed if there are no
|
||||
// waiting endpoints. Consider moving responsibility for doing the copy to
|
||||
// DeliverTransportPacket so that is is only done when needed.
|
||||
replyData := pkt.Data.ToOwnedView()
|
||||
replyData := pkt.Data().AsRange().ToOwnedView()
|
||||
ipHdr := header.IPv4(pkt.NetworkHeader().View())
|
||||
localAddressBroadcast := pkt.NetworkPacketInfo.LocalAddressBroadcast
|
||||
|
||||
@@ -336,7 +336,7 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer) {
|
||||
case header.ICMPv4DstUnreachable:
|
||||
received.dstUnreachable.Increment()
|
||||
|
||||
pkt.Data.TrimFront(header.ICMPv4MinimumSize)
|
||||
pkt.Data().TrimFront(header.ICMPv4MinimumSize)
|
||||
switch h.Code() {
|
||||
case header.ICMPv4HostUnreachable:
|
||||
e.handleControl(&icmpv4DestinationHostUnreachableSockError{}, pkt)
|
||||
@@ -571,7 +571,7 @@ func (p *protocol) returnError(reason icmpReason, pkt *stack.PacketBuffer) tcpip
|
||||
return nil
|
||||
}
|
||||
|
||||
payloadLen := len(origIPHdr) + transportHeader.Size() + pkt.Data.Size()
|
||||
payloadLen := len(origIPHdr) + transportHeader.Size() + pkt.Data().Size()
|
||||
if payloadLen > available {
|
||||
payloadLen = available
|
||||
}
|
||||
@@ -586,8 +586,11 @@ func (p *protocol) returnError(reason icmpReason, pkt *stack.PacketBuffer) tcpip
|
||||
newHeader := append(buffer.View(nil), origIPHdr...)
|
||||
newHeader = append(newHeader, transportHeader...)
|
||||
payload := newHeader.ToVectorisedView()
|
||||
payload.AppendView(pkt.Data.ToView())
|
||||
payload.CapLength(payloadLen)
|
||||
if dataCap := payloadLen - payload.Size(); dataCap > 0 {
|
||||
payload.AppendView(pkt.Data().AsRange().Capped(dataCap).ToOwnedView())
|
||||
} else {
|
||||
payload.CapLength(payloadLen)
|
||||
}
|
||||
|
||||
icmpPkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
|
||||
ReserveHeaderBytes: int(route.MaxHeaderLength()) + header.ICMPv4MinimumSize,
|
||||
@@ -623,7 +626,7 @@ func (p *protocol) returnError(reason icmpReason, pkt *stack.PacketBuffer) tcpip
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported ICMP type %T", reason))
|
||||
}
|
||||
icmpHdr.SetChecksum(header.ICMPv4Checksum(icmpHdr, icmpPkt.Data))
|
||||
icmpHdr.SetChecksum(header.ICMPv4Checksum(icmpHdr, icmpPkt.Data().AsRange().Checksum()))
|
||||
|
||||
if err := route.WritePacket(
|
||||
nil, /* gso */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user