Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Oct 2018 08:45:33 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339681 - head/usr.sbin/bhyve
Message-ID:  <201810240845.w9O8jXxs026113@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Wed Oct 24 08:45:33 2018
New Revision: 339681
URL: https://svnweb.freebsd.org/changeset/base/339681

Log:
  Allow the bhyve VNC server to listen on IPv6 for incoming connections.
  
  Alternatively to IPv4 address:port this will allow to listen on IPv6
  link-local (incl. scope), a specific address, or ::.  Addresses have
  to be given in RFC2732 format so that [::]:port parsing will work.
  
  This patch also starts to introduce WITH_INET/INET6_SUPPORT to bhyve.
  
  PR:			232018
  Submitted by:		Dave Rush (northwoodlogic.free gmail.com) (original)
  Reviewed by:		Dave Rush (updated verison)
  MFC after:		3 days

Modified:
  head/usr.sbin/bhyve/Makefile
  head/usr.sbin/bhyve/bhyve.8
  head/usr.sbin/bhyve/pci_fbuf.c
  head/usr.sbin/bhyve/rfb.c

Modified: head/usr.sbin/bhyve/Makefile
==============================================================================
--- head/usr.sbin/bhyve/Makefile	Wed Oct 24 05:15:46 2018	(r339680)
+++ head/usr.sbin/bhyve/Makefile	Wed Oct 24 08:45:33 2018	(r339681)
@@ -73,6 +73,12 @@ SRCS+=	vmm_instruction_emul.c
 
 LIBADD=	vmmapi md pthread z util sbuf cam
 
+.if ${MK_INET_SUPPORT} != "no"
+CFLAGS+=-DINET
+.endif
+.if ${MK_INET6_SUPPORT} != "no"
+CFLAGS+=-DINET6
+.endif
 .if ${MK_OPENSSL} == "no"
 CFLAGS+=-DNO_OPENSSL
 .else

Modified: head/usr.sbin/bhyve/bhyve.8
==============================================================================
--- head/usr.sbin/bhyve/bhyve.8	Wed Oct 24 05:15:46 2018	(r339680)
+++ head/usr.sbin/bhyve/bhyve.8	Wed Oct 24 08:45:33 2018	(r339681)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Aug 23, 2018
+.Dd October 24, 2018
 .Dt BHYVE 8
 .Os
 .Sh NAME
@@ -369,14 +369,15 @@ Framebuffer devices:
 .Bl -tag -width 10n
 .It Oo rfb= Ns Oo Ar IP: Oc Ns Ar port Oc Ns Oo ,w= Ns Ar width Oc Ns Oo ,h= Ns Ar height Oc Ns Oo ,vga= Ns Ar vgaconf Oc Ns Oo Ns ,wait Oc Ns Oo ,password= Ns Ar password Oc
 .Bl -tag -width 8n
-.It Ar IP:port
+.It Ar IPv4:port No or Ar [IPv6%zone]:port
 An
 .Ar IP
 address and a
 .Ar port
 VNC should listen on.
 The default is to listen on localhost IPv4 address and default VNC port 5900.
-Listening on an IPv6 address is not supported.
+An IPv6 address must be enclosed in square brackets and may contain an
+optional zone identifer.
 .It Ar width No and Ar height
 A display resolution, width and height, respectively.
 If not specified, a default resolution of 1024x768 pixels will be used.
@@ -582,6 +583,20 @@ bhyve -c 2 -m 4G -w -H \\
   -s 4,ahci-hd,disk.img \\
   -s 5,virtio-net,tap0 \\
   -s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \\
+  -s 30,xhci,tablet \\
+  -s 31,lpc -l com1,stdio \\
+  -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\
+   uefivm
+.Ed
+.Pp
+Run a UEFI virtual machine with a VNC display that is bound to all IPv6
+addresses on port 5900.
+.Bd -literal -offset indent
+bhyve -c 2 -m 4G -w -H \\
+  -s 0,hostbridge \\
+  -s 4,ahci-hd,disk.img \\
+  -s 5,virtio-net,tap0 \\
+  -s 29,fbuf,tcp=[::]:5900,w=800,h=600 \\
   -s 30,xhci,tablet \\
   -s 31,lpc -l com1,stdio \\
   -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\

