Skip to content

[vtep] add tun datapath driver + afxdp wrapper (APO-794)#3

Merged
dilyevsky merged 1 commit into
mainfrom
dsky/apo-794-tun-vtep-driver
Jun 16, 2026
Merged

[vtep] add tun datapath driver + afxdp wrapper (APO-794)#3
dilyevsky merged 1 commit into
mainfrom
dsky/apo-794-tun-vtep-driver

Conversation

@dilyevsky

Copy link
Copy Markdown
Contributor

Adds the tun VTEP I/O driver (APO-794) — the kernel-device overlay for the backplane/Envoy cluster VTEP — over the vtep.Datapath/EngineXfrm seam, plus a thin afxdp wrapper so all three drivers (afxdp/tun/netstack) now satisfy vtep.Datapath.

Driver

The tun driver splices a /dev/net/tun device (overlay, raw L3) to a UDP underlay through the cross-buffer icx.Handler. The engine emits full Ethernet+IP+UDP+Geneve frames but the backplane pod has only NET_ADMIN (no CAP_NET_RAW), so the underlay is a plain UDP socket and the driver peels the outer headers on TX / synthesizes them on RX — the same bridge apoxy-cli's l2pc performs.

  • vtep/tun/datapath.go — cross-platform pump core (outbound TUN→engine→UDP, inbound UDP→engine→TUN, keepalive ToPhy), Run/Close, static 1280 inner-MTU clamp, owned device+underlay.
  • vtep/tun/underlay.goudpUnderlay: peel/synthesize over net.UDPConn.
  • vtep/tun/device_linux.go — real /dev/net/tun via wireguard/tun + offload disable + netlink addr/route/MTU (RouteReplace, idempotent), behind Open().
  • vtep/afxdp/datapath.go — wraps forwarder.Forwarder (in-place hot loop untouched) as vtep.Datapath. cli/main.go is not repointed — pure addition, node path byte-identical.

Safety

  • Decap is bounded for the worst case (PhyToVirt's AES-GCM Open does not clamp output to the destination buffer, unlike the APO-667 encap bound) — found + fixed with a regression that reproduces the original slice bounds out of range panic.
  • Read pumps back off + give up on persistent errors rather than busy-spin.
  • Hardened per an adversarial review (memory-safety / crypto / concurrency / linux-device).

Tests

Unit (peel/synthesize, pump plumbing, lifecycle, config) + integration (two real handlers exchanging AES-GCM Geneve over a real loopback UDP underlay) + an oversized-decap regression + a root-gated real-/dev/net/tun smoke test.

Verified on darwin (race-clean) and on a real linux kernel via OrbStack: full module test suite passes, and the privileged device path (Open → CreateTUN → offload-disable → netlink → Run/Close) passes as root. Running on real linux caught the RouteAddRouteReplace connected-route collision fixed here.

Adds golang.zx2c4.com/wireguard (tun device) as a direct dependency.

🤖 Generated with Claude Code

Adds the tun VTEP I/O driver -- the kernel-device overlay for the
backplane/Envoy cluster VTEP -- over the vtep.Datapath/EngineXfrm seam,
plus a thin afxdp wrapper so all three drivers (afxdp/tun/netstack) now
satisfy vtep.Datapath.

The tun driver splices a /dev/net/tun device (overlay, raw L3) to a UDP
underlay through the cross-buffer icx.Handler. The engine emits full
Ethernet+IP+UDP+Geneve frames but the backplane pod has only NET_ADMIN
(no CAP_NET_RAW), so the underlay is a plain UDP socket and the driver
peels the outer headers on TX / synthesizes them on RX -- the same bridge
apoxy-cli's l2pc performs. Structure:

- vtep/tun/datapath.go      cross-platform pump core (outbound TUN->engine->UDP,
                            inbound UDP->engine->TUN, keepalive ToPhy), Run/Close,
                            static 1280 inner-MTU clamp, owned device+underlay.
- vtep/tun/underlay.go      udpUnderlay: peel/synthesize over net.UDPConn.
- vtep/tun/device_linux.go  real /dev/net/tun via wireguard/tun + offload disable
                            + netlink addr/route/MTU (RouteReplace, idempotent),
                            behind Open().
- vtep/afxdp/datapath.go    wraps forwarder.Forwarder (in-place hot loop untouched)
                            as vtep.Datapath. cli/main.go is NOT repointed -- pure
                            addition, node path byte-identical.

Decap is bounded for the worst case (PhyToVirt's AES-GCM Open does not clamp
output to the destination buffer, unlike the APO-667 encap bound), and the
read pumps back off + give up on persistent errors rather than busy-spin.

Tests: unit (peel/synthesize, pump plumbing, lifecycle, config) + integration
(two real handlers exchanging AES-GCM Geneve over a real loopback UDP underlay)
+ an oversized-decap regression + a root-gated real-/dev/net/tun smoke test.
Verified on darwin (race-clean) and on a real linux kernel (full module suite
+ the privileged device path).

Adds golang.zx2c4.com/wireguard (tun device) as a direct dependency.
@linear-code

linear-code Bot commented Jun 16, 2026

Copy link
Copy Markdown

APO-794

@dilyevsky dilyevsky merged commit ca4520e into main Jun 16, 2026
@dilyevsky dilyevsky deleted the dsky/apo-794-tun-vtep-driver branch June 16, 2026 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant