Commit 8a16d273887cce159fd1c30ee820ec30ef93e661
1 parent
c4d10628
Add Virtual Distributed Ethernet native support, by Luca Bigliardi.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4896 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
147 additions
and
1 deletions
Makefile
| @@ -133,6 +133,8 @@ tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o | @@ -133,6 +133,8 @@ tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o | ||
| 133 | OBJS+=$(addprefix slirp/, $(SLIRP_OBJS)) | 133 | OBJS+=$(addprefix slirp/, $(SLIRP_OBJS)) |
| 134 | endif | 134 | endif |
| 135 | 135 | ||
| 136 | +LIBS+=$(VDE_LIBS) | ||
| 137 | + | ||
| 136 | cocoa.o: cocoa.m | 138 | cocoa.o: cocoa.m |
| 137 | $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< | 139 | $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< |
| 138 | 140 |
Makefile.target
| @@ -655,7 +655,7 @@ main.o: CFLAGS+=-p | @@ -655,7 +655,7 @@ main.o: CFLAGS+=-p | ||
| 655 | endif | 655 | endif |
| 656 | 656 | ||
| 657 | $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a | 657 | $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a |
| 658 | - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) | 658 | + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS) |
| 659 | 659 | ||
| 660 | endif # !CONFIG_USER_ONLY | 660 | endif # !CONFIG_USER_ONLY |
| 661 | 661 |
configure
| @@ -89,6 +89,7 @@ mingw32="no" | @@ -89,6 +89,7 @@ mingw32="no" | ||
| 89 | EXESUF="" | 89 | EXESUF="" |
| 90 | gdbstub="yes" | 90 | gdbstub="yes" |
| 91 | slirp="yes" | 91 | slirp="yes" |
| 92 | +vde="no" | ||
| 92 | fmod_lib="" | 93 | fmod_lib="" |
| 93 | fmod_inc="" | 94 | fmod_inc="" |
| 94 | vnc_tls="yes" | 95 | vnc_tls="yes" |
| @@ -280,6 +281,8 @@ for opt do | @@ -280,6 +281,8 @@ for opt do | ||
| 280 | ;; | 281 | ;; |
| 281 | --disable-slirp) slirp="no" | 282 | --disable-slirp) slirp="no" |
| 282 | ;; | 283 | ;; |
| 284 | + --enable-vde) vde="yes" | ||
| 285 | + ;; | ||
| 283 | --disable-kqemu) kqemu="no" | 286 | --disable-kqemu) kqemu="no" |
| 284 | ;; | 287 | ;; |
| 285 | --disable-brlapi) brlapi="no" | 288 | --disable-brlapi) brlapi="no" |
| @@ -432,6 +435,7 @@ echo " --fmod-lib path to FMOD library" | @@ -432,6 +435,7 @@ echo " --fmod-lib path to FMOD library" | ||
| 432 | echo " --fmod-inc path to FMOD includes" | 435 | echo " --fmod-inc path to FMOD includes" |
| 433 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" | 436 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" |
| 434 | echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9" | 437 | echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9" |
| 438 | +echo " --enable-vde enable support for vde network [$vde]" | ||
| 435 | echo "" | 439 | echo "" |
| 436 | echo "NOTE: The object files are built at the place where configure is launched" | 440 | echo "NOTE: The object files are built at the place where configure is launched" |
| 437 | exit 1 | 441 | exit 1 |
| @@ -722,6 +726,24 @@ if test "$vnc_tls" = "yes" ; then | @@ -722,6 +726,24 @@ if test "$vnc_tls" = "yes" ; then | ||
| 722 | fi | 726 | fi |
| 723 | 727 | ||
| 724 | ########################################## | 728 | ########################################## |
| 729 | +# vde libraries probe | ||
| 730 | +if test "$vde" = "yes" ; then | ||
| 731 | + cat > $TMPC << EOF | ||
| 732 | +#include <libvdeplug.h> | ||
| 733 | +int main(void) { struct vde_open_args a = {0, 0, 0} ; return 0;} | ||
| 734 | +EOF | ||
| 735 | + if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then | ||
| 736 | + : | ||
| 737 | + else | ||
| 738 | + echo | ||
| 739 | + echo "Error: VDE check failed" | ||
| 740 | + echo "Make sure to have the VDE libs and headers installed." | ||
| 741 | + echo | ||
| 742 | + exit 1 | ||
| 743 | + fi | ||
| 744 | +fi | ||
| 745 | + | ||
| 746 | +########################################## | ||
| 725 | # Sound support libraries probe | 747 | # Sound support libraries probe |
| 726 | 748 | ||
| 727 | audio_drv_probe() | 749 | audio_drv_probe() |
| @@ -874,6 +896,7 @@ echo "Documentation $build_docs" | @@ -874,6 +896,7 @@ echo "Documentation $build_docs" | ||
| 874 | [ ! -z "$uname_release" ] && \ | 896 | [ ! -z "$uname_release" ] && \ |
| 875 | echo "uname -r $uname_release" | 897 | echo "uname -r $uname_release" |
| 876 | echo "NPTL support $nptl" | 898 | echo "NPTL support $nptl" |
| 899 | +echo "vde support $vde" | ||
| 877 | 900 | ||
| 878 | if test $sdl_too_old = "yes"; then | 901 | if test $sdl_too_old = "yes"; then |
| 879 | echo "-> Your SDL version is too old - please upgrade to have SDL support" | 902 | echo "-> Your SDL version is too old - please upgrade to have SDL support" |
| @@ -1038,6 +1061,11 @@ if test "$slirp" = "yes" ; then | @@ -1038,6 +1061,11 @@ if test "$slirp" = "yes" ; then | ||
| 1038 | echo "CONFIG_SLIRP=yes" >> $config_mak | 1061 | echo "CONFIG_SLIRP=yes" >> $config_mak |
| 1039 | echo "#define CONFIG_SLIRP 1" >> $config_h | 1062 | echo "#define CONFIG_SLIRP 1" >> $config_h |
| 1040 | fi | 1063 | fi |
| 1064 | +if test "$vde" = "yes" ; then | ||
| 1065 | + echo "CONFIG_VDE=yes" >> $config_mak | ||
| 1066 | + echo "#define CONFIG_VDE 1" >> $config_h | ||
| 1067 | + echo "VDE_LIBS=-lvdeplug" >> $config_mak | ||
| 1068 | +fi | ||
| 1041 | for card in $audio_card_list; do | 1069 | for card in $audio_card_list; do |
| 1042 | def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'` | 1070 | def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'` |
| 1043 | echo "$def=yes" >> $config_mak | 1071 | echo "$def=yes" >> $config_mak |
qemu-doc.texi
| @@ -675,6 +675,21 @@ qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \ | @@ -675,6 +675,21 @@ qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \ | ||
| 675 | /path/to/linux ubd0=/path/to/root_fs eth0=mcast | 675 | /path/to/linux ubd0=/path/to/root_fs eth0=mcast |
| 676 | @end example | 676 | @end example |
| 677 | 677 | ||
| 678 | +@item -net vde[,vlan=@var{n}][,sock=@var{socketpath}][,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}] | ||
| 679 | +Connect VLAN @var{n} to PORT @var{n} of a vde switch running on host and | ||
| 680 | +listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname} | ||
| 681 | +and MODE @var{octalmode} to change default ownership and permissions for | ||
| 682 | +communication port. This option is available only if QEMU has been compiled | ||
| 683 | +with vde support enabled. | ||
| 684 | + | ||
| 685 | +Example: | ||
| 686 | +@example | ||
| 687 | +# launch vde switch | ||
| 688 | +vde_switch -F -sock /tmp/myswitch | ||
| 689 | +# launch QEMU instance | ||
| 690 | +qemu linux.img -net nic -net vde,sock=/tmp/myswitch | ||
| 691 | +@end example | ||
| 692 | + | ||
| 678 | @item -net none | 693 | @item -net none |
| 679 | Indicate that no network devices should be configured. It is used to | 694 | Indicate that no network devices should be configured. It is used to |
| 680 | override the default configuration (@option{-net nic -net user}) which | 695 | override the default configuration (@option{-net nic -net user}) which |
vl.c
| @@ -106,6 +106,10 @@ int inet_aton(const char *cp, struct in_addr *ia); | @@ -106,6 +106,10 @@ int inet_aton(const char *cp, struct in_addr *ia); | ||
| 106 | #include "libslirp.h" | 106 | #include "libslirp.h" |
| 107 | #endif | 107 | #endif |
| 108 | 108 | ||
| 109 | +#if defined(CONFIG_VDE) | ||
| 110 | +#include <libvdeplug.h> | ||
| 111 | +#endif | ||
| 112 | + | ||
| 109 | #ifdef _WIN32 | 113 | #ifdef _WIN32 |
| 110 | #include <malloc.h> | 114 | #include <malloc.h> |
| 111 | #include <sys/timeb.h> | 115 | #include <sys/timeb.h> |
| @@ -4418,6 +4422,66 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, | @@ -4418,6 +4422,66 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, | ||
| 4418 | 4422 | ||
| 4419 | #endif /* !_WIN32 */ | 4423 | #endif /* !_WIN32 */ |
| 4420 | 4424 | ||
| 4425 | +#if defined(CONFIG_VDE) | ||
| 4426 | +typedef struct VDEState { | ||
| 4427 | + VLANClientState *vc; | ||
| 4428 | + VDECONN *vde; | ||
| 4429 | +} VDEState; | ||
| 4430 | + | ||
| 4431 | +static void vde_to_qemu(void *opaque) | ||
| 4432 | +{ | ||
| 4433 | + VDEState *s = opaque; | ||
| 4434 | + uint8_t buf[4096]; | ||
| 4435 | + int size; | ||
| 4436 | + | ||
| 4437 | + size = vde_recv(s->vde, buf, sizeof(buf), 0); | ||
| 4438 | + if (size > 0) { | ||
| 4439 | + qemu_send_packet(s->vc, buf, size); | ||
| 4440 | + } | ||
| 4441 | +} | ||
| 4442 | + | ||
| 4443 | +static void vde_from_qemu(void *opaque, const uint8_t *buf, int size) | ||
| 4444 | +{ | ||
| 4445 | + VDEState *s = opaque; | ||
| 4446 | + int ret; | ||
| 4447 | + for(;;) { | ||
| 4448 | + ret = vde_send(s->vde, buf, size, 0); | ||
| 4449 | + if (ret < 0 && errno == EINTR) { | ||
| 4450 | + } else { | ||
| 4451 | + break; | ||
| 4452 | + } | ||
| 4453 | + } | ||
| 4454 | +} | ||
| 4455 | + | ||
| 4456 | +static int net_vde_init(VLANState *vlan, const char *sock, int port, | ||
| 4457 | + const char *group, int mode) | ||
| 4458 | +{ | ||
| 4459 | + VDEState *s; | ||
| 4460 | + char *init_group = strlen(group) ? (char *)group : NULL; | ||
| 4461 | + char *init_sock = strlen(sock) ? (char *)sock : NULL; | ||
| 4462 | + | ||
| 4463 | + struct vde_open_args args = { | ||
| 4464 | + .port = port, | ||
| 4465 | + .group = init_group, | ||
| 4466 | + .mode = mode, | ||
| 4467 | + }; | ||
| 4468 | + | ||
| 4469 | + s = qemu_mallocz(sizeof(VDEState)); | ||
| 4470 | + if (!s) | ||
| 4471 | + return -1; | ||
| 4472 | + s->vde = vde_open(init_sock, "QEMU", &args); | ||
| 4473 | + if (!s->vde){ | ||
| 4474 | + free(s); | ||
| 4475 | + return -1; | ||
| 4476 | + } | ||
| 4477 | + s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s); | ||
| 4478 | + qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s); | ||
| 4479 | + snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d", | ||
| 4480 | + sock, vde_datafd(s->vde)); | ||
| 4481 | + return 0; | ||
| 4482 | +} | ||
| 4483 | +#endif | ||
| 4484 | + | ||
| 4421 | /* network connection */ | 4485 | /* network connection */ |
| 4422 | typedef struct NetSocketState { | 4486 | typedef struct NetSocketState { |
| 4423 | VLANClientState *vc; | 4487 | VLANClientState *vc; |
| @@ -5047,6 +5111,30 @@ static int net_client_init(const char *str) | @@ -5047,6 +5111,30 @@ static int net_client_init(const char *str) | ||
| 5047 | } | 5111 | } |
| 5048 | vlan->nb_host_devs++; | 5112 | vlan->nb_host_devs++; |
| 5049 | } else | 5113 | } else |
| 5114 | +#ifdef CONFIG_VDE | ||
| 5115 | + if (!strcmp(device, "vde")) { | ||
| 5116 | + char vde_sock[1024], vde_group[512]; | ||
| 5117 | + int vde_port, vde_mode; | ||
| 5118 | + vlan->nb_host_devs++; | ||
| 5119 | + if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) { | ||
| 5120 | + vde_sock[0] = '\0'; | ||
| 5121 | + } | ||
| 5122 | + if (get_param_value(buf, sizeof(buf), "port", p) > 0) { | ||
| 5123 | + vde_port = strtol(buf, NULL, 10); | ||
| 5124 | + } else { | ||
| 5125 | + vde_port = 0; | ||
| 5126 | + } | ||
| 5127 | + if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) { | ||
| 5128 | + vde_group[0] = '\0'; | ||
| 5129 | + } | ||
| 5130 | + if (get_param_value(buf, sizeof(buf), "mode", p) > 0) { | ||
| 5131 | + vde_mode = strtol(buf, NULL, 8); | ||
| 5132 | + } else { | ||
| 5133 | + vde_mode = 0700; | ||
| 5134 | + } | ||
| 5135 | + ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode); | ||
| 5136 | + } else | ||
| 5137 | +#endif | ||
| 5050 | { | 5138 | { |
| 5051 | fprintf(stderr, "Unknown network device: %s\n", device); | 5139 | fprintf(stderr, "Unknown network device: %s\n", device); |
| 5052 | return -1; | 5140 | return -1; |
| @@ -7418,6 +7506,13 @@ static void help(int exitcode) | @@ -7418,6 +7506,13 @@ static void help(int exitcode) | ||
| 7418 | " connect the vlan 'n' to another VLAN using a socket connection\n" | 7506 | " connect the vlan 'n' to another VLAN using a socket connection\n" |
| 7419 | "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n" | 7507 | "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n" |
| 7420 | " connect the vlan 'n' to multicast maddr and port\n" | 7508 | " connect the vlan 'n' to multicast maddr and port\n" |
| 7509 | +#ifdef CONFIG_VDE | ||
| 7510 | + "-net vde[,vlan=n][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n" | ||
| 7511 | + " connect the vlan 'n' to port 'n' of a vde switch running\n" | ||
| 7512 | + " on host and listening for incoming connections on 'socketpath'.\n" | ||
| 7513 | + " Use group 'groupname' and mode 'octalmode' to change default\n" | ||
| 7514 | + " ownership and permissions for communication port.\n" | ||
| 7515 | +#endif | ||
| 7421 | "-net none use it alone to have zero network devices; if no -net option\n" | 7516 | "-net none use it alone to have zero network devices; if no -net option\n" |
| 7422 | " is provided, the default is '-net nic -net user'\n" | 7517 | " is provided, the default is '-net nic -net user'\n" |
| 7423 | "\n" | 7518 | "\n" |
| @@ -8907,6 +9002,12 @@ int main(int argc, char **argv) | @@ -8907,6 +9002,12 @@ int main(int argc, char **argv) | ||
| 8907 | s->down_script[0]) | 9002 | s->down_script[0]) |
| 8908 | launch_script(s->down_script, ifname, s->fd); | 9003 | launch_script(s->down_script, ifname, s->fd); |
| 8909 | } | 9004 | } |
| 9005 | +#if defined(CONFIG_VDE) | ||
| 9006 | + if (vc->fd_read == vde_from_qemu) { | ||
| 9007 | + VDEState *s = vc->opaque; | ||
| 9008 | + vde_close(s->vde); | ||
| 9009 | + } | ||
| 9010 | +#endif | ||
| 8910 | } | 9011 | } |
| 8911 | } | 9012 | } |
| 8912 | #endif | 9013 | #endif |