Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Nov 2001 20:54:24 +0000
From:      Ian Dowse <iedowse@maths.tcd.ie>
To:        "Richard E. Hawkins" <dochawk@psu.edu>
Cc:        freebsd-questions@FreeBSD.ORG, freebsd-emulation@FreeBSD.ORG, marcel@FreeBSD.ORG, "Vladimir N. Silyaev" <vsilyaev@mindspring.com>
Subject:   Could not get address for /dev/vmnet1: Invalid argument
Message-ID:   <200111152054.aa71745@salmon.maths.tcd.ie>
In-Reply-To: Your message of "Wed, 14 Nov 2001 20:32:28 GMT." <200111142032.aa79929@salmon.maths.tcd.ie> 

next in thread | previous in thread | raw e-mail | index | archive | help
In message <200111142032.aa79929@salmon.maths.tcd.ie>, Ian Dowse writes:
>A ktrace of vmware as it fails shows that it opens /compat/linux/dev/vmnet1
>and attempts to do a SIOCGIFADDR ioctl on that descriptor (i.e a
>socket ioctl on a character device descriptor) but gets an EINVAL
>return. I haven't figured out for sure if it uses the linux (0x8915)
>or freebsd number for the ioctl.

Ok, I looked into this some more and I have some patches that work
around the issue. The real problem is that it is utterly bogus on
FreeBSD for if_tap/vmnet to use SIOCGIFADDR and SIOCGIFFLAGS the
way it does. These ioctls are supposed to take `struct ifreq'
arguments (as encoded in the length bits) but if_tap/vmnet uses
them for something completely different. I think it's ok for this
reuse to occur on Linux though, so these ioctls on /dev/vmnetX
should really be translated into some if_tap-specific ioctls by
the linux emulation code.

The workaround patch is in two bits: one bit limits the linux
emulator to only touching socket ioctls if the descriptor is
a socket; the other adds an ioctl translator for vmnet ioctls
to the vmmon module. Note that this doesn't do things the right
way (which would be to fix if_tap), but it does seem to work.
VMware also performs ioctls 0x89f2 and 0x89f6 on /dev/vmnet1;
I don't know what these are supposed to do.

Ian

Patch 1, apply in src/sys/compat/linux/, then rebuild kernel or
just linux module.

Index: linux_ioctl.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/compat/linux/linux_ioctl.c,v
retrieving revision 1.55.2.5
diff -u -r1.55.2.5 linux_ioctl.c
--- linux_ioctl.c	2001/11/05 19:08:22	1.55.2.5
+++ linux_ioctl.c	2001/11/15 18:27:31
@@ -1508,8 +1508,14 @@
 {
 	char lifname[LINUX_IFNAMSIZ], ifname[IFNAMSIZ];
 	struct ifnet *ifp;
+	struct file *fp;
 	int error;
 
+	if (args->fd < p->p_fd->fd_nfiles && 
+	    (fp = p->p_fd->fd_ofiles[args->fd]) != NULL &&
+	    fp->f_type != DTYPE_SOCKET)
+		return (ENOIOCTL);
+
 	KASSERT(LINUX_IFNAMSIZ == IFNAMSIZ,
 	    (__FUNCTION__ "(): LINUX_IFNAMSIZ != IFNAMSIZ"));
 	
@@ -1700,7 +1706,7 @@
 	}
 	if (type == DTYPE_SOCKET)
 		return (linux_ioctl_socket(p, args));
-	return (ioctl(p, (struct ioctl_args *)args));
+	return (ENOIOCTL);
 }
 
 /*


Patch 2, apply in vmware2/work/vmware-distrib/vmmon-only/freebsd, then
from vmware2/work/vmware-distrib run "make" then "make install".

--- linux_emu.c.orig	Thu Nov 15 20:16:07 2001
+++ linux_emu.c	Thu Nov 15 20:15:27 2001
@@ -37,6 +37,11 @@
 #include <sys/cdio.h>
 #include <sys/file.h>
 #include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/stat.h>
+
+#include <net/if.h>
 
 #include <machine/ioctl_fd.h>
 
@@ -541,3 +546,41 @@
 #undef DEB    
 }
 
+/* vmnet ioctls */
+LINUX_IOCTL_SET(vmnet, 0x8900, 0x89ff);
+
+#define LINUX_SIOCGIFFLAGS	0x8913
+#define LINUX_SIOCGIFADDR	0x8915
+
+#define VMNET_MAJOR		149
+
+static int
+linux_ioctl_vmnet(struct proc *p, struct linux_ioctl_args *args)
+{
+	struct stat sb;
+	struct filedesc *fdp;
+	struct file *fp;
+	int error;
+	short flags;
+
+	/* Check if this looks like a vmnet device. */
+        if (args->fd >= p->p_fd->fd_nfiles ||
+            (fp = p->p_fd->fd_ofiles[args->fd]) == NULL ||
+	    fp->f_type != DTYPE_VNODE || fo_stat(fp, &sb, p) != 0 ||
+	    (sb.st_mode & S_IFMT) != S_IFCHR ||
+	    ((sb.st_rdev >> 8) & 0xff) != VMNET_MAJOR)
+		return (ENOIOCTL);
+
+	switch (args->cmd & 0xffff) {
+	case LINUX_SIOCGIFADDR:
+		args->cmd = SIOCGIFADDR;
+		return ioctl(p, (struct ioctl_args *)args);
+	case LINUX_SIOCGIFFLAGS:
+		args->cmd = SIOCGIFFLAGS;
+		/* XXX, should translate flags. */
+		return ioctl(p, (struct ioctl_args *)args);
+	default:
+		printf("linux_ioctl_vmnet unknown ioctl %08x\n", args->cmd);
+	}
+	return (ENOIOCTL);
+}



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




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