Index: qemu-doc.texi =================================================================== RCS file: /cvsroot/qemu/qemu/qemu-doc.texi,v retrieving revision 1.65 diff -u -r1.65 qemu-doc.texi --- qemu-doc.texi 28 Jul 2005 22:27:28 -0000 1.65 +++ qemu-doc.texi 1 Oct 2005 20:38:16 -0000 @@ -222,6 +222,22 @@ aa:bb:cc:dd:ee:ff in hexa). The mac address is incremented for each new network interface. +@item -tun devname +Try to use @var{devname} while opening a tap/tun host network interface and use +it. If it work, the network init script is not executed for this +interface. If it don't work, the interface will use the name assigned +by the operating system and the network init script is executed. + +This option permit the use of preconfigured interface. For example, as +root you can assign a tun interface to a user and configure it like this: +@example +tunctl -u bob -t tun2 +ifconfig tun2 192.168.2.1 +@end example +Then bob can use this interface with the option "-tun tun2". Note that +option permit the use of a DHCP server on the host to configure the +guest interface. + @item -tun-fd fd Assumes @var{fd} talks to a tap/tun host network interface and use it. Read @url{http://bellard.org/qemu/tetrinet.html} to have an Index: vl.c =================================================================== RCS file: /cvsroot/qemu/qemu/vl.c,v retrieving revision 1.136 diff -u -r1.136 vl.c --- vl.c 3 Sep 2005 21:33:43 -0000 1.136 +++ vl.c 1 Oct 2005 20:38:17 -0000 @@ -1663,7 +1663,7 @@ } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d"); + pstrcpy(ifr.ifr_name, IFNAMSIZ, (ifname && *ifname) ? ifname : "tun%d"); ret = ioctl(fd, TUNSETIFF, (void *) &ifr); if (ret != 0) { fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n"); @@ -1689,7 +1689,7 @@ qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque); } -static int net_tun_init(NetDriverState *nd) +static int net_tun_init(NetDriverState *nd, int script) { int pid, status; char *args[3]; @@ -1700,7 +1700,7 @@ return -1; /* try to launch network init script */ - pid = fork(); + pid = script ? fork() : -1; if (pid >= 0) { if (pid == 0) { parg = args; @@ -2851,6 +2851,7 @@ "-nics n simulate 'n' network cards [default=1]\n" "-macaddr addr set the mac address of the first interface\n" "-n script set tap/tun network init script [default=%s]\n" + "-tun devname try to use devname while opening tap/tun interface\n" "-tun-fd fd use this fd as already opened tap/tun interface\n" #ifdef CONFIG_SLIRP "-user-net use user mode network stack [default if no tap/tun script]\n" @@ -2940,6 +2941,7 @@ QEMU_OPTION_nics, QEMU_OPTION_macaddr, QEMU_OPTION_n, + QEMU_OPTION_tun, QEMU_OPTION_tun_fd, QEMU_OPTION_user_net, QEMU_OPTION_tftp, @@ -3003,6 +3005,7 @@ { "nics", HAS_ARG, QEMU_OPTION_nics}, { "macaddr", HAS_ARG, QEMU_OPTION_macaddr}, { "n", HAS_ARG, QEMU_OPTION_n }, + { "tun", HAS_ARG, QEMU_OPTION_tun }, { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd }, #ifdef CONFIG_SLIRP { "user-net", 0, QEMU_OPTION_user_net }, @@ -3136,7 +3139,7 @@ int cyls, heads, secs, translation; int start_emulation = 1; uint8_t macaddr[6]; - int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; + int net_if_type, nb_tun, nb_tun_fds, cnt_tun_fds, tun_fds[MAX_NICS]; int optind; const char *r, *optarg; CharDriverState *monitor_hd; @@ -3190,7 +3193,12 @@ parallel_devices[i][0] = '\0'; parallel_device_index = 0; + for(i = 0; i < MAX_NICS; i++) { + nd_table[i].ifname[0] = '\0'; + } + nb_tun = 0; nb_tun_fds = 0; + cnt_tun_fds = 0; net_if_type = -1; nb_nics = 1; /* default mac address of the first network interface */ @@ -3313,18 +3321,25 @@ case QEMU_OPTION_append: kernel_cmdline = optarg; break; + case QEMU_OPTION_tun: + net_if_type = NET_IF_TUN; + if (nb_tun+nb_tun_fds < MAX_NICS) { + pstrcpy(nd_table[nb_tun++].ifname, IFNAMSIZ, optarg); + } + break; case QEMU_OPTION_tun_fd: { const char *p; int fd; net_if_type = NET_IF_TUN; - if (nb_tun_fds < MAX_NICS) { + if (nb_tun+nb_tun_fds < MAX_NICS) { fd = strtol(optarg, (char **)&p, 0); if (*p != '\0') { fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds); exit(1); } tun_fds[nb_tun_fds++] = fd; + nb_tun++; } } break; @@ -3603,12 +3618,20 @@ #endif #if !defined(_WIN32) case NET_IF_TUN: - if (i < nb_tun_fds) { - net_fd_init(nd, tun_fds[i]); - } else { - if (net_tun_init(nd) < 0) - net_dummy_init(nd); - } + if (nd->ifname && *(nd->ifname)) { + if (net_tun_init(nd, 0) < 0) { + nd->ifname[0] = '\0'; + if (net_tun_init(nd, 1) < 0) + net_dummy_init(nd); + } + } else { + if (cnt_tun_fds < nb_tun_fds) { + net_fd_init(nd, tun_fds[cnt_tun_fds++]); + } else { + if (net_tun_init(nd, 1) < 0) + net_dummy_init(nd); + } + } break; #endif case NET_IF_DUMMY: