netstack: Rename pkt.Data().TrimFront() to DeleteFront(), and ...

... it may now invalidate backing slice references

This is currently safe because TrimFront() in VectorisedView only shrinks the
view. This may not hold under the a different buffer implementation.
Reordering method calls order to allow this.

PiperOrigin-RevId: 371167610
This commit is contained in:
Ting-Yu Wang
2021-04-29 11:43:26 -07:00
committed by gVisor bot
parent 2e442f9081
commit a41c5fe217
5 changed files with 33 additions and 22 deletions
+10 -6
View File
@@ -163,10 +163,12 @@ func (e *endpoint) handleControl(errInfo stack.TransportError, pkt *stack.Packet
return
}
// Skip the ip header, then deliver the error.
pkt.Data().TrimFront(hlen)
// Keep needed information before trimming header.
p := hdr.TransportProtocol()
e.dispatcher.DeliverTransportError(srcAddr, hdr.DestinationAddress(), ProtocolNumber, p, errInfo, pkt)
dstAddr := hdr.DestinationAddress()
// Skip the ip header, then deliver the error.
pkt.Data().DeleteFront(hlen)
e.dispatcher.DeliverTransportError(srcAddr, dstAddr, ProtocolNumber, p, errInfo, pkt)
}
func (e *endpoint) handleICMP(pkt *stack.PacketBuffer) {
@@ -336,14 +338,16 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer) {
case header.ICMPv4DstUnreachable:
received.dstUnreachable.Increment()
pkt.Data().TrimFront(header.ICMPv4MinimumSize)
switch h.Code() {
mtu := h.MTU()
code := h.Code()
pkt.Data().DeleteFront(header.ICMPv4MinimumSize)
switch code {
case header.ICMPv4HostUnreachable:
e.handleControl(&icmpv4DestinationHostUnreachableSockError{}, pkt)
case header.ICMPv4PortUnreachable:
e.handleControl(&icmpv4DestinationPortUnreachableSockError{}, pkt)
case header.ICMPv4FragmentationNeeded:
networkMTU, err := calculateNetworkMTU(uint32(h.MTU()), header.IPv4MinimumSize)
networkMTU, err := calculateNetworkMTU(uint32(mtu), header.IPv4MinimumSize)
if err != nil {
networkMTU = 0
}
+12 -8
View File
@@ -181,10 +181,13 @@ func (e *endpoint) handleControl(transErr stack.TransportError, pkt *stack.Packe
return
}
// Keep needed information before trimming header.
p := hdr.TransportProtocol()
dstAddr := hdr.DestinationAddress()
// Skip the IP header, then handle the fragmentation header if there
// is one.
pkt.Data().TrimFront(header.IPv6MinimumSize)
p := hdr.TransportProtocol()
pkt.Data().DeleteFront(header.IPv6MinimumSize)
if p == header.IPv6FragmentHeader {
f, ok := pkt.Data().PullUp(header.IPv6FragmentHeaderSize)
if !ok {
@@ -196,14 +199,14 @@ func (e *endpoint) handleControl(transErr stack.TransportError, pkt *stack.Packe
// because they don't have the transport headers.
return
}
p = fragHdr.TransportProtocol()
// Skip fragmentation header and find out the actual protocol
// number.
pkt.Data().TrimFront(header.IPv6FragmentHeaderSize)
p = fragHdr.TransportProtocol()
pkt.Data().DeleteFront(header.IPv6FragmentHeaderSize)
}
e.dispatcher.DeliverTransportError(srcAddr, hdr.DestinationAddress(), ProtocolNumber, p, transErr, pkt)
e.dispatcher.DeliverTransportError(srcAddr, dstAddr, ProtocolNumber, p, transErr, pkt)
}
// getLinkAddrOption searches NDP options for a given link address option using
@@ -327,11 +330,11 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
received.invalid.Increment()
return
}
pkt.Data().TrimFront(header.ICMPv6PacketTooBigMinimumSize)
networkMTU, err := calculateNetworkMTU(header.ICMPv6(hdr).MTU(), header.IPv6MinimumSize)
if err != nil {
networkMTU = 0
}
pkt.Data().DeleteFront(header.ICMPv6PacketTooBigMinimumSize)
e.handleControl(&icmpv6PacketTooBigSockError{mtu: networkMTU}, pkt)
case header.ICMPv6DstUnreachable:
@@ -341,8 +344,9 @@ func (e *endpoint) handleICMP(pkt *stack.PacketBuffer, hasFragmentHeader bool, r
received.invalid.Increment()
return
}
pkt.Data().TrimFront(header.ICMPv6DstUnreachableMinimumSize)
switch header.ICMPv6(hdr).Code() {
code := header.ICMPv6(hdr).Code()
pkt.Data().DeleteFront(header.ICMPv6DstUnreachableMinimumSize)
switch code {
case header.ICMPv6NetworkUnreachable:
e.handleControl(&icmpv6DestinationNetworkUnreachableSockError{}, pkt)
case header.ICMPv6PortUnreachable:
+4 -3
View File
@@ -364,9 +364,10 @@ func (d PacketData) PullUp(size int) (buffer.View, bool) {
return d.pk.data.PullUp(size)
}
// TrimFront removes count from the beginning of d. It panics if count >
// d.Size().
func (d PacketData) TrimFront(count int) {
// DeleteFront removes count from the beginning of d. It panics if count >
// d.Size(). All backing storage references after the front of the d are
// invalidated.
func (d PacketData) DeleteFront(count int) {
d.pk.data.TrimFront(count)
}
+3 -3
View File
@@ -397,11 +397,11 @@ func TestPacketBufferData(t *testing.T) {
}
})
// TrimFront
// DeleteFront
for _, n := range []int{1, len(tc.data)} {
t.Run(fmt.Sprintf("TrimFront%d", n), func(t *testing.T) {
t.Run(fmt.Sprintf("DeleteFront%d", n), func(t *testing.T) {
pkt := tc.makePkt(t)
pkt.Data().TrimFront(n)
pkt.Data().DeleteFront(n)
checkData(t, pkt, []byte(tc.data)[n:])
})
+4 -2
View File
@@ -138,11 +138,13 @@ func (f *fakeNetworkEndpoint) HandlePacket(pkt *stack.PacketBuffer) {
// Handle control packets.
if netHdr[protocolNumberOffset] == uint8(fakeControlProtocol) {
nb, ok := pkt.Data().PullUp(fakeNetHeaderLen)
hdr, ok := pkt.Data().PullUp(fakeNetHeaderLen)
if !ok {
return
}
pkt.Data().TrimFront(fakeNetHeaderLen)
// DeleteFront invalidates slices. Make a copy before trimming.
nb := append([]byte(nil), hdr...)
pkt.Data().DeleteFront(fakeNetHeaderLen)
f.dispatcher.DeliverTransportError(
tcpip.Address(nb[srcAddrOffset:srcAddrOffset+1]),
tcpip.Address(nb[dstAddrOffset:dstAddrOffset+1]),