aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--Makefile.target2
-rwxr-xr-xconfigure28
-rw-r--r--qemu-doc.texi15
-rw-r--r--vl.c101
5 files changed, 147 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 3756da89e7..5367cc0449 100644
--- a/Makefile
+++ b/Makefile
@@ -133,6 +133,8 @@ tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
endif
+LIBS+=$(VDE_LIBS)
+
cocoa.o: cocoa.m
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
diff --git a/Makefile.target b/Makefile.target
index 73adbb15e0..10f3cb23ac 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -655,7 +655,7 @@ main.o: CFLAGS+=-p
endif
$(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a
- $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS)
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS)
endif # !CONFIG_USER_ONLY
diff --git a/configure b/configure
index 51be6e7ff4..f9707cdc70 100755
--- a/configure
+++ b/configure
@@ -89,6 +89,7 @@ mingw32="no"
EXESUF=""
gdbstub="yes"
slirp="yes"
+vde="no"
fmod_lib=""
fmod_inc=""
vnc_tls="yes"
@@ -280,6 +281,8 @@ for opt do
;;
--disable-slirp) slirp="no"
;;
+ --enable-vde) vde="yes"
+ ;;
--disable-kqemu) kqemu="no"
;;
--disable-brlapi) brlapi="no"
@@ -432,6 +435,7 @@ echo " --fmod-lib path to FMOD library"
echo " --fmod-inc path to FMOD includes"
echo " --enable-uname-release=R Return R for uname -r in usermode emulation"
echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9"
+echo " --enable-vde enable support for vde network [$vde]"
echo ""
echo "NOTE: The object files are built at the place where configure is launched"
exit 1
@@ -722,6 +726,24 @@ if test "$vnc_tls" = "yes" ; then
fi
##########################################
+# vde libraries probe
+if test "$vde" = "yes" ; then
+ cat > $TMPC << EOF
+#include <libvdeplug.h>
+int main(void) { struct vde_open_args a = {0, 0, 0} ; return 0;}
+EOF
+ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+ :
+ else
+ echo
+ echo "Error: VDE check failed"
+ echo "Make sure to have the VDE libs and headers installed."
+ echo
+ exit 1
+ fi
+fi
+
+##########################################
# Sound support libraries probe
audio_drv_probe()
@@ -874,6 +896,7 @@ echo "Documentation $build_docs"
[ ! -z "$uname_release" ] && \
echo "uname -r $uname_release"
echo "NPTL support $nptl"
+echo "vde support $vde"
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -1038,6 +1061,11 @@ if test "$slirp" = "yes" ; then
echo "CONFIG_SLIRP=yes" >> $config_mak
echo "#define CONFIG_SLIRP 1" >> $config_h
fi
+if test "$vde" = "yes" ; then
+ echo "CONFIG_VDE=yes" >> $config_mak
+ echo "#define CONFIG_VDE 1" >> $config_h
+ echo "VDE_LIBS=-lvdeplug" >> $config_mak
+fi
for card in $audio_card_list; do
def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'`
echo "$def=yes" >> $config_mak
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 78ba5878f9..f093915852 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -675,6 +675,21 @@ qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \
/path/to/linux ubd0=/path/to/root_fs eth0=mcast
@end example
+@item -net vde[,vlan=@var{n}][,sock=@var{socketpath}][,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}]
+Connect VLAN @var{n} to PORT @var{n} of a vde switch running on host and
+listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname}
+and MODE @var{octalmode} to change default ownership and permissions for
+communication port. This option is available only if QEMU has been compiled
+with vde support enabled.
+
+Example:
+@example
+# launch vde switch
+vde_switch -F -sock /tmp/myswitch
+# launch QEMU instance
+qemu linux.img -net nic -net vde,sock=/tmp/myswitch
+@end example
+
@item -net none
Indicate that no network devices should be configured. It is used to
override the default configuration (@option{-net nic -net user}) which
diff --git a/vl.c b/vl.c
index e7a0645888..f057a5e6b5 100644
--- a/vl.c
+++ b/vl.c
@@ -106,6 +106,10 @@ int inet_aton(const char *cp, struct in_addr *ia);
#include "libslirp.h"
#endif
+#if defined(CONFIG_VDE)
+#include <libvdeplug.h>
+#endif
+
#ifdef _WIN32
#include <malloc.h>
#include <sys/timeb.h>
@@ -4418,6 +4422,66 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
#endif /* !_WIN32 */
+#if defined(CONFIG_VDE)
+typedef struct VDEState {
+ VLANClientState *vc;
+ VDECONN *vde;
+} VDEState;
+
+static void vde_to_qemu(void *opaque)
+{
+ VDEState *s = opaque;
+ uint8_t buf[4096];
+ int size;
+
+ size = vde_recv(s->vde, buf, sizeof(buf), 0);
+ if (size > 0) {
+ qemu_send_packet(s->vc, buf, size);
+ }
+}
+
+static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
+{
+ VDEState *s = opaque;
+ int ret;
+ for(;;) {
+ ret = vde_send(s->vde, buf, size, 0);
+ if (ret < 0 && errno == EINTR) {
+ } else {
+ break;
+ }
+ }
+}
+
+static int net_vde_init(VLANState *vlan, const char *sock, int port,
+ const char *group, int mode)
+{
+ VDEState *s;
+ char *init_group = strlen(group) ? (char *)group : NULL;
+ char *init_sock = strlen(sock) ? (char *)sock : NULL;
+
+ struct vde_open_args args = {
+ .port = port,
+ .group = init_group,
+ .mode = mode,
+ };
+
+ s = qemu_mallocz(sizeof(VDEState));
+ if (!s)
+ return -1;
+ s->vde = vde_open(init_sock, "QEMU", &args);
+ if (!s->vde){
+ free(s);
+ return -1;
+ }
+ s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s);
+ qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
+ snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d",
+ sock, vde_datafd(s->vde));
+ return 0;
+}
+#endif
+
/* network connection */
typedef struct NetSocketState {
VLANClientState *vc;
@@ -5047,6 +5111,30 @@ static int net_client_init(const char *str)
}
vlan->nb_host_devs++;
} else
+#ifdef CONFIG_VDE
+ if (!strcmp(device, "vde")) {
+ char vde_sock[1024], vde_group[512];
+ int vde_port, vde_mode;
+ vlan->nb_host_devs++;
+ if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
+ vde_sock[0] = '\0';
+ }
+ if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
+ vde_port = strtol(buf, NULL, 10);
+ } else {
+ vde_port = 0;
+ }
+ if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
+ vde_group[0] = '\0';
+ }
+ if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
+ vde_mode = strtol(buf, NULL, 8);
+ } else {
+ vde_mode = 0700;
+ }
+ ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
+ } else
+#endif
{
fprintf(stderr, "Unknown network device: %s\n", device);
return -1;
@@ -7418,6 +7506,13 @@ static void help(int exitcode)
" connect the vlan 'n' to another VLAN using a socket connection\n"
"-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
" connect the vlan 'n' to multicast maddr and port\n"
+#ifdef CONFIG_VDE
+ "-net vde[,vlan=n][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
+ " connect the vlan 'n' to port 'n' of a vde switch running\n"
+ " on host and listening for incoming connections on 'socketpath'.\n"
+ " Use group 'groupname' and mode 'octalmode' to change default\n"
+ " ownership and permissions for communication port.\n"
+#endif
"-net none use it alone to have zero network devices; if no -net option\n"
" is provided, the default is '-net nic -net user'\n"
"\n"
@@ -8907,6 +9002,12 @@ int main(int argc, char **argv)
s->down_script[0])
launch_script(s->down_script, ifname, s->fd);
}
+#if defined(CONFIG_VDE)
+ if (vc->fd_read == vde_from_qemu) {
+ VDEState *s = vc->opaque;
+ vde_close(s->vde);
+ }
+#endif
}
}
#endif