From: Alex Williamson <alex.williamson@hp.com>
To: qemu-devel@nongnu.org
Cc: kvm@vger.kernel.org, alex.williamson@hp.com
Subject: [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 [PATCH 0/4] qemu: TAP filtering support Alex Williamson
2009-02-10 21:28 ` [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 ` [PATCH 3/4] qemu:virtio-net: Add support for qemu_vlan_rxfilter Alex Williamson
2009-02-12 16:26 ` [Qemu-devel] " 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 ` [PATCH 4/4] qemu:e1000: " Alex Williamson
2009-02-11 15:11 ` Alex Williamson
2009-02-11 17:11 ` Alex Williamson
2009-02-11 19:31 ` [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 ` [Qemu-devel] " 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.