Bridge
The guest joins the physical L2 segment directly. Guest-side DHCP configures its own address — the FlashVM looks like any other host on the network.
Technology — Networking
flashvmm never holds CAP_NET_ADMIN — not "drops it after setup," never has it at all. A separate process, flashnet, does every piece of host-side network mutation, then hands off to an unprivileged flash run.
flowchart LR
A["flashnet --mode {bridge|nat|routed}
--uplink IFACE"] --> B["Create persistent TAP device"]
B --> C{mode}
C -->|bridge| D["Guest joins physical L2 segment
guest DHCP configures itself"]
C -->|nat| E["Per-VM nftables NAT table
fixed 192.168.253.2/30"]
C -->|routed| F["Real DHCP lease via proxy-ARP"]
D --> G["fork()"]
E --> G
F --> G
G --> H["drop ALL capabilities
in the child"]
H --> I["exec flash run ... --nic TAP"]
I --> J["flashvmm: CAP_NET_ADMIN
never held, ever"]
The guest joins the physical L2 segment directly. Guest-side DHCP configures its own address — the FlashVM looks like any other host on the network.
A per-VM nftables NAT table gives the guest a fixed internal address (192.168.253.2/30) translated to the host's uplink — isolated by default, reachable via explicit port mapping.
The guest gets a real DHCP lease via proxy-ARP — routable, without joining the physical L2 segment directly.
The single most dangerous capability a compromised VMM process could have is direct control over host networking. FlashVMM's architecture makes that impossible by construction, not by convention: the process that actually runs guest code has never, at any point in its lifetime, held CAP_NET_ADMIN. The capability lives only in flashnet, and only until the fork — after which the child that becomes flashvmm has already dropped everything. A vulnerability in the VMM's virtio-net implementation cannot escalate into host network control, because the process running that code was never capable of it.