From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MCgP8-0001Zu-7V for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:46 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MCgP3-0001TA-Ct for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:45 -0400 Received: from [199.232.76.173] (port=38243 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MCgP3-0001Sp-4Z for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:41 -0400 Received: from g5t0007.atlanta.hp.com ([15.192.0.44]:9530) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MCgP2-0005tm-M6 for qemu-devel@nongnu.org; Fri, 05 Jun 2009 16:52:40 -0400 Received: from g4t0018.houston.hp.com (g4t0018.houston.hp.com [16.234.32.27]) by g5t0007.atlanta.hp.com (Postfix) with ESMTP id 567C914104 for ; Fri, 5 Jun 2009 20:52:39 +0000 (UTC) From: Alex Williamson Date: Fri, 05 Jun 2009 14:47:08 -0600 Message-ID: <20090605204707.3355.24355.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 4/7] virtio-net: Fix MAC filter overflow handling 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 Overloading the promisc and allmulti flags for indicating filter table overflow makes it difficult to track the actual requested operating mode. Split these out into separate flags. Signed-off-by: Alex Williamson --- hw/virtio-net.c | 31 +++++++++++++++++++++++-------- 1 files changed, 23 insertions(+), 8 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 395b735..64515a3 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 8 +#define VIRTIO_NET_VM_VERSION 9 #define MAC_TABLE_ENTRIES 32 #define MAX_VLAN (1 << 12) /* Per 802.1Q definition */ @@ -37,6 +37,8 @@ typedef struct VirtIONet uint8_t allmulti; struct { int in_use; + uint8_t multi_overflow; + uint8_t uni_overflow; uint8_t *macs; } mac_table; uint32_t *vlans; @@ -98,6 +100,8 @@ static void virtio_net_reset(VirtIODevice *vdev) /* Flush any MAC and VLAN filter table state */ n->mac_table.in_use = 0; + n->mac_table.multi_overflow = 0; + n->mac_table.uni_overflow = 0; memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN); memset(n->vlans, 0, MAX_VLAN >> 3); } @@ -168,6 +172,8 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, return VIRTIO_NET_ERR; n->mac_table.in_use = 0; + n->mac_table.uni_overflow = 0; + n->mac_table.multi_overflow = 0; memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN); mac_data.entries = ldl_le_p(elem->out_sg[1].iov_base); @@ -181,8 +187,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, mac_data.entries * ETH_ALEN); n->mac_table.in_use += mac_data.entries; } else { - n->promisc = 1; - return VIRTIO_NET_OK; + n->mac_table.uni_overflow = 1; } mac_data.entries = ldl_le_p(elem->out_sg[2].iov_base); @@ -197,8 +202,9 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, elem->out_sg[2].iov_base + sizeof(mac_data), mac_data.entries * ETH_ALEN); n->mac_table.in_use += mac_data.entries; - } else - n->allmulti = 1; + } else { + n->mac_table.multi_overflow = 1; + } } return VIRTIO_NET_OK; @@ -347,11 +353,13 @@ 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; - } else if (n->allmulti) { + } else if (n->allmulti || n->mac_table.multi_overflow) { return 1; } } else { // unicast - if (!memcmp(ptr, n->mac, ETH_ALEN)) { + if (n->mac_table.uni_overflow) { + return 1; + } else if (!memcmp(ptr, n->mac, ETH_ALEN)) { return 1; } } @@ -527,6 +535,8 @@ static void virtio_net_save(QEMUFile *f, void *opaque) qemu_put_buffer(f, n->mac_table.macs, n->mac_table.in_use * ETH_ALEN); qemu_put_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3); 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); } static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) @@ -563,7 +573,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) n->mac_table.in_use * ETH_ALEN); } else if (n->mac_table.in_use) { qemu_fseek(f, n->mac_table.in_use * ETH_ALEN, SEEK_CUR); - n->promisc = 1; + n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1; n->mac_table.in_use = 0; } } @@ -577,6 +587,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) exit(1); } + if (version_id >= 9) { + n->mac_table.multi_overflow = qemu_get_byte(f); + n->mac_table.uni_overflow = qemu_get_byte(f); + } + if (n->tx_timer_active) { qemu_mod_timer(n->tx_timer, qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL);