From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KDmBx-0008Be-GI for qemu-devel@nongnu.org; Tue, 01 Jul 2008 16:11:09 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KDmBw-0008AZ-6W for qemu-devel@nongnu.org; Tue, 01 Jul 2008 16:11:09 -0400 Received: from [199.232.76.173] (port=55548 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KDmBw-0008AT-2x for qemu-devel@nongnu.org; Tue, 01 Jul 2008 16:11:08 -0400 Received: from bigben2.bytemark.co.uk ([80.68.81.132]:48176) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KDmBw-0005LW-6X for qemu-devel@nongnu.org; Tue, 01 Jul 2008 16:11:08 -0400 Received: from esaurito.net ([80.68.93.96]) by bigben2.bytemark.co.uk with esmtp (Exim 4.63) (envelope-from ) id 1KDmBr-0005gc-HH for qemu-devel@nongnu.org; Tue, 01 Jul 2008 20:11:03 +0000 Received: from localhost (localhost [127.0.0.1]) by esaurito.net (Postfix) with ESMTP id B6FED413E6 for ; Tue, 1 Jul 2008 22:11:02 +0200 (CEST) Received: from pintsize (unknown [80.169.137.165]) by esaurito.net (Postfix) with ESMTP id BEE51413DF for ; Tue, 1 Jul 2008 22:10:59 +0200 (CEST) Date: Tue, 1 Jul 2008 21:11:31 +0100 From: Luca Bigliardi Message-ID: <20080701201131.GA14931@pintsize> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="J2SCkAp4GZ/dPZZf" Content-Disposition: inline Subject: [Qemu-devel] [PATCH] native vde support Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --J2SCkAp4GZ/dPZZf Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi! The patch I'm proposing here adds native support to Virtual Distributed Ethernet using libvdeplug. A small example: - patch latest svn with the attached patch - configure qemu to use vde support (disabled by default) using "./configure --enable-vde" - start a vde switch vde_switch -F -sock /tmp/my_qemu_test - start qemu (full syntax explanation is in the qemu-doc and appears into qemu online help if it's compiled with vde support) qemu -net nic -net vde,sock=/tmp/my_qemu_test linux-0.2.img What is VDE? Virtual Distributed Ethernet is a virtual network that can be spawned over a set of physical computer over the Internet and that can be shared between physical hosts and various kinds of virtual machines. vde_switch, core app of VDE framework, is an evolution of uml_switch. The project was originally written by Renzo Davoli and now is maintained and developed by Virtualsquare Team (which I'm part of). For more information and simple examples of vde usage visit: http://wiki.virtualsquare.org/index.php/VDE and http://wiki.virtualsquare.org/index.php/VDE_Basic_Networking Why add native support to VDE? Nowadays a number of qemu instances already use vde networking, to give you an idea simply search "qemu vde" on google, or think that vde is the recommended networking tool for qemu in major distributions as debian or ubuntu (and maybe others..), so in my opinion native vde networking will be widely used! What's wrong with the present solution? What are you doing with your patch? Unfortunately at the moment qemu is connected to a vde_switch through a dirty hack called 'vdeq' which places itself in the middle between the two applications. The life of a vdeq is quite simple: - do some tricky syntax parsing and mangling - connect to vde_switch using libvdeplug - open socketpair - fork qemu giving him one end of socketpair - enter a loop to forward data between vde_switch and qemu - when qemu exits close the connection with vde_switch This is of course far from being optimal for obvious reasons, so with my patch I simply put into qemu the part of vdeq which connects/disconnects to vde_switch and send/receive data to it. Please tell me what do you think about this idea and the attached patch, thank you! Regards, Luca -- Beware of programmers who carry screwdrivers. -- Leonard Brandwein http://shammash.homelinux.org/ - http://www.artha.org/ - http://www.yue.it/ --J2SCkAp4GZ/dPZZf Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="qemu_vde_0.1.diff" Index: Makefile.target =================================================================== --- Makefile.target (revision 4815) +++ Makefile.target (working copy) @@ -652,7 +652,7 @@ 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 Index: vl.c =================================================================== --- vl.c (revision 4815) +++ vl.c (working copy) @@ -106,6 +106,10 @@ #include "libslirp.h" #endif +#if defined(CONFIG_VDE) +#include +#endif + #ifdef _WIN32 #include #include @@ -4404,6 +4408,66 @@ #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; @@ -5033,6 +5097,30 @@ } 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; @@ -7389,6 +7477,13 @@ " 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" @@ -8868,6 +8963,12 @@ 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 Index: Makefile =================================================================== --- Makefile (revision 4815) +++ Makefile (working copy) @@ -127,6 +127,10 @@ OBJS+=$(addprefix slirp/, $(SLIRP_OBJS)) endif +ifdef CONFIG_VDE +LIBS+=-lvdeplug +endif + cocoa.o: cocoa.m $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< Index: qemu-doc.texi =================================================================== --- qemu-doc.texi (revision 4815) +++ qemu-doc.texi (working copy) @@ -672,6 +672,21 @@ /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 Index: configure =================================================================== --- configure (revision 4815) +++ configure (working copy) @@ -89,6 +89,7 @@ EXESUF="" gdbstub="yes" slirp="yes" +vde="no" fmod_lib="" fmod_inc="" vnc_tls="yes" @@ -280,6 +281,8 @@ ;; --disable-slirp) slirp="no" ;; + --enable-vde) vde="yes" + ;; --disable-kqemu) kqemu="no" ;; --disable-brlapi) brlapi="no" @@ -432,6 +435,7 @@ 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,19 @@ fi ########################################## +# vde libraries probe +if test "$vde" = "yes" ; then + vde=no + cat > $TMPC << EOF +#include +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 + vde=yes + fi +fi + +########################################## # Sound support libraries probe audio_drv_probe() @@ -868,6 +885,7 @@ [ ! -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" @@ -1032,6 +1050,11 @@ 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 --J2SCkAp4GZ/dPZZf--