Re: [PATCH v2 0/3] vsock: add namespace support to vhost-vsock

From: Stefano Garzarella
Date: Thu Mar 13 2025 - 11:37:43 EST


Hi Bobby,
first of all, thank you for starting this work again!

On Wed, Mar 12, 2025 at 07:28:33PM -0700, Bobby Eshleman wrote:
Hey all,

Apologies for forgetting the 'net-next' prefix on this one. Should I
resend or no?

I'd say let's do a firts review cycle on this, then you can re-post.
Please check also maintainer cced, it looks like someone is missing:
https://patchwork.kernel.org/project/netdevbpf/patch/20250312-vsock-netns-v2-1-84bffa1aa97a@xxxxxxxxx/


Best,
Bobby

On Wed, Mar 12, 2025 at 01:59:34PM -0700, Bobby Eshleman wrote:
Picking up Stefano's v1 [1], this series adds netns support to
vhost-vsock. Unlike v1, this series does not address guest-to-host (g2h)
namespaces, defering that for future implementation and discussion.

Any vsock created with /dev/vhost-vsock is a global vsock, accessible
from any namespace. Any vsock created with /dev/vhost-vsock-netns is a
"scoped" vsock, accessible only to sockets in its namespace. If a global
vsock or scoped vsock share the same CID, the scoped vsock takes
precedence.

This inside the netns, right?
I mean if we are in a netns, and there is a VM A attached to /dev/vhost-vsock-netns witch CID=42 and a VM B attached to /dev/vhost-vsock also with CID=42, this means that VM A will not be accessible in the netns, but it can be accessible outside of the netns,
right?


If a socket in a namespace connects with a global vsock, the CID becomes
unavailable to any VMM in that namespace when creating new vsocks. If
disconnected, the CID becomes available again.

IIUC if an application in the host running in a netns, is connected to a guest attached to /dev/vhost-vsock (e.g. CID=42), a new guest can't be ask for the same CID (42) on /dev/vhost-vsock-netns in the same netns till that connection is active. Is that right?


Testing

QEMU with /dev/vhost-vsock-netns support:
https://github.com/beshleman/qemu/tree/vsock-netns

You can also use unmodified QEMU using `vhostfd` parameter of `vhost-vsock-pci` device:

# FD will contain the file descriptor to /dev/vhost-vsock-netns
exec {FD}<>/dev/vhost-vsock-netns

# pass FD to the device, this is used for example by libvirt
qemu-system-x86_64 -smp 2 -M q35,accel=kvm,memory-backend=mem \
-drive file=fedora.qcow2,format=qcow2,if=virtio \
-object memory-backend-memfd,id=mem,size=512M \
-device vhost-vsock-pci,vhostfd=${FD},guest-cid=42 -nographic

That said, I agree we can extend QEMU with `netns` param too.

BTW, I'm traveling, I'll be back next Tuesday and I hope to take a deeper look to the patches.

Thanks,
Stefano


Test: Scoped vsocks isolated by namespace

host# ip netns add ns1
host# ip netns add ns2
host# ip netns exec ns1 \
qemu-system-x86_64 \
-m 8G -smp 4 -cpu host -enable-kvm \
-serial mon:stdio \
-drive if=virtio,file=${IMAGE1} \
-device vhost-vsock-pci,netns=on,guest-cid=15
host# ip netns exec ns2 \
qemu-system-x86_64 \
-m 8G -smp 4 -cpu host -enable-kvm \
-serial mon:stdio \
-drive if=virtio,file=${IMAGE2} \
-device vhost-vsock-pci,netns=on,guest-cid=15

host# socat - VSOCK-CONNECT:15:1234
2025/03/10 17:09:40 socat[255741] E connect(5, AF=40 cid:15 port:1234, 16): No such device

host# echo foobar1 | sudo ip netns exec ns1 socat - VSOCK-CONNECT:15:1234
host# echo foobar2 | sudo ip netns exec ns2 socat - VSOCK-CONNECT:15:1234

vm1# socat - VSOCK-LISTEN:1234
foobar1
vm2# socat - VSOCK-LISTEN:1234
foobar2

Test: Global vsocks accessible to any namespace

host# qemu-system-x86_64 \
-m 8G -smp 4 -cpu host -enable-kvm \
-serial mon:stdio \)
-drive if=virtio,file=${IMAGE2} \
-device vhost-vsock-pci,guest-cid=15,netns=off

host# echo foobar | sudo ip netns exec ns1 socat - VSOCK-CONNECT:15:1234

vm# socat - VSOCK-LISTEN:1234
foobar

Test: Connecting to global vsock makes CID unavailble to namespace

host# qemu-system-x86_64 \
-m 8G -smp 4 -cpu host -enable-kvm \
-serial mon:stdio \
-drive if=virtio,file=${IMAGE2} \
-device vhost-vsock-pci,guest-cid=15,netns=off

vm# socat - VSOCK-LISTEN:1234

host# sudo ip netns exec ns1 socat - VSOCK-CONNECT:15:1234
host# ip netns exec ns1 \
qemu-system-x86_64 \
-m 8G -smp 4 -cpu host -enable-kvm \
-serial mon:stdio \
-drive if=virtio,file=${IMAGE1} \
-device vhost-vsock-pci,netns=on,guest-cid=15

qemu-system-x86_64: -device vhost-vsock-pci,netns=on,guest-cid=15: vhost-vsock: unable to set guest cid: Address already in use

Signed-off-by: Bobby Eshleman <bobbyeshleman@xxxxxxxxx>
---
Changes in v2:
- only support vhost-vsock namespaces
- all g2h namespaces retain old behavior, only common API changes
impacted by vhost-vsock changes
- add /dev/vhost-vsock-netns for "opt-in"
- leave /dev/vhost-vsock to old behavior
- removed netns module param
- Link to v1: https://lore.kernel.org/r/20200116172428.311437-1-sgarzare@xxxxxxxxxx

Changes in v1:
- added 'netns' module param to vsock.ko to enable the
network namespace support (disabled by default)
- added 'vsock_net_eq()' to check the "net" assigned to a socket
only when 'netns' support is enabled
- Link to RFC: https://patchwork.ozlabs.org/cover/1202235/

---
Stefano Garzarella (3):
vsock: add network namespace support
vsock/virtio_transport_common: handle netns of received packets
vhost/vsock: use netns of process that opens the vhost-vsock-netns device

drivers/vhost/vsock.c | 96 +++++++++++++++++++++++++++------
include/linux/miscdevice.h | 1 +
include/linux/virtio_vsock.h | 2 +
include/net/af_vsock.h | 10 ++--
net/vmw_vsock/af_vsock.c | 85 +++++++++++++++++++++++------
net/vmw_vsock/hyperv_transport.c | 2 +-
net/vmw_vsock/virtio_transport.c | 5 +-
net/vmw_vsock/virtio_transport_common.c | 14 ++++-
net/vmw_vsock/vmci_transport.c | 4 +-
net/vmw_vsock/vsock_loopback.c | 4 +-
10 files changed, 180 insertions(+), 43 deletions(-)
---
base-commit: 0ea09cbf8350b70ad44d67a1dcb379008a356034
change-id: 20250312-vsock-netns-45da9424f726

Best regards,
--
Bobby Eshleman <bobbyeshleman@xxxxxxxxx>