diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index bced8c0..ac57c4b 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -37,6 +37,8 @@
#include <linux/un.h>
#include <linux/uaccess.h>
#include <linux/inet.h>
+#include <linux/vmw_vmci_defs.h>
+#include <uapi/linux/vm_sockets.h>
#include <linux/idr.h>
#include <linux/file.h>
#include <linux/parser.h>
@@ -64,6 +66,7 @@ struct p9_fd_opts {
int wfd;
u16 port;
int privport;
+ int vsock;
};
/*
@@ -73,7 +76,7 @@ struct p9_fd_opts {
enum {
/* Options that take integer arguments */
- Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
+ Opt_port, Opt_rfdno, Opt_wfdno, Opt_err, Opt_vsock,
/* Options that take no arguments */
Opt_privport,
};
@@ -83,6 +86,7 @@ static const match_table_t tokens = {
{Opt_rfdno, "rfdno=%u"},
{Opt_wfdno, "wfdno=%u"},
{Opt_privport, "privport"},
+ {Opt_vsock, "vsock=%d"},
{Opt_err, NULL},
};
@@ -735,6 +739,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
opts->rfd = ~0;
opts->wfd = ~0;
opts->privport = 0;
+ opts->vsock = 0;
if (!params)
return 0;
@@ -774,6 +779,9 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
case Opt_privport:
opts->privport = 1;
break;
+ case Opt_vsock:
+ opts->vsock = option;
+ break;
default:
continue;
}
@@ -938,11 +946,27 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
csocket = NULL;
- sin_server.sin_family = AF_INET;
- sin_server.sin_addr.s_addr = in_aton(addr);
- sin_server.sin_port = htons(opts.port);
- err = __sock_create(current->nsproxy->net_ns, PF_INET,
- SOCK_STREAM, IPPROTO_TCP, &csocket, 1);
+ if (opts.vsock == 0) {
+ sin_server.sin_family = AF_INET;
+ sin_server.sin_addr.s_addr = in_aton(addr);
+ sin_server.sin_port = htons(opts.port);
+ err = __sock_create(current->nsproxy->net_ns, PF_INET,
+ SOCK_STREAM, IPPROTO_TCP, &csocket, 1);
+ } else {
+ /*
+ * for vsock, addr is not used, but opts.vsock is the vsock address,
+ * where 2 means host (hypervisor), and other numbers mean the vmci id
+ * in the VMX file of this running VM
+ */
+ struct sockaddr_vm *vsock_server = (struct sockaddr_vm*)&sin_server;
+
+ memset(vsock_server, 0, sizeof(struct sockaddr_vm));
+ vsock_server->svm_family = AF_VSOCK;
+ vsock_server->svm_port = opts.port;
+ vsock_server->svm_cid = opts.vsock;
+ err = __sock_create(read_pnet(¤t->nsproxy->net_ns), PF_VSOCK,
+ SOCK_STREAM, 0, &csocket, 1);
+ }
if (err) {
pr_err("%s (%d): problem creating socket\n",
__func__, task_pid_nr(current));
@@ -963,8 +987,13 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
(struct sockaddr *)&sin_server,
sizeof(struct sockaddr_in), 0);
if (err < 0) {
- pr_err("%s (%d): problem connecting socket to %s\n",
- __func__, task_pid_nr(current), addr);
+ if (opts.vsock) {
+ pr_err("%s (%d): problem connecting vmware vsock addr %d\n",
+ __func__, task_pid_nr(current), opts.vsock);
+ } else {
+ pr_err("%s (%d): problem connecting socket to %s\n",
+ __func__, task_pid_nr(current), addr);
+ }
sock_release(csocket);
return err;
}