aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@hp.com>2009-02-04 04:02:40 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-04 19:35:12 -0500
commit2af7698e2dd698d452ab9d63a9ca5956bbe8fc3b (patch)
treeb4f767eb2b15d85b0f4ebe1cd560b296f44cc8a1 /drivers/net
parent2a41f71d3bd97dde3305b4e1c43ab0eca46e7c71 (diff)
virtio_net: Add a set_rx_mode interface
Make use of the RX_MODE control virtqueue class to enable the set_rx_mode netdev interface. This allows us to selectively enable/disable promiscuous and allmulti mode so we don't see packets we don't want. For now, we automatically enable these as needed if additional unicast or multicast addresses are requested. Signed-off-by: Alex Williamson <alex.williamson@hp.com> Acked-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/virtio_net.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 67bb583b7fc9..1abea9dc6f0f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -37,7 +37,7 @@ module_param(gso, bool, 0444);
37#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN) 37#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
38#define GOOD_COPY_LEN 128 38#define GOOD_COPY_LEN 128
39 39
40#define VIRTNET_SEND_COMMAND_SG_MAX 0 40#define VIRTNET_SEND_COMMAND_SG_MAX 1
41 41
42struct virtnet_info 42struct virtnet_info
43{ 43{
@@ -658,6 +658,36 @@ static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
658 return ethtool_op_set_tx_hw_csum(dev, data); 658 return ethtool_op_set_tx_hw_csum(dev, data);
659} 659}
660 660
661static void virtnet_set_rx_mode(struct net_device *dev)
662{
663 struct virtnet_info *vi = netdev_priv(dev);
664 struct scatterlist sg;
665 u8 promisc, allmulti;
666
667 /* We can't dynamicaly set ndo_set_rx_mode, so return gracefully */
668 if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
669 return;
670
671 promisc = ((dev->flags & IFF_PROMISC) != 0 || dev->uc_count > 0);
672 allmulti = ((dev->flags & IFF_ALLMULTI) != 0 || dev->mc_count > 0);
673
674 sg_set_buf(&sg, &promisc, sizeof(promisc));
675
676 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
677 VIRTIO_NET_CTRL_RX_PROMISC,
678 &sg, 1, 0))
679 dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
680 promisc ? "en" : "dis");
681
682 sg_set_buf(&sg, &allmulti, sizeof(allmulti));
683
684 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
685 VIRTIO_NET_CTRL_RX_ALLMULTI,
686 &sg, 1, 0))
687 dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
688 allmulti ? "en" : "dis");
689}
690
661static struct ethtool_ops virtnet_ethtool_ops = { 691static struct ethtool_ops virtnet_ethtool_ops = {
662 .set_tx_csum = virtnet_set_tx_csum, 692 .set_tx_csum = virtnet_set_tx_csum,
663 .set_sg = ethtool_op_set_sg, 693 .set_sg = ethtool_op_set_sg,
@@ -682,6 +712,7 @@ static const struct net_device_ops virtnet_netdev = {
682 .ndo_start_xmit = start_xmit, 712 .ndo_start_xmit = start_xmit,
683 .ndo_validate_addr = eth_validate_addr, 713 .ndo_validate_addr = eth_validate_addr,
684 .ndo_set_mac_address = eth_mac_addr, 714 .ndo_set_mac_address = eth_mac_addr,
715 .ndo_set_rx_mode = virtnet_set_rx_mode,
685 .ndo_change_mtu = virtnet_change_mtu, 716 .ndo_change_mtu = virtnet_change_mtu,
686#ifdef CONFIG_NET_POLL_CONTROLLER 717#ifdef CONFIG_NET_POLL_CONTROLLER
687 .ndo_poll_controller = virtnet_netpoll, 718 .ndo_poll_controller = virtnet_netpoll,
@@ -897,6 +928,7 @@ static unsigned int features[] = {
897 VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, 928 VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
898 VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ 929 VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
899 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, 930 VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
931 VIRTIO_NET_F_CTRL_RX,
900 VIRTIO_F_NOTIFY_ON_EMPTY, 932 VIRTIO_F_NOTIFY_ON_EMPTY,
901}; 933};
902 934