--- a/lib/librte_pmd_virtio/virtio_ethdev.c	2014-08-25 19:00:16.754586819 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c	2014-08-25 19:02:48.019397658 -0700
@@ -77,6 +77,11 @@ static void virtio_get_hwaddr(struct vir
 static void virtio_dev_rx_queue_release(__rte_unused void *rxq);
 static void virtio_dev_tx_queue_release(__rte_unused void *txq);
 
+static void virtio_promiscuous_enable(struct rte_eth_dev *dev);
+static void virtio_promiscuous_disable(struct rte_eth_dev *dev);
+static void virtio_allmulticast_enable(struct rte_eth_dev *dev);
+static void virtio_allmulticast_disable(struct rte_eth_dev *dev);
+
 static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 static void virtio_dev_stats_reset(struct rte_eth_dev *dev);
 static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);
@@ -405,23 +410,27 @@ virtio_dev_close(struct rte_eth_dev *dev
  * dev_ops for virtio, bare necessities for basic operation
  */
 static struct eth_dev_ops virtio_eth_dev_ops = {
-	.dev_configure           = virtio_dev_configure,
-	.dev_start               = virtio_dev_start,
-	.dev_stop                = virtio_dev_stop,
-	.dev_close               = virtio_dev_close,
-
-	.dev_infos_get           = virtio_dev_info_get,
-	.stats_get               = virtio_dev_stats_get,
-	.stats_reset             = virtio_dev_stats_reset,
-	.link_update             = virtio_dev_link_update,
-	.mac_addr_add            = NULL,
-	.mac_addr_remove         = NULL,
-	.rx_queue_setup          = virtio_dev_rx_queue_setup,
+	.dev_configure		 = virtio_dev_configure,
+	.dev_start		 = virtio_dev_start,
+	.dev_stop		 = virtio_dev_stop,
+	.dev_close		 = virtio_dev_close,
+
+	.dev_infos_get		 = virtio_dev_info_get,
+	.stats_get		 = virtio_dev_stats_get,
+	.stats_reset		 = virtio_dev_stats_reset,
+	.link_update		 = virtio_dev_link_update,
+	.promiscuous_enable	 = virtio_promiscuous_enable,
+	.promiscuous_disable	 = virtio_promiscuous_disable,
+	.allmulticast_enable	 = virtio_allmulticast_enable,
+	.allmulticast_disable	 = virtio_allmulticast_disable,
+	.mac_addr_add		 = NULL,
+	.mac_addr_remove	 = NULL,
+	.rx_queue_setup		 = virtio_dev_rx_queue_setup,
 	/* meaningfull only to multiple queue */
-	.rx_queue_release        = virtio_dev_rx_queue_release,
-	.tx_queue_setup          = virtio_dev_tx_queue_setup,
+	.rx_queue_release	 = virtio_dev_rx_queue_release,
+	.tx_queue_setup		 = virtio_dev_tx_queue_setup,
 	/* meaningfull only to multiple queue */
-	.tx_queue_release        = virtio_dev_tx_queue_release,
+	.tx_queue_release	 = virtio_dev_tx_queue_release,
 	/* collect stats per queue */
 	.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
 };
@@ -466,6 +475,63 @@ virtio_dev_atomic_write_link_status(stru
 	return 0;
 }
 
+/* Control receive processing (ie multicast, promiscious, mac address). */
+static int virtio_ctrl_rx(struct virtio_hw *hw, uint8_t cmd, uint8_t onoff)
+{
+	struct virtio_pmd_ctrl ctrl;
+	int len, ret;
+
+	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX))
+		return -ENOTSUP;
+
+	ctrl.hdr.class = VIRTIO_NET_CTRL_RX;
+	ctrl.hdr.cmd = cmd;
+	memcpy(ctrl.data, &onoff, sizeof(uint8_t));
+
+	len = sizeof(uint8_t);
+	ret = virtio_send_command(hw->cvq, &ctrl, &len, 1);
+	if (ret != 0)
+		PMD_DRV_LOG(NOTICE, "ctrl_rx %u failed: %d\n", cmd, ret);
+
+	return ret;
+}
+
+static void
+virtio_promiscuous_enable(struct rte_eth_dev *dev)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(DEBUG, "promiscious enable");
+	virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_PROMISC, 1);
+}
+
+static void
+virtio_promiscuous_disable(struct rte_eth_dev *dev)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(DEBUG, "promiscious disable");
+	virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_PROMISC, 0);
+}
+
+static void
+virtio_allmulticast_enable(struct rte_eth_dev *dev)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(DEBUG, "allmulticast enable");
+	virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_ALLMULTI, 1);
+}
+
+static void
+virtio_allmulticast_disable(struct rte_eth_dev *dev)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(DEBUG, "allmulticast disable");
+	virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_ALLMULTI, 0);
+}
+
 static void
 virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -559,7 +625,7 @@ virtio_negotiate_features(struct virtio_
 {
 	uint32_t host_features, mask;
 
-	mask = VIRTIO_NET_F_CTRL_RX | VIRTIO_NET_F_CTRL_VLAN;
+	mask = VIRTIO_NET_F_CTRL_VLAN;
 	mask |= VIRTIO_NET_F_CSUM | VIRTIO_NET_F_GUEST_CSUM;
 
 	/* TSO and LRO are only available when their corresponding
