vsock network namespaces let a host put each VM in a namespace of its own. A guest has no equivalent yet. It has a single G2H device that cannot be assigned to a network namespace.
This series lets a guest move that device into a network namespace. A new generic netlink family, "vsock", supports the command VSOCK_CMD_DEV_NETNS_SET which assigns the device to the namespace the request was sent from. The namespace's existing ns_mode then decides who may use it: a "global" namespace shares the device with every other global namespace, and a "local" namespace keeps the host connection to itself. The device starts out in the initial namespace, so until the command is issued nothing has moved and no mode has changed. There is no explicit unassign as assigning the device back to the initial namespace is equivalent. The command requires CAP_NET_ADMIN in the initial user namespace, so that an unprivileged user namespace cannot claim the device. Connections that can no longer reach the device after a move are reset, so that a namespace which has lost access cannot keep using a socket it opened while it still had access. The assignment holds a reference on the namespace, so deleting that namespace does not move the device; only another assignment does. Transports opt in through a new netns_assign_allow flag. Only virtio-vsock sets it here, because it is the only guest transport that I am able to test against. Based off of Stefano's original series: https://lore.kernel.org/all/[email protected]/ Suggested-by: Stefano Garzarella <[email protected]> Link: https://lore.kernel.org/all/20200427142518.uwssa6dtasrp3bfc@steredhat/ Signed-off-by: Bobby Eshleman <[email protected]> --- Changes in v5: - Rename the uapi header to linux/vsock_netlink.h (Stefano) - Drop the VSOCK_CMD_DEV_NETNS_SET reply and rely on the netlink ack (Stefano) - Keep vsock_register_mutex static, export vsock_cid_lock() and vsock_cid_unlock() for vhost_vsock_set_cid() instead (Stefano) - Replace vsock_g2h_next_unreachable() with a generic vsock_next_connected_socket() next to vsock_for_each_connected_socket(), which cannot be reused because the sweep takes lock_sock() (Stefano) - Use rcu_dereference_protected() in vsock_nl_dev_netns_fill(), drop the RCU read lock and allocate the nsid with GFP_KERNEL (Stefano) - Point to the vsock_g2h_assign_mutex comment for the lock ordering in vsock_g2h_net_assign() (Stefano) - Reverse xmas tree in vsock_dev_do_ioctl() (Stefano) - Set SOCK_DONE and peer_shutdown on swept sockets, so recv() returns EOF and send() fails with -EPIPE/-ECONNRESET instead of -ENOTCONN (Sashiko) - Only move sock->state back to SS_UNCONNECTED in vsock_connect() if it is still SS_CONNECTING, via the new vsock_connect_close(), so a socket swept while connect() sleeps cannot be connect()ed again and have vsk->trans freed under in-flight skbs (Michal) - Send the RSTs in virtio_transport_recv_listen() and virtio_transport_recv_connecting() to the netns the packet arrived on, not the socket's: after an assign the socket's netns may no longer reach the device, so the RST would be dropped by the reachability check this patch adds to virtio_transport_send_pkt() (Stefano, Sashiko) - Pick up Stefano's RoBs on patches 2 and 3 - Link to v4: https://lore.kernel.org/r/[email protected] Changes in v4: - All Sashiko fixes (see individual patch change lists) - Link to v3: https://lore.kernel.org/r/[email protected] Changes in v3: - Lots of fixes for race conditions found by local and upstream Sashiko. Sorry for the delayed reposting, it took significant time to track down and confirm that these were real issues, and come up with a decent solution for each... - Pin the assigned netns instead of returning the device to init_net when it is deleted, and refuse an assign that would make the device's CID collide with a nested H2G vhost-vsock with the same CID - Drop the idea of sending RST to the peer from the reset sweep. Sending a RST required a lock_sock, which can't be acquired underneath the vsock_table_lock. Splitting into two phases of locking opened up new races, I couldn't find a solution I was really happy with. Probably not worth the complexity - New prep patch passing the netns to ->has_remote_cid(), which is used in a later patch in the series for avoid CID collisions between nested H2G guests and the G2H device - Various fixes (see individual patch change lists for more details) - Link to v2: https://lore.kernel.org/r/[email protected] Changes in v2: - Replace the IOCTL_VM_SOCKETS_ASSIGN_G2H_NETNS ioctl with the "vsock" genl family and VSOCK_CMD_DEV_NETNS_SET - RST the peer from the reset sweep, v1 only set TCP_CLOSE locally, so the peer waited on a connection the guest had abandoned (Stefano) - Drop the vsock_assign_g2h_netns helper patch, the tests use ynl cli.py - Note why only virtio-vsock opts in (Stefano) - Add a getter to the uAPI - Various fixes (see individual patch change list for more details) - Link to v1: https://lore.kernel.org/r/[email protected] --- Bobby Eshleman (7): vsock: constify the transport in vsock_for_each_connected_socket() vsock: rename the vsock pernet operations vsock: pass the netns to ->has_remote_cid() vsock: add a netlink command to assign the g2h device to a netns vsock/virtio: support guest device network namespace selftests/vsock: test the guest vsock device network namespace selftests/vsock: test the netns assign privilege checks Documentation/admin-guide/sysctl/net.rst | 42 +++ Documentation/netlink/specs/vsock.yaml | 72 ++++ MAINTAINERS | 2 + drivers/vhost/vsock.c | 23 +- include/net/af_vsock.h | 18 +- include/uapi/linux/vsock_netlink.h | 28 ++ net/vmw_vsock/Makefile | 2 +- net/vmw_vsock/af_vsock.c | 523 +++++++++++++++++++++++++++-- net/vmw_vsock/virtio_transport.c | 34 +- net/vmw_vsock/virtio_transport_common.c | 40 ++- net/vmw_vsock/vsock_nl_gen.c | 36 ++ net/vmw_vsock/vsock_nl_gen.h | 20 ++ tools/net/ynl/Makefile.deps | 1 + tools/testing/selftests/vsock/Makefile | 5 + tools/testing/selftests/vsock/config | 1 + tools/testing/selftests/vsock/vmtest.sh | 550 ++++++++++++++++++++++++++++++- 16 files changed, 1326 insertions(+), 71 deletions(-) --- base-commit: 599d0e97610f09162d84c4ede4164628c066921e change-id: 20260831-vsock-guest-ns-d06af451da67 Best regards, -- Bobby Eshleman <[email protected]>
