From: Alex Williamson <alex.williamson@hp.com>
To: qemu-devel@nongnu.org
Cc: alex.williamson@hp.com, kvm@vger.kernel.org
Subject: [Qemu-devel] [PATCH 2/4] qemu:net: Add TAP support for RX filtering on Linux
Date: Tue, 10 Feb 2009 14:28:52 -0700 [thread overview]
Message-ID: <20090210212852.9760.6710.stgit@kvm.aw> (raw)
In-Reply-To: <20090210212841.9760.96780.stgit@kvm.aw>
The Linux tap driver provides an ioctl to set a TX filter. Setting
this restricts the packets received onto the vlan. We provide a
hotplug callback to clear the filter when a new device gets added.
The new rxfilter=off option can be used to disable exporting this
feature to backend drivers.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
---
net.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
qemu-doc.texi | 6 ++++--
vl.c | 3 ++-
3 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/net.c b/net.c
index e68cb40..973efea 100644
--- a/net.c
+++ b/net.c
@@ -724,6 +724,38 @@ static ssize_t tap_receive_iov(void *opaque, const struct iovec *iov,
}
#endif
+#ifdef TUNSETTXFILTER
+static int tap_rxfilter(void *opaque, unsigned int flags, int count,
+ uint8_t *list)
+{
+ TAPState *s = opaque;
+ struct tun_filter *filter;
+ int ret;
+
+ if (flags & QEMU_NET_PROMISC)
+ count = 0;
+
+ filter = qemu_mallocz(sizeof(*filter) + (count * ETH_ALEN));
+
+ memcpy(filter->addr, list, count * ETH_ALEN);
+ filter->count = count;
+
+ if (flags & QEMU_NET_ALLMULTI)
+ filter->flags |= TUN_FLT_ALLMULTI;
+
+ ret = ioctl(s->fd, TUNSETTXFILTER, filter);
+
+ qemu_free(filter);
+
+ return ret;
+}
+
+static void tap_vlan_client_added(void *opaque)
+{
+ tap_rxfilter(opaque, 0, 0, NULL);
+}
+#endif
+
static void tap_receive(void *opaque, const uint8_t *buf, int size)
{
TAPState *s = opaque;
@@ -762,7 +794,7 @@ static void tap_send(void *opaque)
static TAPState *net_tap_fd_init(VLANState *vlan,
const char *model,
const char *name,
- int fd)
+ int fd, int rxfilter)
{
TAPState *s;
@@ -772,6 +804,12 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
#ifdef HAVE_IOVEC
s->vc->fd_readv = tap_receive_iov;
#endif
+#ifdef TUNSETTXFILTER
+ if (rxfilter) {
+ s->vc->fd_rxfilter = tap_rxfilter;
+ s->vc->vlan_client_added = tap_vlan_client_added;
+ }
+#endif
qemu_set_fd_handler(s->fd, tap_send, NULL, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
return s;
@@ -1005,7 +1043,8 @@ static int launch_script(const char *setup_script, const char *ifname, int fd)
static int net_tap_init(VLANState *vlan, const char *model,
const char *name, const char *ifname1,
- const char *setup_script, const char *down_script)
+ const char *setup_script, const char *down_script,
+ int rxfilter)
{
TAPState *s;
int fd;
@@ -1025,7 +1064,7 @@ static int net_tap_init(VLANState *vlan, const char *model,
if (launch_script(setup_script, ifname, fd))
return -1;
}
- s = net_tap_fd_init(vlan, model, name, fd);
+ s = net_tap_fd_init(vlan, model, name, fd, rxfilter);
if (!s)
return -1;
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
@@ -1663,13 +1702,18 @@ int net_client_init(const char *device, const char *p)
if (!strcmp(device, "tap")) {
char ifname[64];
char setup_script[1024], down_script[1024];
- int fd;
+ int fd, rxfilter = 1;
vlan->nb_host_devs++;
+
+ if (get_param_value(buf, sizeof(buf), "rxfilter", p) > 0)
+ if (!strcmp(buf, "off"))
+ rxfilter = 0;
+
if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
fd = strtol(buf, NULL, 0);
fcntl(fd, F_SETFL, O_NONBLOCK);
ret = -1;
- if (net_tap_fd_init(vlan, device, name, fd))
+ if (net_tap_fd_init(vlan, device, name, fd, rxfilter))
ret = 0;
} else {
if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
@@ -1681,7 +1725,7 @@ int net_client_init(const char *device, const char *p)
if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
}
- ret = net_tap_init(vlan, device, name, ifname, setup_script, down_script);
+ ret = net_tap_init(vlan, device, name, ifname, setup_script, down_script, rxfilter);
}
} else
#endif
diff --git a/qemu-doc.texi b/qemu-doc.texi
index efb88d2..9a3957c 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -643,7 +643,7 @@ Use the user mode network stack which requires no administrator
privilege to run. @option{hostname=name} can be used to specify the client
hostname reported by the builtin DHCP server.
-@item -net tap[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}]
+@item -net tap[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}][,rxfilter=on|off]
Connect the host TAP network interface @var{name} to VLAN @var{n}, use
the network script @var{file} to configure it and the network script
@var{dfile} to deconfigure it. If @var{name} is not provided, the OS
@@ -651,7 +651,9 @@ automatically provides one. @option{fd}=@var{h} can be used to specify
the handle of an already opened host TAP interface. The default network
configure script is @file{/etc/qemu-ifup} and the default network
deconfigure script is @file{/etc/qemu-ifdown}. Use @option{script=no}
-or @option{downscript=no} to disable script execution. Example:
+or @option{downscript=no} to disable script execution. The rxfilter
+(Linux-only) option enables or disables availability of the tap device
+MAC filtering (default on). Example:
@example
qemu linux.img -net nic -net tap
diff --git a/vl.c b/vl.c
index aff2b2c..96ab696 100644
--- a/vl.c
+++ b/vl.c
@@ -3909,12 +3909,13 @@ static void help(int exitcode)
"-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]\n"
+ "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,rxfilter=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"
+ " rxfilter enables|disables use of the tap MAC filter (default on)\n"
#endif
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
next prev parent reply other threads:[~2009-02-10 21:31 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-10 21:28 [Qemu-devel] [PATCH 0/4] qemu: TAP filtering support Alex Williamson
2009-02-10 21:28 ` [Qemu-devel] [PATCH 1/4] qemu:net: Add infrastructure for setting an RX filter through the vlan Alex Williamson
2009-02-10 21:28 ` Alex Williamson [this message]
2009-02-10 21:28 ` [Qemu-devel] [PATCH 3/4] qemu:virtio-net: Add support for qemu_vlan_rxfilter Alex Williamson
2009-02-12 16:26 ` Paul Brook
2009-02-12 16:36 ` Alex Williamson
2009-02-12 17:05 ` Paul Brook
2009-02-12 18:21 ` Alex Williamson
2009-02-12 20:26 ` Jamie Lokier
2009-02-13 12:40 ` Paul Brook
2009-02-13 16:00 ` Jamie Lokier
2009-02-13 16:17 ` Paul Brook
2009-02-13 16:46 ` Jamie Lokier
2009-02-13 17:04 ` Paul Brook
2009-02-13 20:38 ` Jamie Lokier
2009-02-15 16:25 ` Paul Brook
2009-02-10 21:29 ` [Qemu-devel] [PATCH 4/4] qemu:e1000: " Alex Williamson
2009-02-11 15:11 ` [Qemu-devel] " Alex Williamson
2009-02-11 17:11 ` [Qemu-devel] " Alex Williamson
2009-02-11 19:31 ` [Qemu-devel] Re: [PATCH 0/4] qemu: TAP filtering support Mark McLoughlin
2009-02-11 19:43 ` Anthony Liguori
2009-02-11 19:51 ` Alex Williamson
2009-02-11 20:19 ` Mark McLoughlin
2009-02-11 20:37 ` Alex Williamson
2009-02-12 19:57 ` Jamie Lokier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090210212852.9760.6710.stgit@kvm.aw \
--to=alex.williamson@hp.com \
--cc=kvm@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).