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
308 lines
25 KiB
Markdown
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) │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|