[PATCH] net/9p: add vsock transport
[email protected] Wed, 27 May 2026 09:34:47 +0200
| Newsgroups | dev.linux.lists.v9fs,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Matus Skvarla <[email protected]> Add vsock as a transport option for 9P client connections. This allows mounting 9P filesystems over VM sockets without requiring TCP/IP networking or additional userspace tools. The implementation extends trans_fd.c with vsock support, reusing the existing socket infrastructure. A new p9_fd_create_vsock() function handles vsock connection setup by parsing the CID from the mount source, creating an AF_VSOCK socket, and connecting to the specified endpoint. All other transport operations (close, request, cancel) use the shared fd transport implementation. Add CONFIG_NET_9P_VSOCK option that conditionally compiles vsock support into 9pnet_fd.ko. This follows the pattern where socket-based transports (TCP, Unix, vsock) share trans_fd.c, while specialized hardware transports (virtio, xen, rdma) have dedicated files. Usage: mount -t 9p -o trans=vsock[,port=<port>] <CID> /mnt/point Signed-off-by: Matus Skvarla <[email protected]> --- include/net/9p/client.h | 6 ++- net/9p/Kconfig | 9 +++++ net/9p/trans_fd.c | 89 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 838a94218b59..4eb2f6b22496 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -122,8 +122,12 @@ struct p9_client { struct { u16 port; bool privport; - } tcp; +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) + struct { + u16 port; + } vsock; +#endif } trans_opts; struct idr fids; diff --git a/net/9p/Kconfig b/net/9p/Kconfig index 22f8c167845d..63a5b5b25063 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -32,6 +32,15 @@ config NET_9P_VIRTIO This builds support for a transports between guest partitions and a host partition. +config NET_9P_VSOCK + depends on VSOCKETS + bool "9P VSOCK Transport" + help + This builds support for a transport for 9pfs over + virtual sockets (vsock). This is useful for communication + between virtual machines and their host without requiring + TCP/IP networking configuration or additional userspace software. + config NET_9P_XEN depends on XEN select XEN_XENBUS_FRONTEND diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index dbad3213ba84..6f35f2d84313 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -28,6 +28,9 @@ #include <net/9p/9p.h> #include <net/9p/client.h> #include <net/9p/transport.h> +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) +#include <linux/vm_sockets.h> +#endif #include <linux/syscalls.h> /* killme */ @@ -36,6 +39,9 @@ static struct p9_trans_module p9_tcp_trans; static struct p9_trans_module p9_fd_trans; +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) +static struct p9_trans_module p9_vsock_trans; +#endif enum { Rworksched = 1, /* read work scheduled or running */ @@ -714,6 +720,12 @@ static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt) if (clnt->trans_opts.fd.wfd != ~0) seq_printf(m, ",wfd=%u", clnt->trans_opts.fd.wfd); } +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) + else if (clnt->trans_mod == &p9_vsock_trans) { + if (clnt->trans_opts.vsock.port != P9_FD_PORT) + seq_printf(m, ",port=%u", clnt->trans_opts.vsock.port); + } +#endif return 0; } @@ -968,6 +980,60 @@ p9_fd_create_unix(struct p9_client *client, struct fs_context *fc) return p9_socket_open(client, csocket); } +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) +static int +p9_fd_create_vsock(struct p9_client *client, struct fs_context *fc) +{ + const char *addr = fc->source; + struct v9fs_context *ctx = fc->fs_private; + int err; + struct socket *csocket; + struct sockaddr_vm addr_vm = { 0 }; + struct p9_fd_opts opts; + unsigned int cid; + + /* opts are already parsed in context */ + opts = ctx->fd_opts; + + if (!addr) + return -EINVAL; + + err = kstrtouint(addr, 10, &cid); + if (err < 0) { + pr_err("%s (%d): invalid CID: %s\n", + __func__, task_pid_nr(current), addr); + return err; + } + + csocket = NULL; + + client->trans_opts.vsock.port = opts.port; + err = __sock_create(current->nsproxy->net_ns, AF_VSOCK, + SOCK_STREAM, 0, &csocket, 1); + if (err) { + pr_err("%s (%d): problem creating socket\n", + __func__, task_pid_nr(current)); + return err; + } + + addr_vm.svm_family = AF_VSOCK; + addr_vm.svm_port = opts.port; + addr_vm.svm_cid = cid; + + err = READ_ONCE(csocket->ops)->connect(csocket, + (struct sockaddr_unsized *)&addr_vm, + sizeof(addr_vm), 0); + if (err < 0) { + pr_err("%s (%d): problem connecting socket to %s:%u\n", + __func__, task_pid_nr(current), addr, opts.port); + sock_release(csocket); + return err; + } + + return p9_socket_open(client, csocket); +} +#endif /* CONFIG_NET_9P_VSOCK */ + static int p9_fd_create(struct p9_client *client, struct fs_context *fc) { @@ -1038,6 +1104,23 @@ static struct p9_trans_module p9_fd_trans = { }; MODULE_ALIAS_9P("fd"); +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) +static struct p9_trans_module p9_vsock_trans = { + .name = "vsock", + .maxsize = MAX_SOCK_BUF, + .def = false, + .supports_vmalloc = true, + .create = p9_fd_create_vsock, + .close = p9_fd_close, + .request = p9_fd_request, + .cancel = p9_fd_cancel, + .cancelled = p9_fd_cancelled, + .show_options = p9_fd_show_options, + .owner = THIS_MODULE, +}; +MODULE_ALIAS_9P("vsock"); +#endif + /** * p9_poll_workfn - poll worker thread * @work: work queue @@ -1075,6 +1158,9 @@ static int __init p9_trans_fd_init(void) v9fs_register_trans(&p9_tcp_trans); v9fs_register_trans(&p9_unix_trans); v9fs_register_trans(&p9_fd_trans); +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) + v9fs_register_trans(&p9_vsock_trans); +#endif return 0; } @@ -1085,6 +1171,9 @@ static void __exit p9_trans_fd_exit(void) v9fs_unregister_trans(&p9_tcp_trans); v9fs_unregister_trans(&p9_unix_trans); v9fs_unregister_trans(&p9_fd_trans); +#if IS_ENABLED(CONFIG_NET_9P_VSOCK) + v9fs_unregister_trans(&p9_vsock_trans); +#endif } module_init(p9_trans_fd_init); -- 2.47.1