Virtio VSOCK Device Implementation in CubeSandbox: Enabling Secure VM-Host Communication
CubeSandbox implements the Virtio VSOCK device as a standard Virtio PCI device that bridges guest VM sockets to host-side UNIX-domain sockets through the VsockUnixBackend, enabling efficient communication between sandboxed workloads and host services without network stack overhead.
The Virtio VSOCK device implementation in TencentCloud's CubeSandbox repository follows the classic Virtio specification used by Cloud-Hypervisor, allowing guest operating systems to use standard Linux AF_VSOCK sockets while the hypervisor manages traffic through UNIX-domain sockets. This architecture provides a secure, high-performance communication channel that bypasses traditional network virtualization layers.
Configuration Layer: Parsing VSOCK Parameters
The configuration lifecycle begins in hypervisor/vmm/src/config.rs, where the VsockConfig structure defines the device's parameters. The VsockConfig::parse method (lines 1960‑1970) validates user input and ensures that both the Context ID (CID) and the UNIX socket path are properly specified.
This configuration structure captures essential parameters including the cid (unique identifier for the guest), the socket path on the host filesystem, and IOMMU settings. The parser enforces validation rules that prevent invalid configurations from reaching the device initialization stage, ensuring that the socket path exists and the CID falls within the valid range for VSOCK communication.
Device Creation: Building the Virtio VSOCK Device
The transformation from configuration to functional device occurs in hypervisor/vmm/src/device_manager.rs within the make_virtio_vsock_device method (lines 2910‑2980). This factory method performs three critical operations:
- Generates a unique device ID to identify the VSOCK device within the PCI bus
- Instantiates the backend by calling
virtio_devices::vsock::VsockUnixBackend::newfrom the external virtio-devices crate, which opens the host-side UNIX-domain socket and binds to the specified CID - Wraps the backend in an
Arc<Mutex<_>>for thread-safe access and encapsulates it within aMetaVirtioDevicestructure
The method also evaluates IOMMU requirements by checking force_iommu | vsock_cfg.iommu, ensuring that memory protection features are properly configured when the device attaches to the PCI bus via the device_node! macro.
VM Integration: Adding Devices to the PCI Bus
Once created, the device must register with the virtual machine's PCI subsystem. The Vm::add_vsock method in hypervisor/vmm/src/vm.rs (lines 1690‑1710) handles this integration by accepting the MetaVirtioDevice from the device manager and appending it to the VM's device vector.
The VM maintains a single optional VSOCK entry in its configuration structure (VmConfig::vsock), ensuring that only one VSOCK device exists per sandbox instance. This design choice simplifies the communication model while providing the guest with a standard Virtio PCI device that appears as a regular network adapter to the Linux kernel.
Runtime Data Plane: The VSOCK Backend
The actual packet forwarding logic resides in the VsockUnixBackend from the external virtio-devices crate. This backend operates as the data plane that bridges the Virtio queues with the host socket:
- Guest-to-Host traffic: The backend reads packets from the Virtio RX queue and writes them to the UNIX-domain socket
- Host-to-Guest traffic: The backend monitors the host socket and injects incoming data into the Virtio TX queue
- CID multiplexing: Uses the configured CID to distinguish traffic from different guests when multiple sandboxes share the same host
The backend respects the IOMMU configuration established during device creation, ensuring that memory access patterns comply with virtualization security policies.
Control Plane: API and CLI Interfaces
CubeSandbox exposes VSOCK management through both command-line arguments and RESTful APIs. The OpenAPI specification in hypervisor/vmm/src/api/openapi/cloud-hypervisor.yaml defines the POST /vm.add-vsock operation for runtime device addition.
The RPC handler in hypervisor/vmm/src/api/mod.rs forwards these requests to the Vm::add_vsock method, enabling dynamic device attachment without VM restart.
CLI Configuration
You can specify a VSOCK device at sandbox startup using the --vsock parameter:
cube-sandbox run \
--kernel /path/to/vmlinuz \
--disk /path/to/rootfs.img \
--vsock socket=/tmp/vsock.sock,cid=3,iommu=on
JSON-RPC API
For running VMs, use the JSON-RPC interface to add VSOCK devices dynamically:
{
"jsonrpc": "2.0",
"method": "VmAddVsock",
"params": {
"vsock": {
"socket": "/tmp/vsock.sock",
"cid": 5,
"iommu": false
}
},
"id": 1
}
Guest-Side Implementation
Applications inside the guest communicate using standard Linux VSOCK sockets:
#include <sys/socket.h>
#include <linux/vm_sockets.h>
int main() {
int fd = socket(AF_VSOCK, SOCK_STREAM, 0);
struct sockaddr_vm addr = {
.svm_family = AF_VSOCK,
.svm_cid = 5, // Must match the CID configured in the VM
.svm_port = 12345
};
connect(fd, (struct sockaddr *)&addr, sizeof(addr));
// Send/receive data through fd
close(fd);
return 0;
}
Summary
- CubeSandbox implements Virtio VSOCK through a layered architecture spanning configuration, device management, and VM integration
- The
VsockConfigstructure inhypervisor/vmm/src/config.rshandles parameter validation and parsing make_virtio_vsock_deviceindevice_manager.rscreates the device using theVsockUnixBackendfrom the virtio-devices crate- VM integration occurs through
Vm::add_vsockinvm.rs, which registers the device as aMetaVirtioDeviceon the PCI bus - Runtime communication bridges guest Virtio queues to host UNIX-domain sockets via the external backend implementation
- Management interfaces support both static CLI configuration and dynamic API-based device addition
Frequently Asked Questions
What is the role of the CID in VSOCK communication?
The Context ID (CID) is a 32-bit identifier that uniquely identifies the virtual machine within the VSOCK address space. In CubeSandbox, the CID configured in VsockConfig must match the address used by guest applications when calling connect() or bind() on AF_VSOCK sockets. The host uses this CID to distinguish traffic between multiple sandboxes that may share the same UNIX-domain socket path.
How does CubeSandbox handle IOMMU for VSOCK devices?
CubeSandbox combines the global force_iommu setting with device-specific iommu flags using the logical OR operation (force_iommu | vsock_cfg.iommu). This result determines whether the VsockUnixBackend operates with memory protection active. When enabled, the device manager configures the Virtio device to use the IOMMU domain, ensuring that DMA operations from the device undergo address translation and permission checks.
Can VSOCK devices be added after the VM has started?
Yes, CubeSandbox supports hot-plugging VSOCK devices through the POST /vm.add-vsock API endpoint defined in cloud-hypervisor.yaml. The RPC handler in api/mod.rs validates the request and invokes Vm::add_vsock, which triggers the same device creation flow used during initial VM configuration. However, the VM configuration only maintains a single VSOCK device (VmConfig::vsock), so adding a new device replaces any existing configuration.
Where does the actual socket forwarding logic reside?
While CubeSandbox manages the device lifecycle and PCI registration, the actual packet forwarding logic resides in the external virtio_devices crate within the VsockUnixBackend implementation. This separation of concerns allows CubeSandbox to focus on configuration and device management while leveraging battle-tested Virtio device implementations for the data plane.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →