qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] native vde support
@ 2008-07-01 20:11 Luca Bigliardi
  2008-07-16 18:24 ` Erik de Castro Lopo
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Luca Bigliardi @ 2008-07-01 20:11 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2444 bytes --]

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/

[-- Attachment #2: qemu_vde_0.1.diff --]
[-- Type: text/x-diff, Size: 7868 bytes --]

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 <libvdeplug.h>
+#endif
+
 #ifdef _WIN32
 #include <malloc.h>
 #include <sys/timeb.h>
@@ -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 <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
+    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

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-07-23 22:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-01 20:11 [Qemu-devel] [PATCH] native vde support Luca Bigliardi
2008-07-16 18:24 ` Erik de Castro Lopo
2008-07-19  6:39 ` Erik de Castro Lopo
2008-07-19 10:00 ` Thiemo Seufer
2008-07-19 10:39   ` Erik de Castro Lopo
2008-07-23 18:15   ` Anthony Liguori
2008-07-23 22:50     ` Erik de Castro Lopo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).