mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Use PacketBuffers, rather than VectorisedViews, in netstack.
PacketBuffers are analogous to Linux's sk_buff. They hold all information about a packet, headers, and payload. This is important for: * iptables to access various headers of packets * Preventing the clutter of passing different net and link headers along with VectorisedViews to packet handling functions. This change only affects the incoming packet path, and a future change will change the outgoing path. Benchmark Regular PacketBufferPtr PacketBufferConcrete -------------------------------------------------------------------------------- BM_Recvmsg 400.715MB/s 373.676MB/s 396.276MB/s BM_Sendmsg 361.832MB/s 333.003MB/s 335.571MB/s BM_Recvfrom 453.336MB/s 393.321MB/s 381.650MB/s BM_Sendto 378.052MB/s 372.134MB/s 341.342MB/s BM_SendmsgTCP/0/1k 353.711MB/s 316.216MB/s 322.747MB/s BM_SendmsgTCP/0/2k 600.681MB/s 588.776MB/s 565.050MB/s BM_SendmsgTCP/0/4k 995.301MB/s 888.808MB/s 941.888MB/s BM_SendmsgTCP/0/8k 1.517GB/s 1.274GB/s 1.345GB/s BM_SendmsgTCP/0/16k 1.872GB/s 1.586GB/s 1.698GB/s BM_SendmsgTCP/0/32k 1.017GB/s 1.020GB/s 1.133GB/s BM_SendmsgTCP/0/64k 475.626MB/s 584.587MB/s 627.027MB/s BM_SendmsgTCP/0/128k 416.371MB/s 503.434MB/s 409.850MB/s BM_SendmsgTCP/0/256k 323.449MB/s 449.599MB/s 388.852MB/s BM_SendmsgTCP/0/512k 243.992MB/s 267.676MB/s 314.474MB/s BM_SendmsgTCP/0/1M 95.138MB/s 95.874MB/s 95.417MB/s BM_SendmsgTCP/0/2M 96.261MB/s 94.977MB/s 96.005MB/s BM_SendmsgTCP/0/4M 96.512MB/s 95.978MB/s 95.370MB/s BM_SendmsgTCP/0/8M 95.603MB/s 95.541MB/s 94.935MB/s BM_SendmsgTCP/0/16M 94.598MB/s 94.696MB/s 94.521MB/s BM_SendmsgTCP/0/32M 94.006MB/s 94.671MB/s 94.768MB/s BM_SendmsgTCP/0/64M 94.133MB/s 94.333MB/s 94.746MB/s BM_SendmsgTCP/0/128M 93.615MB/s 93.497MB/s 93.573MB/s BM_SendmsgTCP/0/256M 93.241MB/s 95.100MB/s 93.272MB/s BM_SendmsgTCP/1/1k 303.644MB/s 316.074MB/s 308.430MB/s BM_SendmsgTCP/1/2k 537.093MB/s 584.962MB/s 529.020MB/s BM_SendmsgTCP/1/4k 882.362MB/s 939.087MB/s 892.285MB/s BM_SendmsgTCP/1/8k 1.272GB/s 1.394GB/s 1.296GB/s BM_SendmsgTCP/1/16k 1.802GB/s 2.019GB/s 1.830GB/s BM_SendmsgTCP/1/32k 2.084GB/s 2.173GB/s 2.156GB/s BM_SendmsgTCP/1/64k 2.515GB/s 2.463GB/s 2.473GB/s BM_SendmsgTCP/1/128k 2.811GB/s 3.004GB/s 2.946GB/s BM_SendmsgTCP/1/256k 3.008GB/s 3.159GB/s 3.171GB/s BM_SendmsgTCP/1/512k 2.980GB/s 3.150GB/s 3.126GB/s BM_SendmsgTCP/1/1M 2.165GB/s 2.233GB/s 2.163GB/s BM_SendmsgTCP/1/2M 2.370GB/s 2.219GB/s 2.453GB/s BM_SendmsgTCP/1/4M 2.005GB/s 2.091GB/s 2.214GB/s BM_SendmsgTCP/1/8M 2.111GB/s 2.013GB/s 2.109GB/s BM_SendmsgTCP/1/16M 1.902GB/s 1.868GB/s 1.897GB/s BM_SendmsgTCP/1/32M 1.655GB/s 1.665GB/s 1.635GB/s BM_SendmsgTCP/1/64M 1.575GB/s 1.547GB/s 1.575GB/s BM_SendmsgTCP/1/128M 1.524GB/s 1.584GB/s 1.580GB/s BM_SendmsgTCP/1/256M 1.579GB/s 1.607GB/s 1.593GB/s PiperOrigin-RevId: 278940079
This commit is contained in:
committed by
gVisor bot
parent
d0d89ceedd
commit
e1b21f3c8c
@@ -6,6 +6,8 @@ package(licenses = ["notice"])
|
||||
go_library(
|
||||
name = "tcpip",
|
||||
srcs = [
|
||||
"packet_buffer.go",
|
||||
"packet_buffer_state.go",
|
||||
"tcpip.go",
|
||||
"time_unsafe.go",
|
||||
],
|
||||
|
||||
@@ -65,14 +65,14 @@ func (e *Endpoint) Drain() int {
|
||||
}
|
||||
}
|
||||
|
||||
// Inject injects an inbound packet.
|
||||
func (e *Endpoint) Inject(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) {
|
||||
e.InjectLinkAddr(protocol, "", vv)
|
||||
// InjectInbound injects an inbound packet.
|
||||
func (e *Endpoint) InjectInbound(protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
e.InjectLinkAddr(protocol, "", pkt)
|
||||
}
|
||||
|
||||
// InjectLinkAddr injects an inbound packet with a remote link address.
|
||||
func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remote tcpip.LinkAddress, vv buffer.VectorisedView) {
|
||||
e.dispatcher.DeliverNetworkPacket(e, remote, "" /* local */, protocol, vv.Clone(nil), nil /* linkHeader */)
|
||||
func (e *Endpoint) InjectLinkAddr(protocol tcpip.NetworkProtocolNumber, remote tcpip.LinkAddress, pkt tcpip.PacketBuffer) {
|
||||
e.dispatcher.DeliverNetworkPacket(e, remote, "" /* local */, protocol, pkt)
|
||||
}
|
||||
|
||||
// Attach saves the stack network-layer dispatcher for use later when packets
|
||||
|
||||
@@ -598,8 +598,8 @@ func (e *InjectableEndpoint) Attach(dispatcher stack.NetworkDispatcher) {
|
||||
}
|
||||
|
||||
// InjectInbound injects an inbound packet.
|
||||
func (e *InjectableEndpoint) InjectInbound(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) {
|
||||
e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, protocol, vv, nil /* linkHeader */)
|
||||
func (e *InjectableEndpoint) InjectInbound(protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, protocol, pkt)
|
||||
}
|
||||
|
||||
// NewInjectable creates a new fd-based InjectableEndpoint.
|
||||
|
||||
@@ -43,10 +43,9 @@ const (
|
||||
)
|
||||
|
||||
type packetInfo struct {
|
||||
raddr tcpip.LinkAddress
|
||||
proto tcpip.NetworkProtocolNumber
|
||||
contents buffer.VectorisedView
|
||||
linkHeader buffer.View
|
||||
raddr tcpip.LinkAddress
|
||||
proto tcpip.NetworkProtocolNumber
|
||||
contents tcpip.PacketBuffer
|
||||
}
|
||||
|
||||
type context struct {
|
||||
@@ -93,8 +92,8 @@ func (c *context) cleanup() {
|
||||
syscall.Close(c.fds[1])
|
||||
}
|
||||
|
||||
func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote tcpip.LinkAddress, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView, linkHeader buffer.View) {
|
||||
c.ch <- packetInfo{remote, protocol, vv, linkHeader}
|
||||
func (c *context) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote tcpip.LinkAddress, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
c.ch <- packetInfo{remote, protocol, pkt}
|
||||
}
|
||||
|
||||
func TestNoEthernetProperties(t *testing.T) {
|
||||
@@ -317,19 +316,21 @@ func TestDeliverPacket(t *testing.T) {
|
||||
select {
|
||||
case pi := <-c.ch:
|
||||
want := packetInfo{
|
||||
raddr: raddr,
|
||||
proto: proto,
|
||||
contents: buffer.View(b).ToVectorisedView(),
|
||||
linkHeader: buffer.View(hdr),
|
||||
raddr: raddr,
|
||||
proto: proto,
|
||||
contents: tcpip.PacketBuffer{
|
||||
Data: buffer.View(b).ToVectorisedView(),
|
||||
LinkHeader: buffer.View(hdr),
|
||||
},
|
||||
}
|
||||
if !eth {
|
||||
want.proto = header.IPv4ProtocolNumber
|
||||
want.raddr = ""
|
||||
}
|
||||
// want.contents will be a single view,
|
||||
// so make pi do the same for the
|
||||
// want.contents.Data will be a single
|
||||
// view, so make pi do the same for the
|
||||
// DeepEqual check.
|
||||
pi.contents = pi.contents.ToView().ToVectorisedView()
|
||||
pi.contents.Data = pi.contents.Data.ToView().ToVectorisedView()
|
||||
if !reflect.DeepEqual(want, pi) {
|
||||
t.Fatalf("Unexpected received packet: %+v, want %+v", pi, want)
|
||||
}
|
||||
|
||||
@@ -190,6 +190,9 @@ func (d *packetMMapDispatcher) dispatch() (bool, *tcpip.Error) {
|
||||
}
|
||||
|
||||
pkt = pkt[d.e.hdrSize:]
|
||||
d.e.dispatcher.DeliverNetworkPacket(d.e, remote, local, p, buffer.NewVectorisedView(len(pkt), []buffer.View{buffer.View(pkt)}), buffer.View(eth))
|
||||
d.e.dispatcher.DeliverNetworkPacket(d.e, remote, local, p, tcpip.PacketBuffer{
|
||||
Data: buffer.View(pkt).ToVectorisedView(),
|
||||
LinkHeader: buffer.View(eth),
|
||||
})
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -139,10 +139,13 @@ func (d *readVDispatcher) dispatch() (bool, *tcpip.Error) {
|
||||
}
|
||||
|
||||
used := d.capViews(n, BufConfig)
|
||||
vv := buffer.NewVectorisedView(n, append([]buffer.View(nil), d.views[:used]...))
|
||||
vv.TrimFront(d.e.hdrSize)
|
||||
pkt := tcpip.PacketBuffer{
|
||||
Data: buffer.NewVectorisedView(n, append([]buffer.View(nil), d.views[:used]...)),
|
||||
LinkHeader: buffer.View(eth),
|
||||
}
|
||||
pkt.Data.TrimFront(d.e.hdrSize)
|
||||
|
||||
d.e.dispatcher.DeliverNetworkPacket(d.e, remote, local, p, vv, buffer.View(eth))
|
||||
d.e.dispatcher.DeliverNetworkPacket(d.e, remote, local, p, pkt)
|
||||
|
||||
// Prepare e.views for another packet: release used views.
|
||||
for i := 0; i < used; i++ {
|
||||
@@ -293,9 +296,12 @@ func (d *recvMMsgDispatcher) dispatch() (bool, *tcpip.Error) {
|
||||
}
|
||||
|
||||
used := d.capViews(k, int(n), BufConfig)
|
||||
vv := buffer.NewVectorisedView(int(n), append([]buffer.View(nil), d.views[k][:used]...))
|
||||
vv.TrimFront(d.e.hdrSize)
|
||||
d.e.dispatcher.DeliverNetworkPacket(d.e, remote, local, p, vv, buffer.View(eth))
|
||||
pkt := tcpip.PacketBuffer{
|
||||
Data: buffer.NewVectorisedView(int(n), append([]buffer.View(nil), d.views[k][:used]...)),
|
||||
LinkHeader: buffer.View(eth),
|
||||
}
|
||||
pkt.Data.TrimFront(d.e.hdrSize)
|
||||
d.e.dispatcher.DeliverNetworkPacket(d.e, remote, local, p, pkt)
|
||||
|
||||
// Prepare e.views for another packet: release used views.
|
||||
for i := 0; i < used; i++ {
|
||||
|
||||
@@ -80,12 +80,13 @@ func (e *endpoint) WritePacket(_ *stack.Route, _ *stack.GSO, hdr buffer.Prependa
|
||||
views := make([]buffer.View, 1, 1+len(payload.Views()))
|
||||
views[0] = hdr.View()
|
||||
views = append(views, payload.Views()...)
|
||||
vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views)
|
||||
|
||||
// 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, vv, nil /* linkHeader */)
|
||||
e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, protocol, tcpip.PacketBuffer{
|
||||
Data: buffer.NewVectorisedView(len(views[0])+payload.Size(), views),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -105,7 +106,10 @@ func (e *endpoint) WriteRawPacket(packet buffer.VectorisedView) *tcpip.Error {
|
||||
// There should be an ethernet header at the beginning of packet.
|
||||
linkHeader := header.Ethernet(packet.First()[:header.EthernetMinimumSize])
|
||||
packet.TrimFront(len(linkHeader))
|
||||
e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, linkHeader.Type(), packet, buffer.View(linkHeader))
|
||||
e.dispatcher.DeliverNetworkPacket(e, "" /* remote */, "" /* local */, linkHeader.Type(), tcpip.PacketBuffer{
|
||||
Data: packet,
|
||||
LinkHeader: buffer.View(linkHeader),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ func (m *InjectableEndpoint) IsAttached() bool {
|
||||
}
|
||||
|
||||
// InjectInbound implements stack.InjectableLinkEndpoint.
|
||||
func (m *InjectableEndpoint) InjectInbound(protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) {
|
||||
m.dispatcher.DeliverNetworkPacket(m, "" /* remote */, "" /* local */, protocol, vv, nil /* linkHeader */)
|
||||
func (m *InjectableEndpoint) InjectInbound(protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
m.dispatcher.DeliverNetworkPacket(m, "" /* remote */, "" /* local */, protocol, pkt)
|
||||
}
|
||||
|
||||
// WritePackets writes outbound packets to the appropriate
|
||||
|
||||
@@ -273,8 +273,11 @@ func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) {
|
||||
}
|
||||
|
||||
// Send packet up the stack.
|
||||
eth := header.Ethernet(b)
|
||||
d.DeliverNetworkPacket(e, eth.SourceAddress(), eth.DestinationAddress(), eth.Type(), buffer.View(b[header.EthernetMinimumSize:]).ToVectorisedView(), buffer.View(eth))
|
||||
eth := header.Ethernet(b[:header.EthernetMinimumSize])
|
||||
d.DeliverNetworkPacket(e, eth.SourceAddress(), eth.DestinationAddress(), eth.Type(), tcpip.PacketBuffer{
|
||||
Data: buffer.View(b[header.EthernetMinimumSize:]).ToVectorisedView(),
|
||||
LinkHeader: buffer.View(eth),
|
||||
})
|
||||
}
|
||||
|
||||
// Clean state.
|
||||
|
||||
@@ -131,13 +131,12 @@ func newTestContext(t *testing.T, mtu, bufferSize uint32, addr tcpip.LinkAddress
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *testContext) DeliverNetworkPacket(_ stack.LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, proto tcpip.NetworkProtocolNumber, vv buffer.VectorisedView, linkHeader buffer.View) {
|
||||
func (c *testContext) DeliverNetworkPacket(_ stack.LinkEndpoint, remoteLinkAddr, localLinkAddr tcpip.LinkAddress, proto tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
c.mu.Lock()
|
||||
c.packets = append(c.packets, packetInfo{
|
||||
addr: remoteLinkAddr,
|
||||
proto: proto,
|
||||
vv: vv.Clone(nil),
|
||||
linkHeader: linkHeader,
|
||||
addr: remoteLinkAddr,
|
||||
proto: proto,
|
||||
vv: pkt.Data.Clone(nil),
|
||||
})
|
||||
c.mu.Unlock()
|
||||
|
||||
|
||||
@@ -116,19 +116,19 @@ func NewWithFile(lower stack.LinkEndpoint, file *os.File, snapLen uint32) (stack
|
||||
// DeliverNetworkPacket implements the stack.NetworkDispatcher interface. It is
|
||||
// called by the link-layer endpoint being wrapped when a packet arrives, and
|
||||
// logs the packet before forwarding to the actual dispatcher.
|
||||
func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView, linkHeader buffer.View) {
|
||||
func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
if atomic.LoadUint32(&LogPackets) == 1 && e.file == nil {
|
||||
logPacket("recv", protocol, vv.First(), nil)
|
||||
logPacket("recv", protocol, pkt.Data.First(), nil)
|
||||
}
|
||||
if e.file != nil && atomic.LoadUint32(&LogPacketsToFile) == 1 {
|
||||
vs := vv.Views()
|
||||
length := vv.Size()
|
||||
vs := pkt.Data.Views()
|
||||
length := 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(vv.Size()))); err != nil {
|
||||
if err := binary.Write(buf, binary.BigEndian, newPCAPPacketHeader(uint32(length), uint32(pkt.Data.Size()))); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range vs {
|
||||
@@ -147,7 +147,7 @@ func (e *endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
e.dispatcher.DeliverNetworkPacket(e, remote, local, protocol, vv, linkHeader)
|
||||
e.dispatcher.DeliverNetworkPacket(e, remote, local, protocol, pkt)
|
||||
}
|
||||
|
||||
// Attach implements the stack.LinkEndpoint interface. It saves the dispatcher
|
||||
|
||||
@@ -50,12 +50,12 @@ func New(lower stack.LinkEndpoint) *Endpoint {
|
||||
// It is called by the link-layer endpoint being wrapped when a packet arrives,
|
||||
// and only forwards to the actual dispatcher if Wait or WaitDispatch haven't
|
||||
// been called.
|
||||
func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView, linkHeader buffer.View) {
|
||||
func (e *Endpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
if !e.dispatchGate.Enter() {
|
||||
return
|
||||
}
|
||||
|
||||
e.dispatcher.DeliverNetworkPacket(e, remote, local, protocol, vv, linkHeader)
|
||||
e.dispatcher.DeliverNetworkPacket(e, remote, local, protocol, pkt)
|
||||
e.dispatchGate.Leave()
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ type countedEndpoint struct {
|
||||
dispatcher stack.NetworkDispatcher
|
||||
}
|
||||
|
||||
func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView, linkHeader buffer.View) {
|
||||
func (e *countedEndpoint) DeliverNetworkPacket(linkEP stack.LinkEndpoint, remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
e.dispatchCount++
|
||||
}
|
||||
|
||||
@@ -120,21 +120,21 @@ func TestWaitDispatch(t *testing.T) {
|
||||
}
|
||||
|
||||
// Dispatch and check that it goes through.
|
||||
ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, buffer.VectorisedView{}, buffer.View{})
|
||||
ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, tcpip.PacketBuffer{})
|
||||
if want := 1; ep.dispatchCount != want {
|
||||
t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want)
|
||||
}
|
||||
|
||||
// Wait on writes, then try to dispatch. It must go through.
|
||||
wep.WaitWrite()
|
||||
ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, buffer.VectorisedView{}, buffer.View{})
|
||||
ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, tcpip.PacketBuffer{})
|
||||
if want := 2; ep.dispatchCount != want {
|
||||
t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want)
|
||||
}
|
||||
|
||||
// Wait on dispatches, then try to dispatch. It must not go through.
|
||||
wep.WaitDispatch()
|
||||
ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, buffer.VectorisedView{}, buffer.View{})
|
||||
ep.dispatcher.DeliverNetworkPacket(ep, "", "", 0, tcpip.PacketBuffer{})
|
||||
if want := 2; ep.dispatchCount != want {
|
||||
t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want)
|
||||
}
|
||||
|
||||
@@ -92,8 +92,8 @@ func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, payload buffer.Vect
|
||||
return tcpip.ErrNotSupported
|
||||
}
|
||||
|
||||
func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) {
|
||||
v := vv.First()
|
||||
func (e *endpoint) HandlePacket(r *stack.Route, pkt tcpip.PacketBuffer) {
|
||||
v := pkt.Data.First()
|
||||
h := header.ARP(v)
|
||||
if !h.IsValid() {
|
||||
return
|
||||
|
||||
@@ -102,7 +102,9 @@ func TestDirectRequest(t *testing.T) {
|
||||
|
||||
inject := func(addr tcpip.Address) {
|
||||
copy(h.ProtocolAddressTarget(), addr)
|
||||
c.linkEP.Inject(arp.ProtocolNumber, v.ToVectorisedView())
|
||||
c.linkEP.InjectInbound(arp.ProtocolNumber, tcpip.PacketBuffer{
|
||||
Data: v.ToVectorisedView(),
|
||||
})
|
||||
}
|
||||
|
||||
for i, address := range []tcpip.Address{stackAddr1, stackAddr2} {
|
||||
|
||||
@@ -96,16 +96,16 @@ func (t *testObject) checkValues(protocol tcpip.TransportProtocolNumber, vv buff
|
||||
// DeliverTransportPacket is called by network endpoints after parsing incoming
|
||||
// packets. This is used by the test object to verify that the results of the
|
||||
// parsing are expected.
|
||||
func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, netHeader buffer.View, vv buffer.VectorisedView) {
|
||||
t.checkValues(protocol, vv, r.RemoteAddress, r.LocalAddress)
|
||||
func (t *testObject) DeliverTransportPacket(r *stack.Route, protocol tcpip.TransportProtocolNumber, pkt tcpip.PacketBuffer) {
|
||||
t.checkValues(protocol, pkt.Data, r.RemoteAddress, r.LocalAddress)
|
||||
t.dataCalls++
|
||||
}
|
||||
|
||||
// DeliverTransportControlPacket is called by network endpoints after parsing
|
||||
// incoming control (ICMP) packets. This is used by the test object to verify
|
||||
// that the results of the parsing are expected.
|
||||
func (t *testObject) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ stack.ControlType, extra uint32, vv buffer.VectorisedView) {
|
||||
t.checkValues(trans, vv, remote, local)
|
||||
func (t *testObject) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ stack.ControlType, extra uint32, pkt tcpip.PacketBuffer) {
|
||||
t.checkValues(trans, pkt.Data, remote, local)
|
||||
if typ != t.typ {
|
||||
t.t.Errorf("typ = %v, want %v", typ, t.typ)
|
||||
}
|
||||
@@ -279,7 +279,9 @@ func TestIPv4Receive(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("could not find route: %v", err)
|
||||
}
|
||||
ep.HandlePacket(&r, view.ToVectorisedView())
|
||||
ep.HandlePacket(&r, tcpip.PacketBuffer{
|
||||
Data: view.ToVectorisedView(),
|
||||
})
|
||||
if o.dataCalls != 1 {
|
||||
t.Fatalf("Bad number of data calls: got %x, want 1", o.dataCalls)
|
||||
}
|
||||
@@ -367,7 +369,9 @@ func TestIPv4ReceiveControl(t *testing.T) {
|
||||
o.extra = c.expectedExtra
|
||||
|
||||
vv := view[:len(view)-c.trunc].ToVectorisedView()
|
||||
ep.HandlePacket(&r, vv)
|
||||
ep.HandlePacket(&r, tcpip.PacketBuffer{
|
||||
Data: vv,
|
||||
})
|
||||
if want := c.expectedCount; o.controlCalls != want {
|
||||
t.Fatalf("Bad number of control calls for %q case: got %v, want %v", c.name, o.controlCalls, want)
|
||||
}
|
||||
@@ -430,13 +434,17 @@ func TestIPv4FragmentationReceive(t *testing.T) {
|
||||
}
|
||||
|
||||
// Send first segment.
|
||||
ep.HandlePacket(&r, frag1.ToVectorisedView())
|
||||
ep.HandlePacket(&r, tcpip.PacketBuffer{
|
||||
Data: frag1.ToVectorisedView(),
|
||||
})
|
||||
if o.dataCalls != 0 {
|
||||
t.Fatalf("Bad number of data calls: got %x, want 0", o.dataCalls)
|
||||
}
|
||||
|
||||
// Send second segment.
|
||||
ep.HandlePacket(&r, frag2.ToVectorisedView())
|
||||
ep.HandlePacket(&r, tcpip.PacketBuffer{
|
||||
Data: frag2.ToVectorisedView(),
|
||||
})
|
||||
if o.dataCalls != 1 {
|
||||
t.Fatalf("Bad number of data calls: got %x, want 1", o.dataCalls)
|
||||
}
|
||||
@@ -509,7 +517,9 @@ func TestIPv6Receive(t *testing.T) {
|
||||
t.Fatalf("could not find route: %v", err)
|
||||
}
|
||||
|
||||
ep.HandlePacket(&r, view.ToVectorisedView())
|
||||
ep.HandlePacket(&r, tcpip.PacketBuffer{
|
||||
Data: view.ToVectorisedView(),
|
||||
})
|
||||
if o.dataCalls != 1 {
|
||||
t.Fatalf("Bad number of data calls: got %x, want 1", o.dataCalls)
|
||||
}
|
||||
@@ -618,12 +628,12 @@ func TestIPv6ReceiveControl(t *testing.T) {
|
||||
o.typ = c.expectedTyp
|
||||
o.extra = c.expectedExtra
|
||||
|
||||
vv := view[:len(view)-c.trunc].ToVectorisedView()
|
||||
|
||||
// Set ICMPv6 checksum.
|
||||
icmp.SetChecksum(header.ICMPv6Checksum(icmp, outerSrcAddr, localIpv6Addr, buffer.VectorisedView{}))
|
||||
|
||||
ep.HandlePacket(&r, vv)
|
||||
ep.HandlePacket(&r, tcpip.PacketBuffer{
|
||||
Data: view[:len(view)-c.trunc].ToVectorisedView(),
|
||||
})
|
||||
if want := c.expectedCount; o.controlCalls != want {
|
||||
t.Fatalf("Bad number of control calls for %q case: got %v, want %v", c.name, o.controlCalls, want)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package ipv4
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/buffer"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
@@ -24,8 +25,8 @@ import (
|
||||
// the original packet that caused the ICMP one to be sent. This information is
|
||||
// used to find out which transport endpoint must be notified about the ICMP
|
||||
// packet.
|
||||
func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.VectorisedView) {
|
||||
h := header.IPv4(vv.First())
|
||||
func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, pkt tcpip.PacketBuffer) {
|
||||
h := header.IPv4(pkt.Data.First())
|
||||
|
||||
// We don't use IsValid() here because ICMP only requires that the IP
|
||||
// header plus 8 bytes of the transport header be included. So it's
|
||||
@@ -39,7 +40,7 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.
|
||||
}
|
||||
|
||||
hlen := int(h.HeaderLength())
|
||||
if vv.Size() < hlen || h.FragmentOffset() != 0 {
|
||||
if pkt.Data.Size() < hlen || h.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).
|
||||
@@ -47,15 +48,15 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.
|
||||
}
|
||||
|
||||
// Skip the ip header, then deliver control message.
|
||||
vv.TrimFront(hlen)
|
||||
pkt.Data.TrimFront(hlen)
|
||||
p := h.TransportProtocol()
|
||||
e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv)
|
||||
e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, pkt)
|
||||
}
|
||||
|
||||
func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.VectorisedView) {
|
||||
func (e *endpoint) handleICMP(r *stack.Route, pkt tcpip.PacketBuffer) {
|
||||
stats := r.Stats()
|
||||
received := stats.ICMP.V4PacketsReceived
|
||||
v := vv.First()
|
||||
v := pkt.Data.First()
|
||||
if len(v) < header.ICMPv4MinimumSize {
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
@@ -73,20 +74,23 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
// checksum. We'll have to reset this before we hand the packet
|
||||
// off.
|
||||
h.SetChecksum(0)
|
||||
gotChecksum := ^header.ChecksumVV(vv, 0 /* initial */)
|
||||
gotChecksum := ^header.ChecksumVV(pkt.Data, 0 /* initial */)
|
||||
if gotChecksum != wantChecksum {
|
||||
// It's possible that a raw socket expects to receive this.
|
||||
h.SetChecksum(wantChecksum)
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, netHeader, vv)
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, pkt)
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
}
|
||||
|
||||
// It's possible that a raw socket expects to receive this.
|
||||
h.SetChecksum(wantChecksum)
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, netHeader, vv)
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, tcpip.PacketBuffer{
|
||||
Data: pkt.Data.Clone(nil),
|
||||
NetworkHeader: append(buffer.View(nil), pkt.NetworkHeader...),
|
||||
})
|
||||
|
||||
vv := vv.Clone(nil)
|
||||
vv := pkt.Data.Clone(nil)
|
||||
vv.TrimFront(header.ICMPv4MinimumSize)
|
||||
hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.ICMPv4MinimumSize)
|
||||
pkt := header.ICMPv4(hdr.Prepend(header.ICMPv4MinimumSize))
|
||||
@@ -104,19 +108,19 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
case header.ICMPv4EchoReply:
|
||||
received.EchoReply.Increment()
|
||||
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, netHeader, vv)
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, pkt)
|
||||
|
||||
case header.ICMPv4DstUnreachable:
|
||||
received.DstUnreachable.Increment()
|
||||
|
||||
vv.TrimFront(header.ICMPv4MinimumSize)
|
||||
pkt.Data.TrimFront(header.ICMPv4MinimumSize)
|
||||
switch h.Code() {
|
||||
case header.ICMPv4PortUnreachable:
|
||||
e.handleControl(stack.ControlPortUnreachable, 0, vv)
|
||||
e.handleControl(stack.ControlPortUnreachable, 0, pkt)
|
||||
|
||||
case header.ICMPv4FragmentationNeeded:
|
||||
mtu := uint32(h.MTU())
|
||||
e.handleControl(stack.ControlPacketTooBig, calculateMTU(mtu), vv)
|
||||
e.handleControl(stack.ControlPacketTooBig, calculateMTU(mtu), pkt)
|
||||
}
|
||||
|
||||
case header.ICMPv4SrcQuench:
|
||||
|
||||
@@ -198,7 +198,7 @@ func (e *endpoint) writePacketFragments(r *stack.Route, gso *stack.GSO, hdr buff
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *endpoint) addIPHeader(r *stack.Route, hdr *buffer.Prependable, payloadSize int, params stack.NetworkHeaderParams) {
|
||||
func (e *endpoint) addIPHeader(r *stack.Route, hdr *buffer.Prependable, payloadSize int, params stack.NetworkHeaderParams) header.IPv4 {
|
||||
ip := header.IPv4(hdr.Prepend(header.IPv4MinimumSize))
|
||||
length := uint16(hdr.UsedLength() + payloadSize)
|
||||
id := uint32(0)
|
||||
@@ -218,19 +218,24 @@ func (e *endpoint) addIPHeader(r *stack.Route, hdr *buffer.Prependable, payloadS
|
||||
DstAddr: r.RemoteAddress,
|
||||
})
|
||||
ip.SetChecksum(^ip.CalculateChecksum())
|
||||
return ip
|
||||
}
|
||||
|
||||
// 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 {
|
||||
e.addIPHeader(r, &hdr, payload.Size(), params)
|
||||
ip := e.addIPHeader(r, &hdr, payload.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()...)
|
||||
vv := buffer.NewVectorisedView(len(views[0])+payload.Size(), views)
|
||||
loopedR := r.MakeLoopedRoute()
|
||||
e.HandlePacket(&loopedR, vv)
|
||||
|
||||
e.HandlePacket(&loopedR, tcpip.PacketBuffer{
|
||||
Data: buffer.NewVectorisedView(len(views[0])+payload.Size(), views),
|
||||
NetworkHeader: buffer.View(ip),
|
||||
})
|
||||
|
||||
loopedR.Release()
|
||||
}
|
||||
if loop&stack.PacketOut == 0 {
|
||||
@@ -301,7 +306,10 @@ func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, payload buffer.Vect
|
||||
ip.SetChecksum(^ip.CalculateChecksum())
|
||||
|
||||
if loop&stack.PacketLoop != 0 {
|
||||
e.HandlePacket(r, payload)
|
||||
e.HandlePacket(r, tcpip.PacketBuffer{
|
||||
Data: payload,
|
||||
NetworkHeader: buffer.View(ip),
|
||||
})
|
||||
}
|
||||
if loop&stack.PacketOut == 0 {
|
||||
return nil
|
||||
@@ -314,22 +322,23 @@ func (e *endpoint) WriteHeaderIncludedPacket(r *stack.Route, payload buffer.Vect
|
||||
|
||||
// HandlePacket is called by the link layer when new ipv4 packets arrive for
|
||||
// this endpoint.
|
||||
func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) {
|
||||
headerView := vv.First()
|
||||
func (e *endpoint) HandlePacket(r *stack.Route, pkt tcpip.PacketBuffer) {
|
||||
headerView := pkt.Data.First()
|
||||
h := header.IPv4(headerView)
|
||||
if !h.IsValid(vv.Size()) {
|
||||
if !h.IsValid(pkt.Data.Size()) {
|
||||
r.Stats().IP.MalformedPacketsReceived.Increment()
|
||||
return
|
||||
}
|
||||
pkt.NetworkHeader = headerView[:h.HeaderLength()]
|
||||
|
||||
hlen := int(h.HeaderLength())
|
||||
tlen := int(h.TotalLength())
|
||||
vv.TrimFront(hlen)
|
||||
vv.CapLength(tlen - hlen)
|
||||
pkt.Data.TrimFront(hlen)
|
||||
pkt.Data.CapLength(tlen - hlen)
|
||||
|
||||
more := (h.Flags() & header.IPv4FlagMoreFragments) != 0
|
||||
if more || h.FragmentOffset() != 0 {
|
||||
if vv.Size() == 0 {
|
||||
if pkt.Data.Size() == 0 {
|
||||
// Drop the packet as it's marked as a fragment but has
|
||||
// no payload.
|
||||
r.Stats().IP.MalformedPacketsReceived.Increment()
|
||||
@@ -337,10 +346,10 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) {
|
||||
return
|
||||
}
|
||||
// The packet is a fragment, let's try to reassemble it.
|
||||
last := h.FragmentOffset() + uint16(vv.Size()) - 1
|
||||
last := h.FragmentOffset() + uint16(pkt.Data.Size()) - 1
|
||||
// Drop the packet if the fragmentOffset is incorrect. i.e the
|
||||
// combination of fragmentOffset and vv.size() causes a wrap
|
||||
// around resulting in last being less than the offset.
|
||||
// combination of fragmentOffset and pkt.Data.size() causes a
|
||||
// wrap around resulting in last being less than the offset.
|
||||
if last < h.FragmentOffset() {
|
||||
r.Stats().IP.MalformedPacketsReceived.Increment()
|
||||
r.Stats().IP.MalformedFragmentsReceived.Increment()
|
||||
@@ -348,7 +357,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) {
|
||||
}
|
||||
var ready bool
|
||||
var err error
|
||||
vv, ready, err = e.fragmentation.Process(hash.IPv4FragmentHash(h), h.FragmentOffset(), last, more, vv)
|
||||
pkt.Data, ready, err = e.fragmentation.Process(hash.IPv4FragmentHash(h), h.FragmentOffset(), last, more, pkt.Data)
|
||||
if err != nil {
|
||||
r.Stats().IP.MalformedPacketsReceived.Increment()
|
||||
r.Stats().IP.MalformedFragmentsReceived.Increment()
|
||||
@@ -361,11 +370,11 @@ func (e *endpoint) HandlePacket(r *stack.Route, vv buffer.VectorisedView) {
|
||||
p := h.TransportProtocol()
|
||||
if p == header.ICMPv4ProtocolNumber {
|
||||
headerView.CapLength(hlen)
|
||||
e.handleICMP(r, headerView, vv)
|
||||
e.handleICMP(r, pkt)
|
||||
return
|
||||
}
|
||||
r.Stats().IP.PacketsDelivered.Increment()
|
||||
e.dispatcher.DeliverTransportPacket(r, p, headerView, vv)
|
||||
e.dispatcher.DeliverTransportPacket(r, p, pkt)
|
||||
}
|
||||
|
||||
// Close cleans up resources associated with the endpoint.
|
||||
|
||||
@@ -464,7 +464,9 @@ func TestInvalidFragments(t *testing.T) {
|
||||
s.CreateNIC(nicid, sniffer.New(ep))
|
||||
|
||||
for _, pkt := range tc.packets {
|
||||
ep.InjectLinkAddr(header.IPv4ProtocolNumber, remoteLinkAddr, buffer.NewVectorisedView(len(pkt), []buffer.View{pkt}))
|
||||
ep.InjectLinkAddr(header.IPv4ProtocolNumber, remoteLinkAddr, tcpip.PacketBuffer{
|
||||
Data: buffer.NewVectorisedView(len(pkt), []buffer.View{pkt}),
|
||||
})
|
||||
}
|
||||
|
||||
if got, want := s.Stats().IP.MalformedPacketsReceived.Value(), tc.wantMalformedIPPackets; got != want {
|
||||
|
||||
@@ -25,8 +25,8 @@ import (
|
||||
// the original packet that caused the ICMP one to be sent. This information is
|
||||
// used to find out which transport endpoint must be notified about the ICMP
|
||||
// packet.
|
||||
func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.VectorisedView) {
|
||||
h := header.IPv6(vv.First())
|
||||
func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, pkt tcpip.PacketBuffer) {
|
||||
h := header.IPv6(pkt.Data.First())
|
||||
|
||||
// We don't use IsValid() here because ICMP only requires that up to
|
||||
// 1280 bytes of the original packet be included. So it's likely that it
|
||||
@@ -40,10 +40,10 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.
|
||||
|
||||
// Skip the IP header, then handle the fragmentation header if there
|
||||
// is one.
|
||||
vv.TrimFront(header.IPv6MinimumSize)
|
||||
pkt.Data.TrimFront(header.IPv6MinimumSize)
|
||||
p := h.TransportProtocol()
|
||||
if p == header.IPv6FragmentHeader {
|
||||
f := header.IPv6Fragment(vv.First())
|
||||
f := header.IPv6Fragment(pkt.Data.First())
|
||||
if !f.IsValid() || f.FragmentOffset() != 0 {
|
||||
// We can't handle fragments that aren't at offset 0
|
||||
// because they don't have the transport headers.
|
||||
@@ -52,19 +52,19 @@ func (e *endpoint) handleControl(typ stack.ControlType, extra uint32, vv buffer.
|
||||
|
||||
// Skip fragmentation header and find out the actual protocol
|
||||
// number.
|
||||
vv.TrimFront(header.IPv6FragmentHeaderSize)
|
||||
pkt.Data.TrimFront(header.IPv6FragmentHeaderSize)
|
||||
p = f.TransportProtocol()
|
||||
}
|
||||
|
||||
// Deliver the control packet to the transport endpoint.
|
||||
e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, vv)
|
||||
e.dispatcher.DeliverTransportControlPacket(e.id.LocalAddress, h.DestinationAddress(), ProtocolNumber, p, typ, extra, pkt)
|
||||
}
|
||||
|
||||
func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.VectorisedView) {
|
||||
func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, pkt tcpip.PacketBuffer) {
|
||||
stats := r.Stats().ICMP
|
||||
sent := stats.V6PacketsSent
|
||||
received := stats.V6PacketsReceived
|
||||
v := vv.First()
|
||||
v := pkt.Data.First()
|
||||
if len(v) < header.ICMPv6MinimumSize {
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
@@ -77,7 +77,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
// Only the first view in vv is accounted for by h. To account for the
|
||||
// rest of vv, a shallow copy is made and the first view is removed.
|
||||
// This copy is used as extra payload during the checksum calculation.
|
||||
payload := vv
|
||||
payload := pkt.Data
|
||||
payload.RemoveFirst()
|
||||
if got, want := h.Checksum(), header.ICMPv6Checksum(h, iph.SourceAddress(), iph.DestinationAddress(), payload); got != want {
|
||||
received.Invalid.Increment()
|
||||
@@ -113,9 +113,9 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
}
|
||||
vv.TrimFront(header.ICMPv6PacketTooBigMinimumSize)
|
||||
pkt.Data.TrimFront(header.ICMPv6PacketTooBigMinimumSize)
|
||||
mtu := h.MTU()
|
||||
e.handleControl(stack.ControlPacketTooBig, calculateMTU(mtu), vv)
|
||||
e.handleControl(stack.ControlPacketTooBig, calculateMTU(mtu), pkt)
|
||||
|
||||
case header.ICMPv6DstUnreachable:
|
||||
received.DstUnreachable.Increment()
|
||||
@@ -123,10 +123,10 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
}
|
||||
vv.TrimFront(header.ICMPv6DstUnreachableMinimumSize)
|
||||
pkt.Data.TrimFront(header.ICMPv6DstUnreachableMinimumSize)
|
||||
switch h.Code() {
|
||||
case header.ICMPv6PortUnreachable:
|
||||
e.handleControl(stack.ControlPortUnreachable, 0, vv)
|
||||
e.handleControl(stack.ControlPortUnreachable, 0, pkt)
|
||||
}
|
||||
|
||||
case header.ICMPv6NeighborSolicit:
|
||||
@@ -189,9 +189,9 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
header.NDPTargetLinkLayerAddressOption(r.LocalLinkAddress[:]),
|
||||
}
|
||||
hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.ICMPv6NeighborAdvertMinimumSize + int(optsSerializer.Length()))
|
||||
pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize))
|
||||
pkt.SetType(header.ICMPv6NeighborAdvert)
|
||||
na := header.NDPNeighborAdvert(pkt.NDPPayload())
|
||||
packet := header.ICMPv6(hdr.Prepend(header.ICMPv6NeighborAdvertSize))
|
||||
packet.SetType(header.ICMPv6NeighborAdvert)
|
||||
na := header.NDPNeighborAdvert(packet.NDPPayload())
|
||||
na.SetSolicitedFlag(true)
|
||||
na.SetOverrideFlag(true)
|
||||
na.SetTargetAddress(targetAddr)
|
||||
@@ -209,7 +209,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
r := r.Clone()
|
||||
defer r.Release()
|
||||
r.LocalAddress = targetAddr
|
||||
pkt.SetChecksum(header.ICMPv6Checksum(pkt, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{}))
|
||||
packet.SetChecksum(header.ICMPv6Checksum(packet, r.LocalAddress, r.RemoteAddress, buffer.VectorisedView{}))
|
||||
|
||||
// TODO(tamird/ghanan): there exists an explicit NDP option that is
|
||||
// used to update the neighbor table with link addresses for a
|
||||
@@ -285,13 +285,13 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
}
|
||||
vv.TrimFront(header.ICMPv6EchoMinimumSize)
|
||||
pkt.Data.TrimFront(header.ICMPv6EchoMinimumSize)
|
||||
hdr := buffer.NewPrependable(int(r.MaxHeaderLength()) + header.ICMPv6EchoMinimumSize)
|
||||
pkt := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize))
|
||||
copy(pkt, h)
|
||||
pkt.SetType(header.ICMPv6EchoReply)
|
||||
pkt.SetChecksum(header.ICMPv6Checksum(pkt, r.LocalAddress, r.RemoteAddress, vv))
|
||||
if err := r.WritePacket(nil /* gso */, hdr, vv, stack.NetworkHeaderParams{Protocol: header.ICMPv6ProtocolNumber, TTL: r.DefaultTTL(), TOS: stack.DefaultTOS}); err != nil {
|
||||
packet := header.ICMPv6(hdr.Prepend(header.ICMPv6EchoMinimumSize))
|
||||
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 {
|
||||
sent.Dropped.Increment()
|
||||
return
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func (e *endpoint) handleICMP(r *stack.Route, netHeader buffer.View, vv buffer.V
|
||||
received.Invalid.Increment()
|
||||
return
|
||||
}
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, netHeader, vv)
|
||||
e.dispatcher.DeliverTransportPacket(r, header.ICMPv6ProtocolNumber, pkt)
|
||||
|
||||
case header.ICMPv6TimeExceeded:
|
||||
received.TimeExceeded.Increment()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user