From patchwork Tue Jan 13 21:23:20 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 2219 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n0DLJfAF012070 for ; Tue, 13 Jan 2009 13:19:42 -0800 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754105AbZAMVXi (ORCPT ); Tue, 13 Jan 2009 16:23:38 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753625AbZAMVXi (ORCPT ); Tue, 13 Jan 2009 16:23:38 -0500 Received: from g5t0008.atlanta.hp.com ([15.192.0.45]:26279 "EHLO g5t0008.atlanta.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752109AbZAMVXg (ORCPT ); Tue, 13 Jan 2009 16:23:36 -0500 Received: from g4t0009.houston.hp.com (g4t0009.houston.hp.com [16.234.32.26]) by g5t0008.atlanta.hp.com (Postfix) with ESMTP id 0C9FF245D5; Tue, 13 Jan 2009 21:23:36 +0000 (UTC) Received: from ldl.fc.hp.com (ldl.fc.hp.com [15.11.146.30]) by g4t0009.houston.hp.com (Postfix) with ESMTP id BFFA2C152; Tue, 13 Jan 2009 21:23:35 +0000 (UTC) Received: from localhost (ldl.fc.hp.com [127.0.0.1]) by ldl.fc.hp.com (Postfix) with ESMTP id 79C4539C017; Tue, 13 Jan 2009 14:23:35 -0700 (MST) X-Virus-Scanned: Debian amavisd-new at ldl.fc.hp.com Received: from ldl.fc.hp.com ([127.0.0.1]) by localhost (ldl.fc.hp.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YMbiRLZTVIsj; Tue, 13 Jan 2009 14:23:33 -0700 (MST) Received: from [192.168.1.60] (squirrel.fc.hp.com [15.11.146.57]) by ldl.fc.hp.com (Postfix) with ESMTP id A1E3439C001; Tue, 13 Jan 2009 14:23:32 -0700 (MST) Subject: [PATCH 4/4] virtio_net: Add a MAC filter table From: Alex Williamson To: Rusty Russell Cc: kvm , netdev , Mark McLoughlin Organization: HP OSLO R&D Date: Tue, 13 Jan 2009 14:23:20 -0700 Message-Id: <1231881800.9095.189.camel@bling> Mime-Version: 1.0 X-Mailer: Evolution 2.24.2 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Number of entries configurable via module param. Signed-off-by: Alex Williamson flags & IFF_PROMISC) != 0 || dev->uc_count > 0); - allmulti = ((dev->flags & IFF_ALLMULTI) != 0 || dev->mc_count > 0); + promisc = ((dev->flags & IFF_PROMISC) != 0); + allmulti = ((dev->flags & IFF_ALLMULTI) != 0); + + if (dev->uc_count > mac_entries) { + promisc = 1; + if (dev->mc_count > mac_entries) + allmulti = 1; + } else if (dev->uc_count + dev->mc_count > mac_entries) + allmulti = 1; + + if (!promisc && (dev->uc_count || (dev->mc_count && !allmulti))) { + u8 *buf, *cur; + int count, i; + struct dev_addr_list *uc_ptr, *mc_ptr; + + count = dev->uc_count + (allmulti ? 0 : dev->mc_count); + buf = kzalloc(count * ETH_ALEN, GFP_ATOMIC); + if (!buf) { + promisc = 1; + goto set_status; + } + + cur = buf; + uc_ptr = dev->uc_list; + mc_ptr = dev->mc_list; + + for (i = 0; i < dev->uc_count; i++) { + memcpy(cur, uc_ptr->da_addr, ETH_ALEN); + cur += ETH_ALEN; + uc_ptr = uc_ptr->next; + } + if (!allmulti) { + for (i = 0; i < dev->mc_count; i++) { + memcpy(cur, mc_ptr->da_addr, ETH_ALEN); + cur += ETH_ALEN; + mc_ptr = mc_ptr->next; + } + } + if (virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC_TABLE, + VIRTIO_NET_CTRL_MAC_TABLE_SET, + buf, count * ETH_ALEN)) { + printk(KERN_WARNING "%s: failed to program MAC filter " + "table, running in promiscuous mode.\n", + dev->name); + promisc = 1; + } + kfree(buf); + } else { + /* Set an empty MAC table - disabled */ + virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC_TABLE, + VIRTIO_NET_CTRL_MAC_TABLE_SET, NULL, 0); + } + +set_status: virtnet_send_command(vi, VIRTIO_NET_CTRL_RX_MODE, VIRTIO_NET_CTRL_RX_MODE_PROMISC, &promisc, sizeof(promisc)); @@ -799,6 +856,16 @@ static int virtnet_probe(struct virtio_device *vdev) vi->cvq = vdev->config->find_vq(vdev, 2, NULL); if (IS_ERR(vi->cvq)) vi->cvq = NULL; + else { + unsigned int entries; + + entries = mac_entries = min(mac_entries, + (unsigned int)(PAGE_SIZE / ETH_ALEN)); + if (virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC_TABLE, + VIRTIO_NET_CTRL_MAC_TABLE_ALLOC, + &entries, sizeof(entries))) + mac_entries = 0; + } /* Initialize our empty receive and send queues. */ skb_queue_head_init(&vi->recv); diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 80cd7d3..31235a0 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -60,4 +60,8 @@ struct virtio_net_hdr_mrg_rxbuf { #define VIRTIO_NET_CTRL_RX_MODE_PROMISC 0 #define VIRTIO_NET_CTRL_RX_MODE_ALLMULTI 1 +#define VIRTIO_NET_CTRL_MAC_TABLE 1 + #define VIRTIO_NET_CTRL_MAC_TABLE_ALLOC 0 + #define VIRTIO_NET_CTRL_MAC_TABLE_SET 1 + #endif /* _LINUX_VIRTIO_NET_H */