patches and low-level development discussion
 help / color / mirror / code / Atom feed
From: Alyssa Ross <hi@alyssa.is>
To: devel@spectrum-os.org
Subject: [DEMO PATCH linux 3/3] usbip: tools: usbip: support vsock(7) connections
Date: Wed, 13 Oct 2021 13:53:13 +0000	[thread overview]
Message-ID: <20211013135313.2494599-4-hi@alyssa.is> (raw)
In-Reply-To: <20211013135313.2494599-1-hi@alyssa.is>

"usbip list" and "usbip attach" can now both be given a "-P vsock" to
tell them to use vsock sockets instead of ip sockets.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
---
 tools/usb/usbip/src/usbip_attach.c  | 25 +++++++++-----
 tools/usb/usbip/src/usbip_list.c    | 43 +++++++++++++++++-------
 tools/usb/usbip/src/usbip_network.c | 51 ++++++++++++++++++++++++++++-
 tools/usb/usbip/src/usbip_network.h |  4 ++-
 4 files changed, 102 insertions(+), 21 deletions(-)

diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c
index b202c7513bc3..74adf9f09d01 100644
--- a/tools/usb/usbip/src/usbip_attach.c
+++ b/tools/usb/usbip/src/usbip_attach.c
@@ -26,10 +26,11 @@
 #include "usbip.h"
 
 static const char usbip_attach_usage_string[] =
-	"usbip attach <args>\n"
-	"    -r, --remote=<host>      The machine with exported USB devices\n"
+	"usbip attach [-P|--proto] <args>\n"
+	"    -P, --proto            Protocol family (ip or vsock)\n"
+	"    -r, --remote=<host>    The machine with exported USB devices\n"
 	"    -b, --busid=<busid>    Busid of the device on <host>\n"
-	"    -d, --device=<devid>    Id of the virtual UDC on <host>\n";
+	"    -d, --device=<devid>   Id of the virtual UDC on <host>\n";
 
 void usbip_attach_usage(void)
 {
@@ -184,20 +185,23 @@ static int get_protocol_family(int fd, char **proto)
 	case AF_INET6:
 		*proto = "ip";
 		return 0;
+	case AF_VSOCK:
+		*proto = "vsock";
+		return 0;
 	}
 	return -1;
 }
 
