From patchwork Thu Jan 29 23:05:23 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 4677 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 n0TN8OCm019213 for ; Thu, 29 Jan 2009 23:08:24 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755429AbZA2XIV (ORCPT ); Thu, 29 Jan 2009 18:08:21 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755334AbZA2XIV (ORCPT ); Thu, 29 Jan 2009 18:08:21 -0500 Received: from g1t0029.austin.hp.com ([15.216.28.36]:21072 "EHLO g1t0029.austin.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754023AbZA2XIU (ORCPT ); Thu, 29 Jan 2009 18:08:20 -0500 Received: from g5t0029.atlanta.hp.com (g5t0029.atlanta.hp.com [16.228.8.141]) by g1t0029.austin.hp.com (Postfix) with ESMTP id 34CF2384DE; Thu, 29 Jan 2009 23:08:20 +0000 (UTC) Received: from ldl.fc.hp.com (ldl.fc.hp.com [15.11.146.30]) by g5t0029.atlanta.hp.com (Postfix) with ESMTP id C4D711008D; Thu, 29 Jan 2009 23:08:00 +0000 (UTC) Received: from localhost (ldl.fc.hp.com [127.0.0.1]) by ldl.fc.hp.com (Postfix) with ESMTP id 5494D39C00E; Thu, 29 Jan 2009 16:08:00 -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 F183a8j+XYg1; Thu, 29 Jan 2009 16:08:00 -0700 (MST) Received: from debian.lart (lart.fc.hp.com [15.11.146.31]) by ldl.fc.hp.com (Postfix) with ESMTP id 5FA0739C06E; Thu, 29 Jan 2009 16:07:57 -0700 (MST) From: Alex Williamson Subject: [PATCH v2 4/4] virtio_net: Add support for VLAN filtering in the hypervisor To: rusty@rustcorp.com.au Cc: markmc@redhat.com, netdev@vger.kernel.org, kvm@vger.kernel.org Date: Thu, 29 Jan 2009 16:05:23 -0700 Message-ID: <20090129230523.2672.55464.stgit@debian.lart> In-Reply-To: <20090129230502.2672.87669.stgit@debian.lart> References: <20090129230502.2672.87669.stgit@debian.lart> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org VLAN filtering allows the hypervisor to drop packets from VLANs that we're not a part of, further reducing the number of extraneous packets recieved. This makes use of the VLAN virtqueue command class. The CTRL_VLAN feature bit tells us whether the backend supports VLAN filtering. Signed-off-by: Alex Williamson --- drivers/net/virtio_net.c | 37 ++++++++++++++++++++++++++++++++++++- include/linux/virtio_net.h | 16 ++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 23610ce..14ee139 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -767,6 +767,26 @@ free_uc: kfree(uc_buf); } +static void virnet_vlan_rx_add_vid(struct net_device *dev, u16 vid) +{ + struct virtnet_info *vi = netdev_priv(dev); + + if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, + VIRTIO_NET_CTRL_VLAN_ADD, &vid, sizeof(vid))) + printk(KERN_WARNING "%s: Failed to add VLAN ID %d.\n", + dev->name, vid); +} + +static void virnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) +{ + struct virtnet_info *vi = netdev_priv(dev); + + if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, + VIRTIO_NET_CTRL_VLAN_DEL, &vid, sizeof(vid))) + printk(KERN_WARNING "%s: Failed to kill VLAN ID %d.\n", + dev->name, vid); +} + static struct ethtool_ops virtnet_ethtool_ops = { .set_tx_csum = virtnet_set_tx_csum, .set_sg = ethtool_op_set_sg, @@ -793,6 +813,8 @@ static const struct net_device_ops virtnet_netdev = { .ndo_set_mac_address = virtnet_set_mac_address, .ndo_set_rx_mode = virtnet_set_rx_mode, .ndo_change_mtu = virtnet_change_mtu, + .ndo_vlan_rx_add_vid = virnet_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = virnet_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = virtnet_netpoll, #endif @@ -920,6 +942,19 @@ static int virtnet_probe(struct virtio_device *vdev) err = PTR_ERR(vi->svq); goto free_send; } + + if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN)) { + u8 enable = 1; + + /* Enable VLAN filtering */ + if (virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, + VIRTIO_NET_CTRL_VLAN_ENABLE, + &enable, sizeof(enable))) + dev->features |= NETIF_F_HW_VLAN_FILTER; + else + printk(KERN_WARNING "virtio_net: " + "Failed to enable VLAN filter\n"); + } } /* Initialize our empty receive and send queues. */ @@ -1010,7 +1045,7 @@ static unsigned int features[] = { VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, - VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_MAC, + VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_MAC, VIRTIO_NET_F_CTRL_VLAN, VIRTIO_F_NOTIFY_ON_EMPTY, }; diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index c8e945a..8733a66 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -25,6 +25,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_MAC 19 /* Control channel MAC filtering */ +#define VIRTIO_NET_F_CTRL_VLAN 20 /* Control channel VLAN filtering */ #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ @@ -103,4 +104,19 @@ typedef __u8 virtio_net_ctrl_ack; #define VIRTIO_NET_CTRL_MAC 1 #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 +/* + * Control VLAN filtering + * + * The VLAN filter table is controlled via a simple ADD/DEL interface. + * VLAN IDs not added will be dropped. Del is the opposite of add. + * Both commands expect an out entry containing a 2 byte VLAN ID. + * The ENABLE command expects an out entry containing a single byte, + * zero to disable, non-zero to enable. The default state is disabled + * for compatibility. + */ +#define VIRTIO_NET_CTRL_VLAN 2 + #define VIRTIO_NET_CTRL_VLAN_ENABLE 0 + #define VIRTIO_NET_CTRL_VLAN_ADD 1 + #define VIRTIO_NET_CTRL_VLAN_DEL 2 + #endif /* _LINUX_VIRTIO_NET_H */