Files
volt-vmm/vmm/docs/NETWORKD_NATIVE_NETWORKING.md
Karl Clinger 40ed108dd5 Volt VMM (Neutron Stardust): source-available under AGPSL v5.0
KVM-based microVMM for the Volt platform:
- Sub-second VM boot times
- Minimal memory footprint
- Landlock LSM + seccomp security
- Virtio device support
- Custom kernel management

Copyright (c) Armored Gates LLC. All rights reserved.
Licensed under AGPSL v5.0
2026-03-21 01:04:35 -05:00

308 lines
25 KiB
Markdown

# Networkd-Native VM Networking Design
## Executive Summary
This document describes a networking architecture for Volt VMs that **replaces virtio-net** with networkd-native approaches, achieving significantly higher performance through kernel bypass and direct hardware access.
## Performance Comparison
| Backend | Throughput | Latency | CPU Usage | Complexity |
|--------------------|---------------|--------------|------------|------------|
| virtio-net (user) | ~1-2 Gbps | ~50-100μs | High | Low |
| virtio-net (vhost) | ~10 Gbps | ~20-50μs | Medium | Low |
| **macvtap** | **~20+ Gbps** | ~10-20μs | Low | Low |
| **AF_XDP** | **~40+ Gbps** | **~5-10μs** | Very Low | High |
| vhost-user-net | ~25 Gbps | ~15-25μs | Low | Medium |
## Architecture Overview
```
┌─────────────────────────────────────────────────────────────────────────┐
│ Host Network Stack │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ systemd-networkd │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ .network │ │ .netdev │ │ .link │ │ │
│ │ │ files │ │ files │ │ files │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Network Backends │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ macvtap │ │ AF_XDP │ │ vhost-user │ │ │
│ │ │ Backend │ │ Backend │ │ Backend │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ /dev/tapN │ │ XSK socket │ │ Unix sock │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
│ │ │ │ │ │ │
│ │ ┌──────┴────────────────┴────────────────┴──────┐ │ │
│ │ │ Unified NetDevice API │ │ │
│ │ │ (trait-based abstraction) │ │ │
│ │ └────────────────────────┬───────────────────────┘ │ │
│ │ │ │ │
│ └───────────────────────────┼────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────┼───────────────────────────────────────┐ │
│ │ Volt VMM │ │
│ │ │ │ │
│ │ ┌────────────────────────┴───────────────────────────────────┐ │ │
│ │ │ VirtIO Compatibility │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │
│ │ │ │ virtio-net HDR │ │ Guest Driver │ │ │ │
│ │ │ │ translation │ │ Compatibility │ │ │ │
│ │ │ └─────────────────┘ └─────────────────┘ │ │ │
│ │ └────────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Physical NIC │ │
│ │ (or veth pair) │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```
## Option 1: macvtap (Recommended Default)
### Why macvtap?
- **No bridge needed**: Direct attachment to physical NIC
- **Near-native performance**: Packets bypass userspace entirely
- **Networkd integration**: First-class support via `.netdev` files
- **Simple setup**: Works like a TAP but with hardware acceleration
- **Multi-queue support**: Scale with multiple vCPUs
### How it Works
```
┌────────────────────────────────────────────────────────────────┐
│ Guest VM │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ virtio-net driver │ │
│ └────────────────────────────┬─────────────────────────────┘ │
└───────────────────────────────┼─────────────────────────────────┘
┌───────────────────────────────┼─────────────────────────────────┐
│ Volt VMM │ │
│ ┌────────────────────────────┴─────────────────────────────┐ │
│ │ MacvtapDevice │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ /dev/tap<ifindex> │ │ │
│ │ │ - read() → RX packets │ │ │
│ │ │ - write() → TX packets │ │ │
│ │ │ - ioctl() → offload config │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└───────────────────────────────┬─────────────────────────────────┘
┌───────────┴───────────┐
│ macvtap interface │
│ (macvtap0) │
└───────────┬───────────┘
│ direct attachment
┌───────────┴───────────┐
│ Physical NIC │
│ (eth0 / enp3s0) │
└───────────────────────┘
```
### macvtap Modes
| Mode | Description | Use Case |
|------------|------------------------------------------|-----------------------------|
| **vepa** | All traffic goes through external switch | Hardware switch with VEPA |
| **bridge** | VMs can communicate directly | Multi-VM on same host |
| **private**| VMs isolated from each other | Tenant isolation |
| **passthru**| Single VM owns the NIC | Maximum performance |
## Option 2: AF_XDP (Ultra-High Performance)
### Why AF_XDP?
- **Kernel bypass**: Zero-copy to/from NIC
- **40+ Gbps**: Near line-rate on modern NICs
- **eBPF integration**: Programmable packet processing
- **XDP program**: Filter/redirect at driver level
### How it Works
```
┌────────────────────────────────────────────────────────────────────┐
│ Guest VM │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ virtio-net driver │ │
│ └────────────────────────────┬─────────────────────────────────┘ │
└───────────────────────────────┼─────────────────────────────────────┘
┌───────────────────────────────┼─────────────────────────────────────┐
│ Volt VMM │ │
│ ┌────────────────────────────┴─────────────────────────────────┐ │
│ │ AF_XDP Backend │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ XSK Socket │ │ │
│ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │
│ │ │ │ UMEM │ │ Fill/Comp │ │ │ │
│ │ │ │ (shared mem)│ │ Rings │ │ │ │
│ │ │ └──────────────┘ └──────────────┘ │ │ │
│ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │
│ │ │ │ RX Ring │ │ TX Ring │ │ │ │
│ │ │ └──────────────┘ └──────────────┘ │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
└───────────────────────────────┬─────────────────────────────────────┘
┌───────────┴───────────┐
│ XDP Program │
│ (eBPF redirect) │
└───────────┬───────────┘
│ zero-copy
┌───────────┴───────────┐
│ Physical NIC │
│ (XDP-capable) │
└───────────────────────┘
```
### AF_XDP Ring Structure
```
UMEM (Shared Memory Region)
┌─────────────────────────────────────────────┐
│ Frame 0 │ Frame 1 │ Frame 2 │ ... │ Frame N │
└─────────────────────────────────────────────┘
↑ ↑
│ │
┌────┴────┐ ┌────┴────┐
│ RX Ring │ │ TX Ring │
│ (NIC→VM)│ │ (VM→NIC)│
└─────────┘ └─────────┘
↑ ↑
│ │
┌────┴────┐ ┌────┴────┐
│ Fill │ │ Comp │
│ Ring │ │ Ring │
│ (empty) │ │ (done) │
└─────────┘ └─────────┘
```
## Option 3: Direct Namespace Networking (nspawn-style)
For containers and lightweight VMs, share the kernel network stack:
```
┌──────────────────────────────────────────────────────────────────┐
│ Host │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Network Namespace (vm-ns0) │ │
│ │ ┌──────────────────┐ │ │
│ │ │ veth-vm0 │ ◄─── Guest sees this as eth0 │ │
│ │ │ 10.0.0.2/24 │ │ │
│ │ └────────┬─────────┘ │ │
│ └───────────┼────────────────────────────────────────────────┘ │
│ │ veth pair │
│ ┌───────────┼────────────────────────────────────────────────┐ │
│ │ │ Host Namespace │ │
│ │ ┌────────┴─────────┐ │ │
│ │ │ veth-host0 │ │ │
│ │ │ 10.0.0.1/24 │ │ │
│ │ └────────┬─────────┘ │ │
│ │ │ │ │
│ │ ┌────────┴─────────┐ │ │
│ │ │ nft/iptables │ NAT / routing │ │
│ │ └────────┬─────────┘ │ │
│ │ │ │ │
│ │ ┌────────┴─────────┐ │ │
│ │ │ eth0 │ Physical NIC │ │
│ │ └──────────────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
```
## Voltainer Integration
### Shared Networking Model
Volt VMs can participate in Voltainer's network zones:
```
┌─────────────────────────────────────────────────────────────────────┐
│ Voltainer Network Zone │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Container A │ │ Container B │ │ Volt │ │
│ │ (nspawn) │ │ (nspawn) │ │ VM │ │
│ │ │ │ │ │ │ │
│ │ veth0 │ │ veth0 │ │ macvtap0 │ │
│ │ 10.0.1.2 │ │ 10.0.1.3 │ │ 10.0.1.4 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌──────┴────────────────┴────────────────┴──────┐ │
│ │ zone0 bridge │ │
│ │ 10.0.1.1/24 │ │
│ └────────────────────────┬───────────────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ nft NAT │ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ eth0 │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
```
### networkd Configuration Files
All networking is declarative via networkd drop-in files:
```
/etc/systemd/network/
├── 10-physical.link # udev rules for NIC naming
├── 20-macvtap@.netdev # Template for macvtap devices
├── 25-zone0.netdev # Voltainer zone bridge
├── 25-zone0.network # Zone bridge configuration
├── 30-vm-<uuid>.netdev # Per-VM macvtap
└── 30-vm-<uuid>.network # Per-VM network config
```
## Implementation Phases
### Phase 1: macvtap Backend (Immediate)
- Implement `MacvtapDevice` replacing `TapDevice`
- networkd integration via `.netdev` files
- Multi-queue support
### Phase 2: AF_XDP Backend (High Performance)
- XSK socket implementation
- eBPF XDP redirect program
- UMEM management with guest memory
### Phase 3: Voltainer Integration
- Zone participation for VMs
- Shared networking model
- Service discovery
## Selection Criteria
```
┌─────────────────────────────────────────────────────────────────┐
│ Backend Selection Logic │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Is NIC XDP-capable? ──YES──► Need >25 Gbps? ──YES──► │
│ │ │ │
│ NO NO │
│ ▼ ▼ │
│ Need VM-to-VM on host? Use AF_XDP │
│ │ │
│ ┌─────┴─────┐ │
│ YES NO │
│ │ │ │
│ ▼ ▼ │
│ macvtap macvtap │
│ (bridge) (passthru) │
│ │
└─────────────────────────────────────────────────────────────────┘
```