- docs/design/fips-tun-driver.md: comprehensive TUN interface documentation - Architecture diagrams, component descriptions, packet flow - Implementation status checklist (completed vs planned) - Testing instructions and configuration reference
8.7 KiB
FIPS TUN Driver Design
This document describes the design and implementation of the TUN interface driver that connects FIPS to the local system's network stack.
Overview
The TUN driver provides the interface between local applications and the FIPS
mesh network. It presents a virtual network interface (fips0) with the node's
FIPS address, allowing standard socket applications to communicate over the
mesh transparently.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Local System │
│ ┌──────────────┐ │
│ │ Applications │ (sockets using fd00::/8 addresses) │
│ └──────┬───────┘ │
│ │ │
│ ┌──────▼───────┐ │
│ │ Kernel │ routing: fd00::/8 → fips0 │
│ │ IPv6 Stack │ local table intercepts traffic to self │
│ └──────┬───────┘ │
└─────────┼───────────────────────────────────────────────────────┘
│ raw IPv6 packets
┌─────────▼───────────────────────────────────────────────────────┐
│ TUN Device (fips0) │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ File Descriptor ││
│ │ (duplicated for reader/writer) ││
│ └──────────┬─────────────────────────────┬────────────────────┘│
│ │ │ │
│ ┌──────▼──────┐ ┌──────▼──────┐ │
│ │ Reader │ │ Writer │ │
│ │ Thread │ │ Thread │ │
│ │ (blocking) │ │ (blocking) │ │
│ └──────┬──────┘ └──────▲──────┘ │
│ │ │ │
└─────────────┼─────────────────────────────┼──────────────────────┘
│ │
▼ │
┌─────────────┐ ┌───────┴───────┐
│ Packet │ │ TX Queue │
│ Processing │──────────────▶ (mpsc) │
│ (routing) │ │ │
└─────────────┘ └───────▲───────┘
│
(future: transports)
Components
TunDevice (src/tun.rs)
The main TUN device wrapper that handles creation, configuration, and lifecycle.
Responsibilities:
- Create TUN interface via
tuncrate - Configure IPv6 address via netlink (
rtnetlink) - Set MTU and bring interface up
- Provide read access for incoming packets
- Create writer handle via fd duplication
Lifecycle:
- Startup: Delete existing interface if present, create new
- Active: Reader and writer threads operate independently
- Shutdown: Delete interface via netlink, threads exit on I/O error
TunWriter (src/tun.rs)
Services a queue of outbound packets and writes them to the TUN device.
Design rationale:
Multiple sources will need to write to TUN:
- ICMPv6 error responses (from packet processing)
- Inbound mesh traffic from peers (future: transports)
- Locally-generated control traffic (future)
A single writer thread with an mpsc queue provides:
- No contention on TUN writes
- Clean separation of concerns
- Easy addition of new packet sources via
TunTx::clone()
ICMPv6 Module (src/icmp.rs)
Generates RFC 4443 compliant ICMPv6 error messages.
Currently implemented:
- Type 1 Code 0: Destination Unreachable - No route
Validation (when NOT to send errors):
- Original packet was an ICMPv6 error (types 0-127)
- Source address is multicast (0xff prefix)
- Source address is unspecified (::)
Response format:
- Total size ≤ 1280 bytes (IPv6 minimum MTU)
- Includes as much of original packet as fits
- Proper checksum with pseudo-header
Packet Flow
Outbound (local → mesh)
- Application sends to
fd00::/8address - Kernel routes to
fips0(requires manual route addition) - TUN reader receives raw IPv6 packet
- Packet processing determines next hop
- If routable: forward to transport (future)
- If not routable: send ICMPv6 Destination Unreachable via TX queue
Inbound (mesh → local)
- Transport receives packet from peer (future)
- Check destination address
- If destination is self: write to TUN via TX queue
- If destination is other: forward to next hop (transit)
Local Address Guarantee
Packets arriving at the TUN reader are guaranteed NOT to be destined for local addresses. The Linux kernel routing order ensures this:
- Local routing table - intercepts traffic to addresses on this machine
- Main routing table - routes
fd00::/8to fips0
This means every packet in the TUN reader requires a routing decision. No "is this for me?" check needed on the read path.
Configuration
From fips.yaml:
tun:
enabled: true
name: fips0
mtu: 1400
Parameters:
| Field | Default | Description |
|---|---|---|
enabled |
true |
Enable TUN interface |
name |
fips0 |
Interface name |
mtu |
1400 |
Maximum transmission unit |
Privileges
TUN device creation requires CAP_NET_ADMIN. Options:
- Run as root:
sudo ./fips - Set capability:
sudo setcap cap_net_admin+ep ./target/debug/fips - Pre-created device: Admin creates persistent TUN, FIPS just opens it
Route Configuration
The kernel route must be added manually (not done by FIPS):
sudo ip -6 route add fd00::/8 dev fips0
This routes all FIPS addresses through the TUN interface.
Implementation Status
Completed
- TUN device creation and configuration
- IPv6 address assignment via netlink
- Interface lifecycle (startup cleanup, graceful shutdown)
- Reader thread with blocking I/O
- Writer thread with mpsc queue
- fd duplication for independent read/write
- ICMPv6 Destination Unreachable (Type 1 Code 0)
- Packet validation for ICMPv6 error generation
Planned
- ICMPv6 Echo Reply (respond to ping)
- ICMPv6 Packet Too Big (PMTUD support)
- ICMPv6 Time Exceeded (hop limit)
- Rate limiting for ICMPv6 errors
- Integration with routing/forwarding logic
- Transit packet handling (decrement hop limit, forward)
- Automatic route management (add/remove fd00::/8 route)
Testing
Manual Testing
# Terminal 1: Run FIPS with debug logging
sudo RUST_LOG=debug ./target/debug/fips
# Terminal 2: Add route and test
sudo ip -6 route add fd00::/8 dev fips0
ping6 -c 1 fd00::1
# Expected: "Destination unreachable: No route" (not timeout)
Verifying Local Routing
# Check that local address goes via loopback, not TUN
ip -6 route get <your-fips-address>
# Should show: local ... dev lo
Dependencies
| Crate | Purpose |
|---|---|
tun |
TUN device creation |
rtnetlink |
Netlink interface configuration |
libc |
fd duplication (dup) |
futures |
Async netlink operations |
References
- RFC 4443: ICMPv6 for IPv6
- RFC 4291: IPv6 Addressing Architecture
- Linux TUN/TAP documentation