tun

package
v0.19.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package tun implements the tun VTEP datapath driver: it splices a kernel /dev/net/tun device (the overlay-side, L3 link the consumer routes to) to the ICX engine, moving encap'd frames over a UDP-socket underlay.

It is the kernel-device, NET_ADMIN-only driver of the vtep family. Unlike the netstack driver — which is handed both its endpoint and underlay by the consumer and only drives the pump — the tun driver OWNS both the TUN device and the UDP socket and tears them down on Close (see vtep.Datapath). This is the consumer-locality seam for a normal kernel-socket process (Envoy on the backplane): the overlay consumer reaches overlay backends by kernel route, so the VTEP must present a kernel device it can route to.

The engine speaks full Ethernet+IP+UDP+Geneve frames on the physical side (udp.Encode/udp.Decode own the outer stack); the backplane pod has NET_ADMIN but no CAP_NET_RAW, so the underlay is a plain UDP socket and the driver's Underlay implementation peels the outer headers on TX and synthesizes them on RX (see udpUnderlay). The driver drives the engine strictly through the cross-buffer EngineXfrm contract — never the in-place forwarder.Handler path, whose shared-UMEM / exact-GCM-overlap contract a copy-based driver cannot honor.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Engine is the ICX engine performing encap/decap + crypto. *icx.Handler
	// satisfies this; it must be configured in layer3 mode (WithLayer3VirtFrames),
	// since the TUN device carries raw L3 inner packets.
	Engine vtep.EngineXfrm
	// Device is the overlay-side TUN device. The driver owns it and closes it on
	// Close.
	Device Device
	// Underlay is the encap'd-frame transport. The driver owns it and closes it on
	// Close.
	Underlay Underlay
	// DeviceOffset is the read/write headroom offset into Device buffers. The real
	// wireguard TUN needs >= virtioNetHdrLen (10); device_linux.go uses 16. The
	// test fake uses 0. Negative values are treated as 0.
	DeviceOffset int
	// InnerMTU is the overlay MTU; 0 uses defaultInnerMTU (1280). It sizes the TUN
	// read/decap buffers and must not exceed what the underlay path can carry.
	InnerMTU int
	// FlushInterval overrides how often scheduled (keep-alive) frames are flushed.
	// Zero uses defaultFlushInterval.
	FlushInterval time.Duration
}

Config configures a Datapath. Engine, Device and Underlay are required.

type Datapath

type Datapath struct {
	// contains filtered or unexported fields
}

Datapath splices a TUN device to the ICX engine over a UDP underlay. It implements vtep.Datapath.

func New

func New(cfg Config) (*Datapath, error)

New creates a Datapath over an injected device and underlay. The pumps do not run until Run is called.

func Open

func Open(cfg OpenConfig) (*Datapath, error)

Open creates a /dev/net/tun overlay device and a UDP underlay socket, wires them to the engine, configures the device's MTU/addresses/routes, and returns a ready-to-Run Datapath that OWNS both (Close tears them down). It requires NET_ADMIN and access to /dev/net/tun.

func (*Datapath) Close

func (d *Datapath) Close() error

Close stops the datapath and releases the device and underlay it owns. It is safe to call after Run returns and idempotent. Closing the device unblocks the outbound pump; closing the underlay unblocks the inbound pump; closing done stops the keep-alive pump.

func (*Datapath) Run

func (d *Datapath) Run(ctx context.Context) error

Run drives the pump loops and blocks until shutdown. Cancelling ctx (or calling Close) tears down the device and underlay, which unblocks the data pumps; Run then returns. A nil return means a clean shutdown. Run must not be called more than once, nor after Close.

type Device

type Device interface {
	// Read reads up to len(bufs) packets, writing packet i into bufs[i][offset:]
	// and its length into sizes[i] (len(sizes) >= len(bufs)); returns the packet
	// count. It blocks until at least one packet is available or the device is
	// closed (after which it returns a closed error).
	Read(bufs [][]byte, sizes []int, offset int) (int, error)
	// Write writes len(bufs) packets, taking packet i from bufs[i][offset:].
	Write(bufs [][]byte, offset int) (int, error)
	// BatchSize is the max number of packets a single Read/Write handles.
	BatchSize() int
	io.Closer
}

Device is the overlay-side L3 TUN device the driver owns. It is the subset of golang.zx2c4.com/wireguard/tun.Device the datapath uses; the real /dev/net/tun device (device_linux.go) and the in-memory test fake both satisfy it. Packets are raw L3 IP (the device is opened IFF_NO_PI); Read/Write take a fixed offset (Config.DeviceOffset) so the device implementation has the headroom it needs.

type OpenConfig

type OpenConfig struct {
	// Engine is the ICX engine; it must be configured in layer3 mode.
	Engine vtep.EngineXfrm
	// Name is the TUN interface name to create (e.g. "icx0"). An empty name lets
	// the kernel pick one.
	Name string
	// OverlayAddrs are the L3 addresses assigned to the TUN device (the overlay
	// CIDRs the consumer's stack owns).
	OverlayAddrs []netip.Prefix
	// Routes are the overlay prefixes routed out the TUN device (link-scoped).
	Routes []netip.Prefix
	// InnerMTU is the device MTU / inner-MTU clamp; 0 uses defaultInnerMTU (1280).
	InnerMTU int
	// UnderlayBind is the local UDP address the underlay socket binds to.
	UnderlayBind netip.AddrPort
	// FlushInterval overrides the keep-alive flush cadence; 0 uses the default.
	FlushInterval time.Duration
}

OpenConfig configures Open. Engine, Name and UnderlayBind are required.

type Underlay

type Underlay interface {
	// ReadFrame reads a single underlay frame into buf, returning its length. A
	// length of 0 with a nil error is skipped. Once Close has been called it must
	// return an error satisfying errors.Is(err, net.ErrClosed).
	ReadFrame(buf []byte) (int, error)
	// WriteFrames writes a batch of full phy frames, returning the number actually
	// sent. A short write (n < len(frames)) is permitted; the datapath drains the
	// unsent suffix by calling again, so implementations must not drop the tail. A
	// zero return with a nil error is treated as a stall. The frames are owned by
	// the caller and valid only until the call returns.
	WriteFrames(frames [][]byte) (int, error)
	io.Closer
}

Underlay is the encap'd-frame transport the driver owns. It carries full Ethernet+IP+UDP+Geneve "phy" frames to/from the engine — the same contract the netstack driver's Underlay uses — peeling the outer headers onto a UDP socket internally (see udpUnderlay). It additionally satisfies io.Closer because the tun driver owns the socket's lifecycle; closing it unblocks a running inbound pump.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL