--- configure Mon Feb 19 21:49:15 2007 +++ /home/reddawg/qemu-0.9.0/configure Mon Feb 19 21:00:11 2007 @@ -111,6 +111,7 @@ ;; FreeBSD) bsd="yes" +freebsd="yes" oss="yes" if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then kqemu="yes" @@ -719,6 +720,10 @@ if test "$solaris" = "yes" ; then echo "CONFIG_SOLARIS=yes" >> $config_mak echo "#define HOST_SOLARIS $solarisrev" >> $config_h +fi +if test "$freebsd" = "yes" ; then + echo "CONFIG_FREEBSD=yes" >> $config_mak + echo "#define HOST_FREEBSD 1" >> $config_h fi if test "$gdbstub" = "yes" ; then echo "CONFIG_GDBSTUB=yes" >> $config_mak --- Makefile.target Mon Feb 19 21:49:15 2007 +++ /home/reddawg/qemu-0.9.0/Makefile.target Mon Feb 19 21:07:04 2007 @@ -440,7 +440,11 @@ ifndef CONFIG_DARWIN ifndef CONFIG_WIN32 ifndef CONFIG_SOLARIS +ifndef CONFIG_FREEBSD VL_LIBS=-lutil -lrt +else +VL_LIBS=-lutil +endif endif endif endif --- osdep.c Mon Feb 19 22:01:46 2007 +++ /home/reddawg/qemu-0.9.0/osdep.c Mon Feb 19 21:40:45 2007 @@ -79,7 +79,12 @@ #if defined(USE_KQEMU) +#ifdef HOST_FREEBSD +#include +#include +#else #include +#endif #include #include @@ -102,6 +107,9 @@ #ifdef HOST_SOLARIS tmpdir = "/tmp"; if (statvfs(tmpdir, &stfs) == 0) { +#elif HOST_FREEBSD + tmpdir = "/tmp"; + if (statfs(tmpdir, &stfs) == 0) { #else tmpdir = "/dev/shm"; if (statfs(tmpdir, &stfs) == 0) { --- vl.c Mon Feb 19 22:01:46 2007 +++ /home/reddawg/qemu-0.9.0/vl.c Mon Feb 19 22:10:06 2007 @@ -47,6 +47,9 @@ #ifndef __APPLE__ #include #endif +#ifdef HOST_FREEBSD +#include +#endif #else #ifndef __sun__ #include @@ -3171,6 +3174,34 @@ #endif /* CONFIG_SLIRP */ +#ifdef HOST_FREEBSD + +#define LOAD_QUIETLY 1 +#define LOAD_VERBOSLY 2 + +/* This function is used to load needed kernel modules for tap */ +int loadmodules(int how, const char *module, ...) { + int loaded = 0; + va_list ap; + + va_start(ap, module); +#ifndef NO_MODULES + while (module != NULL) { + if (modfind(module) == -1) { + if (kldload(module) == -1) { + if (how == LOAD_VERBOSLY) + fprintf(stderr, "%s: Cannot load module\n", module); + } else + loaded++; + } + module = va_arg(ap, const char *); + } + va_end(ap); +#endif + return loaded; +} +#endif + #if !defined(_WIN32) typedef struct TAPState { @@ -3226,11 +3257,55 @@ char *dev; struct stat s; +#ifdef HOST_FREEBSD + int i, kldtried = 0, enoentcount = 0, err = 0; + char dname[100]; +#ifdef USE_DEVTAP + /* + * 5.x has /dev/tap, but that seems to just blindly increase its + * couter on every open() for some people(??), i.e. on every qemu run. + */ + i = -1; +#else + i = 0; +#endif + for (; i < 10; i++) { + if (i == -1) + strcpy(dname, "/dev/tap"); + else + snprintf(dname, sizeof dname, "%s%d", + "/dev/tap", i); + fd = open(dname, O_RDWR); + if (fd >= 0) + break; + else if (errno == ENXIO || errno == ENOENT) { + if (i == 0 && !kldtried++) { + /* + * Attempt to load the tunnel interface KLD if it isn't loaded + * already. + */ + if (loadmodules(LOAD_VERBOSLY, "if_tap", NULL)) + i = -1; + continue; + } + if (errno != ENOENT || ++enoentcount > 3) { + err = errno; + break; + } + } else + err = errno; + } + if (fd < 0) { + fprintf(stderr, "warning: could not open %s (%s): no virtual network emulation\n", dname, strerror(err)); + return -1; + } +#else fd = open("/dev/tap", O_RDWR); if (fd < 0) { fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n"); return -1; } +#endif fstat(fd, &s); dev = devname(s.st_rdev, S_IFCHR);