wgengine: inject packetbuffers rather than bytes (#4220)

Plumb the outbound injection path to allow passing netstack
PacketBuffers down to the tun Read, where they are decref'd to enable
buffer re-use. This removes one packet alloc & copy, and reduces GC
pressure by pooling outbound injected packets.

Fixes #2741
Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker
2022-03-21 14:58:43 -07:00
committed by GitHub
parent a09c30aac2
commit 445c04c938
2 changed files with 52 additions and 23 deletions

View File

@@ -382,17 +382,14 @@ func (ns *Impl) injectOutbound() {
ns.logf("[v2] ReadContext-for-write = ok=false")
continue
}
hdrNetwork := pkt.NetworkHeader()
hdrTransport := pkt.TransportHeader()
full := make([]byte, 0, pkt.Size())
full = append(full, hdrNetwork.View()...)
full = append(full, hdrTransport.View()...)
full = append(full, pkt.Data().AsRange().AsView()...)
if debugPackets {
ns.logf("[v2] packet Write out: % x", full)
ns.logf("[v2] packet Write out: % x", stack.PayloadSince(pkt.NetworkHeader()))
}
if err := ns.tundev.InjectOutbound(full); err != nil {
// pkt has a non-zero refcount, InjectOutboundPacketBuffer takes
// ownership of one count and will decrement on completion.
if err := ns.tundev.InjectOutboundPacketBuffer(pkt); err != nil {
log.Printf("netstack inject outbound: %v", err)
return
}