Modified: head/usr.sbin/bhyve/pci_fbuf.c
==============================================================================
--- head/usr.sbin/bhyve/pci_fbuf.c	Wed Oct 24 05:15:46 2018	(r339680)
+++ head/usr.sbin/bhyve/pci_fbuf.c	Wed Oct 24 08:45:33 2018	(r339681)
@@ -251,13 +251,33 @@ pci_fbuf_parse_opts(struct pci_fbuf_softc *sc, char *o
 		   xopts, config));
 
 		if (!strcmp(xopts, "tcp") || !strcmp(xopts, "rfb")) {
-			/* parse host-ip:port */
-		        tmpstr = strsep(&config, ":");
-			if (!config)
-				sc->rfb_port = atoi(tmpstr);
-			else {
-				sc->rfb_port = atoi(config);
+			/*
+			 * IPv4 -- host-ip:port
+			 * IPv6 -- [host-ip%zone]:port
+			 * XXX for now port is mandatory.
+			 */
+			tmpstr = strsep(&config, "]");
+			if (config) {
+				if (tmpstr[0] == '[')
+					tmpstr++;
 				sc->rfb_host = tmpstr;
+				if (config[0] == ':')
+					config++;
+				else {
+					pci_fbuf_usage(xopts);
+					ret = -1;
+					goto done;
+				}
+				sc->rfb_port = atoi(config);
+			} else {
+				config = tmpstr;
+				tmpstr = strsep(&config, ":");
+				if (!config)
+					sc->rfb_port = atoi(tmpstr);
+				else {
+					sc->rfb_port = atoi(config);
+					sc->rfb_host = tmpstr;
+				}
 			}
 	        } else if (!strcmp(xopts, "vga")) {
 			if (!strcmp(config, "off")) {

Modified: head/usr.sbin/bhyve/rfb.c
==============================================================================
--- head/usr.sbin/bhyve/rfb.c	Wed Oct 24 05:15:46 2018	(r339680)
+++ head/usr.sbin/bhyve/rfb.c	Wed Oct 24 08:45:33 2018	(r339681)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/cpufunc.h>
 #include <machine/specialreg.h>
 #include <netinet/in.h>
+#include <netdb.h>
 
 #include <assert.h>
 #include <err.h>
@@ -960,8 +961,11 @@ sse42_supported(void)
 int
 rfb_init(char *hostname, int port, int wait, char *password)
 {
+	int e;
+	char servname[6];
 	struct rfb_softc *rc;
-	struct sockaddr_in sin;
+	struct addrinfo *ai;
+	struct addrinfo hints;
 	int on = 1;
 #ifndef WITHOUT_CAPSICUM
 	cap_rights_t rights;
@@ -978,29 +982,43 @@ rfb_init(char *hostname, int port, int wait, char *pas
 
 	rc->password = password;
 
-	rc->sfd = socket(AF_INET, SOCK_STREAM, 0);
+	snprintf(servname, sizeof(servname), "%d", port ? port : 5900);
+
+	if (!hostname || strlen(hostname) == 0)
+#if defined(INET)
+		hostname = "127.0.0.1";
+#elif defined(INET6)
+		hostname = "[::1]";
+#endif
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE;
+
+	if ((e = getaddrinfo(hostname, servname, &hints, &ai)) != 0) {
+		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e));
+		return(-1);
+	}
+
+	rc->sfd = socket(ai->ai_family, ai->ai_socktype, 0);
 	if (rc->sfd < 0) {
 		perror("socket");
+		freeaddrinfo(ai);
 		return (-1);
 	}
 
 	setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
 
-	sin.sin_len = sizeof(sin);
-	sin.sin_family = AF_INET;
-	sin.sin_port = port ? htons(port) : htons(5900);
-	if (hostname && strlen(hostname) > 0)
-		inet_pton(AF_INET, hostname, &(sin.sin_addr));
-	else
-		sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-	if (bind(rc->sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+	if (bind(rc->sfd, ai->ai_addr, ai->ai_addrlen) < 0) {
 		perror("bind");
+		freeaddrinfo(ai);
 		return (-1);
 	}
 
 	if (listen(rc->sfd, 1) < 0) {
 		perror("listen");
+		freeaddrinfo(ai);
 		return (-1);
 	}
 
@@ -1028,5 +1046,6 @@ rfb_init(char *hostname, int port, int wait, char *pas
 		pthread_mutex_unlock(&rc->mtx);
 	}
 
+	freeaddrinfo(ai);
 	return (0);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810240845.w9O8jXxs026113>