From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MCgPH-0001mI-JA for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:55 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MCgPD-0001gc-TU for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:55 -0400 Received: from [199.232.76.173] (port=38245 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MCgPD-0001gF-IZ for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:51 -0400 Received: from g4t0017.houston.hp.com ([15.201.24.20]:31903) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MCgPC-0005vE-SW for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:51 -0400 Received: from g1t0039.austin.hp.com (g1t0039.austin.hp.com [16.236.32.45]) by g4t0017.houston.hp.com (Postfix) with ESMTP id C17CE381BC for ; Fri, 5 Jun 2009 20:52:49 +0000 (UTC) From: Alex Williamson Date: Fri, 05 Jun 2009 14:47:18 -0600 Message-ID: <20090605204718.3355.28647.stgit@kvm.aw> In-Reply-To: <20090605204647.3355.81929.stgit@kvm.aw> References: <20090605204647.3355.81929.stgit@kvm.aw> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH 6/7] virtio-net: Add new RX filter controls List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: alex.williamson@hp.com Add a few new RX modes to better control the receive_filter. These are all fairly obvious features that hardware could provide. Signed-off-by: Alex Williamson --- hw/virtio-net.c | 40 ++++++++++++++++++++++++++++++++++++---- hw/virtio-net.h | 14 ++++++++++---- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 5239cc0..ecb58de 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -16,7 +16,7 @@ #include "qemu-timer.h" #include "virtio-net.h" -#define VIRTIO_NET_VM_VERSION 9 +#define VIRTIO_NET_VM_VERSION 10 #define MAC_TABLE_ENTRIES 32 #define MAX_VLAN (1 << 12) /* Per 802.1Q definition */ @@ -35,6 +35,10 @@ typedef struct VirtIONet int mergeable_rx_bufs; uint8_t promisc; uint8_t allmulti; + uint8_t alluni; + uint8_t nomulti; + uint8_t nouni; + uint8_t nobcast; struct { int in_use; int first_multi; @@ -98,6 +102,10 @@ static void virtio_net_reset(VirtIODevice *vdev) /* Reset back to compatibility mode */ n->promisc = 1; n->allmulti = 0; + n->alluni = 0; + n->nomulti = 0; + n->nouni = 0; + n->nobcast = 0; /* Flush any MAC and VLAN filter table state */ n->mac_table.in_use = 0; @@ -114,7 +122,8 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev) (1 << VIRTIO_NET_F_STATUS) | (1 << VIRTIO_NET_F_CTRL_VQ) | (1 << VIRTIO_NET_F_CTRL_RX) | - (1 << VIRTIO_NET_F_CTRL_VLAN); + (1 << VIRTIO_NET_F_CTRL_VLAN) | + (1 << VIRTIO_NET_F_CTRL_RX_EXTRA); return features; } @@ -157,6 +166,14 @@ static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, n->promisc = on; else if (cmd == VIRTIO_NET_CTRL_RX_MODE_ALLMULTI) n->allmulti = on; + else if (cmd == VIRTIO_NET_CTRL_RX_MODE_ALLUNI) + n->alluni = on; + else if (cmd == VIRTIO_NET_CTRL_RX_MODE_NOMULTI) + n->nomulti = on; + else if (cmd == VIRTIO_NET_CTRL_RX_MODE_NOUNI) + n->nouni = on; + else if (cmd == VIRTIO_NET_CTRL_RX_MODE_NOBCAST) + n->nobcast = on; else return VIRTIO_NET_ERR; @@ -357,7 +374,9 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) if (ptr[0] & 1) { // multicast if (!memcmp(ptr, bcast, sizeof(bcast))) { - return 1; + return !n->nobcast; + } else if (n->nomulti) { + return 0; } else if (n->allmulti || n->mac_table.multi_overflow) { return 1; } @@ -368,7 +387,9 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) } } } else { // unicast - if (n->mac_table.uni_overflow) { + if (n->nouni) { + return 0; + } else if (n->alluni || n->mac_table.uni_overflow) { return 1; } else if (!memcmp(ptr, n->mac, ETH_ALEN)) { return 1; @@ -549,6 +570,10 @@ static void virtio_net_save(QEMUFile *f, void *opaque) qemu_put_be32(f, 0); /* vnet-hdr placeholder */ qemu_put_byte(f, n->mac_table.multi_overflow); qemu_put_byte(f, n->mac_table.uni_overflow); + qemu_put_byte(f, n->alluni); + qemu_put_byte(f, n->nomulti); + qemu_put_byte(f, n->nouni); + qemu_put_byte(f, n->nobcast); } static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) @@ -605,6 +630,13 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) n->mac_table.uni_overflow = qemu_get_byte(f); } + if (version_id >= 10) { + n->alluni = qemu_get_byte(f); + n->nomulti = qemu_get_byte(f); + n->nouni = qemu_get_byte(f); + n->nobcast = qemu_get_byte(f); + } + /* Find the first multicast entry in the saved MAC filter */ for (i = 0; i < n->mac_table.in_use; i++) { if (n->mac_table.macs[i * ETH_ALEN] & 1) { diff --git a/hw/virtio-net.h b/hw/virtio-net.h index 390fe10..2085181 100644 --- a/hw/virtio-net.h +++ b/hw/virtio-net.h @@ -43,6 +43,7 @@ #define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ #define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ #define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */ +#define VIRTIO_NET_F_CTRL_RX_EXTRA 20 /* Extra RX mode control support */ #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ @@ -103,14 +104,19 @@ typedef uint8_t virtio_net_ctrl_ack; #define VIRTIO_NET_ERR 1 /* - * Control the RX mode, ie. promisucous and allmulti. PROMISC and - * ALLMULTI commands require an "out" sg entry containing a 1 byte - * state value, zero = disable, non-zero = enable. These commands - * are supported with the VIRTIO_NET_F_CTRL_RX feature. + * Control the RX mode, ie. promisucous, allmulti, etc... + * All commands require an "out" sg entry containing a 1 byte + * state value, zero = disable, non-zero = enable. Commands + * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature. + * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA. */ #define VIRTIO_NET_CTRL_RX_MODE 0 #define VIRTIO_NET_CTRL_RX_MODE_PROMISC 0 #define VIRTIO_NET_CTRL_RX_MODE_ALLMULTI 1 + #define VIRTIO_NET_CTRL_RX_MODE_ALLUNI 2 + #define VIRTIO_NET_CTRL_RX_MODE_NOMULTI 3 + #define VIRTIO_NET_CTRL_RX_MODE_NOUNI 4 + #define VIRTIO_NET_CTRL_RX_MODE_NOBCAST 5 /* * Control the MAC filter table.