From patchwork Tue Dec 8 17:41:44 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 40660 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 79CEEB7B6C for ; Wed, 9 Dec 2009 05:43:05 +1100 (EST) Received: from localhost ([127.0.0.1]:55044 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NI51Z-0007kQ-Rp for incoming@patchwork.ozlabs.org; Tue, 08 Dec 2009 13:43:01 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NI44U-0001Zs-CU for qemu-devel@nongnu.org; Tue, 08 Dec 2009 12:41:58 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NI44P-0001Up-Fw for qemu-devel@nongnu.org; Tue, 08 Dec 2009 12:41:57 -0500 Received: from [199.232.76.173] (port=40241 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NI44P-0001UV-3L for qemu-devel@nongnu.org; Tue, 08 Dec 2009 12:41:53 -0500 Received: from moutng.kundenserver.de ([212.227.17.10]:49542) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NI44O-0003UR-HJ for qemu-devel@nongnu.org; Tue, 08 Dec 2009 12:41:52 -0500 Received: from klappe2.localnet (deibp9eh1--blueice2n1.emea.ibm.com [195.212.29.171]) by mrelayeu.kundenserver.de (node=mrbap2) with ESMTP (Nemesis) id 0LzYuY-1OCgto1D3C-014bMg; Tue, 08 Dec 2009 18:41:50 +0100 From: Arnd Bergmann To: qemu-devel@nongnu.org Date: Tue, 8 Dec 2009 18:41:44 +0100 User-Agent: KMail/1.12.2 (Linux/2.6.31-14-generic; KDE/4.3.2; x86_64; ; ) MIME-Version: 1.0 Message-Id: <200912081841.45075.arnd@arndb.de> X-Provags-ID: V01U2FsdGVkX1/gm0JlpPvNCdpDAd3VeUntW7XHxg4yhD0+85U /i9bxPN8XqSF9cFFhpICBzt+6sWYOqt4T22fUq3X1RAT8JFrSy Tawx5W4tfDjJeiwNrfq8A== X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Subject: [Qemu-devel] [PATCH, try 2] qemu/tap: add -net tap,dev= option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org In order to support macvtap, we need a way to select the actual tap endpoint. While it would be nice to pass it by network interface name, passing the character device is more flexible, and we can easily do both in the long run. Signed-off-by: Arnd Bergmann Acked-by: Mark McLoughlin diff --git a/net.c b/net.c index 13bdbb2..deb12fd 100644 --- a/net.c +++ b/net.c @@ -955,6 +955,11 @@ static struct { }, #ifndef _WIN32 { + .name = "dev", + .type = QEMU_OPT_STRING, + .help = "character device pathname", + }, + { .name = "fd", .type = QEMU_OPT_STRING, .help = "file descriptor of an already opened tap", diff --git a/net/tap-aix.c b/net/tap-aix.c index 4bc9f2f..b789d06 100644 --- a/net/tap-aix.c +++ b/net/tap-aix.c @@ -25,7 +25,8 @@ #include "net/tap.h" #include -int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) +int tap_open(char *ifname, int ifname_size, char *dev, int dev_size, + int *vnet_hdr, int vnet_hdr_required) { fprintf(stderr, "no tap on AIX\n"); return -1; diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 815997d..09a7780 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -40,7 +40,8 @@ #include #endif -int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) +int tap_open(char *ifname, int ifname_size, char *dev, int dev_size, + int *vnet_hdr, int vnet_hdr_required) { int fd; char *dev; diff --git a/net/tap-linux.c b/net/tap-linux.c index 6af9e82..a6df123 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -32,14 +32,21 @@ #include "sysemu.h" #include "qemu-common.h" -int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) +int tap_open(char *ifname, int ifname_size, char *dev, int dev_size, + int *vnet_hdr, int vnet_hdr_required) { struct ifreq ifr; int fd, ret; + const char *path; - TFR(fd = open("/dev/net/tun", O_RDWR)); + if (dev[0] == '\0') + path = "/dev/net/tun"; + else + path = dev; + + TFR(fd = open(dev, O_RDWR)); if (fd < 0) { - fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n"); + fprintf(stderr, "warning: could not open %s: no virtual network emulation\n", path); return -1; } memset(&ifr, 0, sizeof(ifr)); @@ -70,7 +77,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d"); ret = ioctl(fd, TUNSETIFF, (void *) &ifr); if (ret != 0) { - fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n"); + fprintf(stderr, "warning: could not configure %s: no virtual network emulation\n", path); close(fd); return -1; } diff --git a/net/tap-solaris.c b/net/tap-solaris.c index e14fe36..72abb78 100644 --- a/net/tap-solaris.c +++ b/net/tap-solaris.c @@ -171,7 +171,8 @@ static int tap_alloc(char *dev, size_t dev_size) return tap_fd; } -int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) +int tap_open(char *ifname, int ifname_size, char *dev, int dev_size, + int *vnet_hdr, int vnet_hdr_required) { char dev[10]=""; int fd; diff --git a/net/tap.c b/net/tap.c index 0d8b424..14ddf65 100644 --- a/net/tap.c +++ b/net/tap.c @@ -343,12 +343,17 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr) { int fd, vnet_hdr_required; char ifname[128] = {0,}; + char dev[128] = {0,}; const char *setup_script; if (qemu_opt_get(opts, "ifname")) { pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname")); } + if (qemu_opt_get(opts, "dev")) { + pstrcpy(dev, sizeof(dev), qemu_opt_get(opts, "dev")); + } + *vnet_hdr = qemu_opt_get_bool(opts, "vnet_hdr", 1); if (qemu_opt_get(opts, "vnet_hdr")) { vnet_hdr_required = *vnet_hdr; @@ -356,7 +361,8 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr) vnet_hdr_required = 0; } - TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr, vnet_hdr_required)); + TFR(fd = tap_open(ifname, sizeof(ifname), dev, sizeof(dev), + vnet_hdr, vnet_hdr_required)); if (fd < 0) { return -1; } @@ -371,6 +377,7 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr) } qemu_opt_set(opts, "ifname", ifname); + qemu_opt_set(opts, "dev", dev); return fd; } @@ -382,10 +389,12 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan if (qemu_opt_get(opts, "fd")) { if (qemu_opt_get(opts, "ifname") || + qemu_opt_get(opts, "dev") || qemu_opt_get(opts, "script") || qemu_opt_get(opts, "downscript") || qemu_opt_get(opts, "vnet_hdr")) { - qemu_error("ifname=, script=, downscript= and vnet_hdr= is invalid with fd=\n"); + qemu_error("ifname=, dev=, script=, downscript= and vnet_hdr= is " + "invalid with fd=\n"); return -1; } @@ -425,15 +434,16 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan if (qemu_opt_get(opts, "fd")) { snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd); } else { - const char *ifname, *script, *downscript; + const char *ifname, *dev, *script, *downscript; ifname = qemu_opt_get(opts, "ifname"); + dev = qemu_opt_get(opts, "dev"); script = qemu_opt_get(opts, "script"); downscript = qemu_opt_get(opts, "downscript"); snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "ifname=%s,script=%s,downscript=%s", - ifname, script, downscript); + "ifname=%s,dev=%s,script=%s,downscript=%s", + ifname, dev, script, downscript); if (strcmp(downscript, "no") != 0) { snprintf(s->down_script, sizeof(s->down_script), "%s", downscript); diff --git a/net/tap.h b/net/tap.h index 538a562..ba44363 100644 --- a/net/tap.h +++ b/net/tap.h @@ -34,7 +34,8 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan); -int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required); +int tap_open(char *ifname, int ifname_size, char *dev, int dev_size, + int *vnet_hdr, int vnet_hdr_required); ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen); diff --git a/qemu-options.hx b/qemu-options.hx index 1b5781a..7f7aa18 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -810,12 +810,14 @@ DEF("net", HAS_ARG, QEMU_OPTION_net, "-net tap[,vlan=n][,name=str],ifname=name\n" " connect the host TAP network interface to VLAN 'n'\n" #else - "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off]\n" + "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,dev=str][,script=file]\n" + " [,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off]\n" " connect the host TAP network interface to VLAN 'n' and use the\n" " network scripts 'file' (default=%s)\n" " and 'dfile' (default=%s);\n" " use '[down]script=no' to disable script execution;\n" " use 'fd=h' to connect to an already opened TAP interface\n" + " use 'dev=str' to open a specific tap character device\n" " use 'sndbuf=nbytes' to limit the size of the send buffer; the\n" " default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n" " use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag; use\n"