-static int attach_device(char *host, char *busid)
+static int attach_device(char *proto, char *host, char *busid)
 {
 	int sockfd;
 	int rc;
 	int rhport;
 	char *pf;
 
-	sockfd = usbip_net_tcp_connect(host, usbip_port_string);
+	sockfd = usbip_net_connect(proto, host, usbip_port_string);
 	if (sockfd < 0) {
-		err("tcp connect");
+		err("connect");
 		return -1;
 	}
 
@@ -222,23 +226,28 @@ static int attach_device(char *host, char *busid)
 int usbip_attach(int argc, char *argv[])
 {
 	static const struct option opts[] = {
+		{ "proto", required_argument, NULL, 'P' },
 		{ "remote", required_argument, NULL, 'r' },
 		{ "busid",  required_argument, NULL, 'b' },
 		{ "device",  required_argument, NULL, 'd' },
 		{ NULL, 0,  NULL, 0 }
 	};
+	char *proto = NULL;
 	char *host = NULL;
 	char *busid = NULL;
 	int opt;
 	int ret = -1;
 
 	for (;;) {
-		opt = getopt_long(argc, argv, "d:r:b:", opts, NULL);
+		opt = getopt_long(argc, argv, "P:d:r:b:", opts, NULL);
 
 		if (opt == -1)
 			break;
 
 		switch (opt) {
+		case 'P':
+			proto = optarg;
+			break;
 		case 'r':
 			host = optarg;
 			break;
@@ -254,7 +263,7 @@ int usbip_attach(int argc, char *argv[])
 	if (!host || !busid)
 		goto err_out;
 
-	ret = attach_device(host, busid);
+	ret = attach_device(proto, host, busid);
 	goto out;
 
 err_out:
diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c
index 3d810bcca02f..f479e15f9ae7 100644
--- a/tools/usb/usbip/src/usbip_list.c
+++ b/tools/usb/usbip/src/usbip_list.c
@@ -30,7 +30,8 @@
 #include "usbip.h"
 
 static const char usbip_list_usage_string[] =
-	"usbip list [-p|--parsable] <args>\n"
+	"usbip list [-P|--proto] [-p|--parsable] <args>\n"
+	"    -P, --proto            Protocol family (ip or vsock)\n"
 	"    -p, --parsable         Parsable list format\n"
 	"    -r, --remote=<host>    List the exportable USB devices on <host>\n"
 	"    -l, --local            List the local USB devices\n"
@@ -125,12 +126,12 @@ static int get_exported_devices(char *host, int sockfd)
 	return 0;
 }
 
-static int list_exported_devices(char *host)
+static int list_exported_devices(char *proto, char *host)
 {
 	int rc;
 	int sockfd;
 
-	sockfd = usbip_net_tcp_connect(host, usbip_port_string);
+	sockfd = usbip_net_connect(proto, host, usbip_port_string);
 	if (sockfd < 0) {
 		err("could not connect to %s:%s: %s", host,
 		    usbip_port_string, gai_strerror(sockfd));
@@ -326,44 +327,64 @@ static int list_gadget_devices(bool parsable)
 int usbip_list(int argc, char *argv[])
 {
 	static const struct option opts[] = {
+		{ "proto",    required_argument, NULL, 'P' },
 		{ "parsable", no_argument,       NULL, 'p' },
 		{ "remote",   required_argument, NULL, 'r' },
 		{ "local",    no_argument,       NULL, 'l' },
-		{ "device",    no_argument,       NULL, 'd' },
+		{ "device",   no_argument,       NULL, 'd' },
 		{ NULL,       0,                 NULL,  0  }
 	};
 
 	bool parsable = false;
+	char *proto = NULL, *host = NULL;
 	int opt;
+	int mode = -1;
 	int ret = -1;
 
 	if (usbip_names_init(USBIDS_FILE))
 		err("failed to open %s", USBIDS_FILE);
 
 	for (;;) {
-		opt = getopt_long(argc, argv, "pr:ld", opts, NULL);
+		opt = getopt_long(argc, argv, "P:pr:ld", opts, NULL);
 
 		if (opt == -1)
 			break;
 
 		switch (opt) {
+		case 'P':
+			proto = optarg;
+			break;
 		case 'p':
 			parsable = true;
 			break;
 		case 'r':
-			ret = list_exported_devices(optarg);
-			goto out;
+			host = optarg;
+			/* fall through */
 		case 'l':
-			ret = list_devices(parsable);
-			goto out;
 		case 'd':
-			ret = list_gadget_devices(parsable);
-			goto out;
+			if (mode != -1) {
+				err("-%c and -%c are mutually exclusive", mode, opt);
+				goto out;
+			}
+			mode = opt;
+			break;
 		default:
 			goto err_out;
 		}
 	}
 
+	switch (mode) {
+	case 'r':
+		ret = list_exported_devices(proto, host);
+		goto out;
+	case 'l':
+		ret = list_devices(parsable);
+		goto out;
+	case 'd':
+		ret = list_gadget_devices(parsable);
+		goto out;
+	}
+
 err_out:
 	usbip_list_usage();
 out:
diff --git a/tools/usb/usbip/src/usbip_network.c b/tools/usb/usbip/src/usbip_network.c
index ed4dc8c14269..c096dbb6afb3 100644
--- a/tools/usb/usbip/src/usbip_network.c
+++ b/tools/usb/usbip/src/usbip_network.c
@@ -9,10 +9,14 @@
 #include <string.h>
 
 #include <arpa/inet.h>
+#include <errno.h>
+#include <limits.h>
 #include <netdb.h>
 #include <netinet/tcp.h>
 #include <unistd.h>
 
+#include <linux/vm_sockets.h>
+
 #ifdef HAVE_LIBWRAP
 #include <tcpd.h>
 #endif
@@ -258,7 +262,7 @@ int usbip_net_set_v6only(int sockfd)
 /*
  * IPv6 Ready
  */
-int usbip_net_tcp_connect(char *hostname, char *service)
+int usbip_net_ip_connect(char *hostname, char *service)
 {
 	struct addrinfo hints, *res, *rp;
 	int sockfd;
@@ -301,3 +305,48 @@ int usbip_net_tcp_connect(char *hostname, char *service)
 
 	return sockfd;
 }
+
+int usbip_net_vsock_connect(char *cid_s, char *port_s)
+{
+	char *cid_end, *port_end;
+	int sockfd;
+	unsigned long cid, port;
+	struct sockaddr_vm addr = { 0 };
+	socklen_t addrlen = sizeof addr;
+
+	errno = 0;
+	cid = strtoul(cid_s, &cid_end, 0);
+	port = strtoul(port_s, &port_end, 0);
+	if (*cid_end || *port_end) {
+		errno = EINVAL;
+		return EAI_SYSTEM;
+	}
+	if (errno)
+		return EAI_SYSTEM;
+	if (cid > UINT_MAX || port > UINT_MAX) {
+		errno = ERANGE;
+		return EAI_SYSTEM;
+	}
+
+	addr.svm_family = AF_VSOCK;
+	addr.svm_port = port;
+	addr.svm_cid = cid;
+
+	sockfd = socket(AF_VSOCK, SOCK_STREAM, 0);
+	if (sockfd == -1)
+		return EAI_SYSTEM;
+	if (connect(sockfd, (struct sockaddr *)&addr, addrlen) == -1)
+		return EAI_SYSTEM;
+	return sockfd;
+}
+
+int usbip_net_connect(char *proto, char *host, char *service)
+{
+	if (!proto || !strcmp(proto, "ip"))
+		return usbip_net_ip_connect(host, service);
+	if (!strcmp(proto, "vsock"))
+		return usbip_net_vsock_connect(host, service);
+
+	errno = EPROTONOSUPPORT;
+	return EAI_SYSTEM;
+}
diff --git a/tools/usb/usbip/src/usbip_network.h b/tools/usb/usbip/src/usbip_network.h
index 83b4c5344f72..fc2579525bc3 100644
--- a/tools/usb/usbip/src/usbip_network.h
+++ b/tools/usb/usbip/src/usbip_network.h
@@ -173,6 +173,8 @@ int usbip_net_set_reuseaddr(int sockfd);
 int usbip_net_set_nodelay(int sockfd);
 int usbip_net_set_keepalive(int sockfd);
 int usbip_net_set_v6only(int sockfd);
-int usbip_net_tcp_connect(char *hostname, char *port);
+int usbip_net_ip_connect(char *hostname, char *port);
+int usbip_net_vsock_connect(char *cid, char *port);
+int usbip_net_connect(char *proto, char *host, char *port);
 
 #endif /* __USBIP_NETWORK_H */
-- 
2.32.0


      parent reply	other threads:[~2021-10-13 13:54 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-13 13:53 [DEMO PATCH linux 0/3] usbip: tools: support USB over vsock(7) Alyssa Ross
2021-10-13 13:53 ` [DEMO PATCH linux 1/3] usbip: tools: in.usbipd: add Alyssa Ross
2021-10-13 13:53 ` [DEMO PATCH linux 2/3] usbip: tools: usbip: record protocol Alyssa Ross
2021-10-13 13:53 ` Alyssa Ross [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211013135313.2494599-4-hi@alyssa.is \
    --to=hi@alyssa.is \
    --cc=devel@spectrum-os.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://spectrum-os.org/git/crosvm
	https://spectrum-os.org/git/doc
	https://spectrum-os.org/git/mktuntap
	https://spectrum-os.org/git/nixpkgs
	https://spectrum-os.org/git/spectrum
	https://spectrum-os.org/git/ucspi-vsock
	https://spectrum-os.org/git/www

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).