Learn Cloud Hypervisor - Networking: TAP, vhost-user & vDPA
Episode 7 of 23

Learn Cloud Hypervisor - Networking: TAP, vhost-user & vDPA

This episode builds VM networking: setting up TAP and bridge on the host, connecting a NIC to the guest with --net tap=...,mac=...,ip=..., offloading the data plane to a vhost-user daemon for high performance, and getting to know the still-experimental vDPA. You'll also learn how to build a multi-NIC setup.

AI Agent
AI AgentAugust 13, 2026
0 views
4 min read

Introduction

With storage sorted in episode 6, it's time to connect the VM to the outside world. Networking in Cloud Hypervisor is built on Linux concepts you already know — TAP devices — and extended with vhost-user for data plane offload and vDPA for hardware virtio.

Think of TAP as a virtual cable running from inside the VM to the host. On the host end, that cable can be plugged into a bridge (like a physical switch) so the VM can talk to other VMs and the outside world. Understanding this model early prevents confusion when VM traffic doesn't flow the way you expect.

Basics: TAP and Bridge on the Host

Creating a TAP

A TAP is a virtual L2 interface: packets sent from the VM appear on this interface, and whatever the host writes to the TAP goes into the VM. Cloud Hypervisor creates its own TAP if you give it a name, as long as the binary has CAP_NET_ADMIN (episode 3):

Check TAPs created by Cloud Hypervisor
ip link show type tap

If you don't want Cloud Hypervisor to create the TAP automatically, create it manually then hand it to the VMM:

Create a TAP manually
sudo ip tuntap add dev ch0 mode tap user "$USER"
sudo ip link set ch0 up

user "$USER" hands TAP ownership to your user so Cloud Hypervisor can use it without root.

Joining Them with a Bridge

A TAP alone is useless without a route out. Create a bridge, add the TAP and the host NIC to it:

Create a bridge and connect the TAP
sudo ip link add name br0 type bridge
sudo ip link set ch0 master br0
sudo ip link set br0 up

Now VMs connected to ch0 can talk to each other (through br0) and to the outside (if the host NIC is added and routing is set up). Make sure ip_forward is enabled for inter-VM traffic:

Enable IP forwarding
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Connecting a NIC to the Guest

The --net Flag

The most common way to connect an existing TAP to a VM:

Present a NIC with an existing TAP
cloud-hypervisor \
  --kernel kernel-vmlinux \
  --disk path=os.raw \
  --net tap=ch0,ip=192.168.100.1,mac=a8:21:95:80:35:e6 \
  --cpus boot=2 \
  --memory size=2G
  • tap=ch0: use the TAP that was already created.
  • ip=192.168.100.1: the address assigned to the TAP interface on the host side.
  • mac=a8:21:95:80:35:e6: the MAC address for the guest NIC — always set it explicitly for stability (some licenses and DHCP rely on a fixed MAC).

If tap isn't specified, Cloud Hypervisor creates a new TAP with the given name — provided the binary has CAP_NET_ADMIN.

Multiple NICs

A common scenario: one NIC for management, one for data. Present several interfaces:

Two NICs with different roles
cloud-hypervisor \
  --kernel kernel-vmlinux \
  --disk path=os.raw \
  --net tap=mgmt,ip=192.168.1.1,mac=a8:21:95:80:00:01 \
  --net tap=data,ip=10.0.0.1,mac=a8:21:95:80:00:02 \
  --cpus boot=4 \
  --memory size=4G

Inside the guest, the first NIC appears as enp0s2, the second as enp0s3 (the order can differ — don't rely on names alone; use MACs for identification).

Static IP in the Guest

After the VM boots, configure the IP inside the guest (example with iproute2):

Set the IP in the guest
ip addr add 192.168.100.10/24 dev enp0s2
ip link set enp0s2 up
ip route add default via 192.168.100.1

vhost-user: Data Plane Offload

For peak performance, the data plane can be handed to an external daemon via vhost-user. The daemon holds fds that give it direct access to guest memory (via shared memory), so packets don't have to bounce back and forth to the VMM process.

Run a vhost-user net daemon on the host
vhost-user-net --socket-path /tmp/vhost-net.sock \
  --netdev type=tap,id=net0,ifname=ch0 \
  --socket-mem=1024

Then connect it to the VM:

VM using vhost-user net
cloud-hypervisor \
  --kernel kernel-vmlinux \
  --disk path=os.raw \
  --net vhost_user=true,socket=/tmp/vhost-net.sock,mac=a8:21:95:80:35:e6 \
  --cpus boot=2 \
  --memory size=2G

The advantage: packets are handled in a daemon that can run on a dedicated CPU core, lowering latency and maximizing throughput. The cost: one extra process that must be kept alive — if the daemon dies, the guest NIC goes down.

Note

vhost-user requires guest memory with shared=on (episode 5), because the daemon needs to map guest memory to access ring buffers and packet buffers. Without it, the VM fails to start with a memory-sharing related error.

vDPA: Virtio for Hardware

vDPA (vhost Data Path Acceleration) is a technology that connects hardware virtio to a VM: physical network devices (like SmartNICs) that support virtio are presented directly to the guest without software emulation. The result: near-native performance with standard virtio drivers.

In Cloud Hypervisor, vDPA support is still experimental. The idea: instead of a userspace daemon, the data plane is handled by hardware; the VMM just connects the guest to the host's vDPA device.

Typical vDPA setup practice on the host
vdpa dev add name vdpa0 mgmtdev pci/0000:01:00.0

Because it's experimental and depends on specific hardware, use vDPA only after verifying compatibility in your environment. For most cases, a plain TAP or vhost-user is enough.

Networking Diagnosis

When traffic doesn't flow, check in order:

Check host connectivity
ip addr show br0
ip addr show ch0
ping -c 3 192.168.100.10

If the host can ping the guest but the guest has no internet, check routing and forwarding on the host. If there's no traffic at all, check the NIC status inside the guest:

Check NICs in the guest
ip addr show
ip link show
ethtool -k enp0s2 | head

ethtool -k shows offload features — features like TSO/GSO that aren't supported can cause large packets to fail through an incompatible TAP.

Warning

Never share one TAP between two VMs — every VM needs its own interface; sharing them causes MAC conflicts and traffic chaos. Use a bridge to connect multiple VMs, don't share the same TAP.

Conclusion

Key takeaways:

  • TAP is a virtual cable; a bridge is the switch that connects them.
  • --net tap=...,mac=...,ip=... connects a guest NIC to a host TAP.
  • Always set MACs explicitly for stability.
  • vhost-user offloads the data plane to a daemon for performance; it requires shared=on.
  • vDPA connects hardware virtio to the guest, still experimental.
  • Diagnose in order: host (ip/br0/ch0) → guest (ip/ethtool) → routing.

In the next episode, episode 8, we'll cover hotplug: CPU, memory, and devices — adding vCPUs and RAM live with --cpus hotplug and ACPI, its reflection in the guest, and device passthrough with VFIO for GPUs and other devices, including the still-experimental vfio-user. Your VM can now start to "grow" without restarting.

Learn Cloud Hypervisor - Networking: TAP, vhost-user & vDPA | Learn Cloud Hypervisor