zero copy even with virtioheder

This commit is contained in:
Jay Wren
2025-11-19 12:03:38 -05:00
parent 518a78c9d2
commit 8b32382cd9
5 changed files with 27 additions and 63 deletions

View File

@@ -11,6 +11,7 @@ import (
)
const DefaultMTU = 1300
const VirtioNetHdrLen = 10 // Size of virtio_net_hdr structure
// TODO: We may be able to remove routines
type DeviceFactory func(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, routines int) (Device, error)

View File

@@ -66,10 +66,6 @@ type ifreqQLEN struct {
pad [8]byte
}
const (
virtioNetHdrLen = 10 // Size of virtio_net_hdr structure
)
// wgDeviceWrapper wraps a wireguard Device to implement io.ReadWriteCloser
// This allows multiqueue readers to use the same wireguard Device batching as the main device
type wgDeviceWrapper struct {
@@ -92,27 +88,11 @@ func (w *wgDeviceWrapper) Read(b []byte) (int, error) {
}
func (w *wgDeviceWrapper) Write(b []byte) (int, error) {
// Check if buffer has the expected headroom pattern to avoid copy
var buf []byte
if cap(b) >= len(b)+virtioNetHdrLen {
buf = b[:cap(b)]
if len(buf) == len(b)+virtioNetHdrLen {
// Perfect! Buffer has headroom, no copy needed
buf = buf[:len(b)+virtioNetHdrLen]
} else {
// Unexpected capacity, safer to copy
buf = make([]byte, virtioNetHdrLen+len(b))
copy(buf[virtioNetHdrLen:], b)
}
} else {
// No headroom, need to allocate and copy
buf = make([]byte, virtioNetHdrLen+len(b))
copy(buf[virtioNetHdrLen:], b)
}
bufs := [][]byte{buf}
n, err := w.dev.Write(bufs, virtioNetHdrLen)
// Buffer b should have virtio header space (10 bytes) at the beginning
// The decrypted packet data starts at offset 10
// Pass the full buffer to WireGuard with offset=virtioNetHdrLen
bufs := [][]byte{b}
n, err := w.dev.Write(bufs, VirtioNetHdrLen)
if err != nil {
return 0, err
}
@@ -419,32 +399,11 @@ func (t *tun) BatchSize() int {
func (t *tun) Write(b []byte) (int, error) {
if t.wgDevice != nil {
// Use wireguard device which handles virtio headers internally
// Check if buffer has the expected headroom pattern:
// cap(b) should be len(b) + virtioNetHdrLen, indicating pre-allocated headroom
var buf []byte
if cap(b) >= len(b)+virtioNetHdrLen {
// Buffer likely has headroom - use unsafe to access it
// Create a slice that includes the headroom by re-slicing from capacity
buf = b[:cap(b)]
// Check if we have exactly the right amount of extra capacity
if len(buf) == len(b)+virtioNetHdrLen {
// Perfect! This buffer was allocated with headroom, no copy needed
buf = buf[:len(b)+virtioNetHdrLen]
} else {
// Unexpected capacity, safer to copy
buf = make([]byte, virtioNetHdrLen+len(b))
copy(buf[virtioNetHdrLen:], b)
}
} else {
// No headroom, need to allocate and copy
buf = make([]byte, virtioNetHdrLen+len(b))
copy(buf[virtioNetHdrLen:], b)
}
bufs := [][]byte{buf}
n, err := t.wgDevice.Write(bufs, virtioNetHdrLen)
// Buffer b should have virtio header space (10 bytes) at the beginning
// The decrypted packet data starts at offset 10
// Pass the full buffer to WireGuard with offset=virtioNetHdrLen
bufs := [][]byte{b}
n, err := t.wgDevice.Write(bufs, VirtioNetHdrLen)
if err != nil {
return 0, err
}