better and batched tun interface

This commit is contained in:
JackDoan
2026-04-17 10:25:05 -05:00
parent 6c3972f464
commit ff48040c78
34 changed files with 1183 additions and 478 deletions
+23 -6
View File
@@ -6,7 +6,6 @@ package overlay
import (
"errors"
"fmt"
"io"
"log/slog"
"net/netip"
"os"
@@ -16,6 +15,7 @@ import (
"github.com/gaissmai/bart"
"github.com/slackhq/nebula/config"
"github.com/slackhq/nebula/overlay/tio"
"github.com/slackhq/nebula/routing"
"github.com/slackhq/nebula/util"
netroute "golang.org/x/net/route"
@@ -31,6 +31,9 @@ type tun struct {
routeTree atomic.Pointer[bart.Table[routing.Gateways]]
linkAddr *netroute.LinkAddr
l *slog.Logger
readBuf []byte
batchRet [1][]byte
}
type ifReq struct {
@@ -126,6 +129,7 @@ func newTun(c *config.C, l *slog.Logger, vpnNetworks []netip.Prefix, _ bool) (*t
vpnNetworks: vpnNetworks,
DefaultMTU: c.GetInt("tun.mtu", DefaultMTU),
l: l,
readBuf: make([]byte, defaultBatchBufSize),
}
err = t.reload(c, true)
@@ -515,9 +519,9 @@ func tunWritev(fd int, iovecs []unix.Iovec) (n int, err error)
//go:noescape
func tunReadv(fd int, iovecs []unix.Iovec) (n int, err error)
// Read pulls one IP packet off the utun device, scattering the 4 byte protocol header away from
// readOne pulls one IP packet off the utun device, scattering the 4 byte protocol header away from
// the packet so the payload lands directly in to.
func (t *tun) Read(to []byte) (int, error) {
func (t *tun) readOne(to []byte) (int, error) {
var head [4]byte
rc, err := t.f.SyscallConn()
@@ -550,7 +554,16 @@ func (t *tun) Read(to []byte) (int, error) {
return n - 4, nil
}
// Write pushes one IP packet onto the utun device.
func (t *tun) Read() ([][]byte, error) {
n, err := t.readOne(t.readBuf)
if err != nil {
return nil, err
}
t.batchRet[0] = t.readBuf[:n]
return t.batchRet[:], nil
}
// Write pushes one IP packet onto the utun device. Only valid for single threaded use.
func (t *tun) Write(from []byte) (int, error) {
if len(from) == 0 {
return 0, syscall.EIO
@@ -610,6 +623,10 @@ func (t *tun) SupportsMultiqueue() bool {
return false
}
func (t *tun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
return nil, fmt.Errorf("TODO: multiqueue not implemented for darwin")
func (t *tun) NewMultiQueueReader() error {
return fmt.Errorf("TODO: multiqueue not implemented for darwin")
}
func (t *tun) Readers() []tio.Queue {
return []tio.Queue{t}
}