diff --git a/virtio_net.c b/virtio_net.c
index 35c00c5..8aaaa7e 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -132,6 +132,10 @@ struct virtnet_info {
 	struct notifier_block nb;
 };
 
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
 struct skb_vnet_hdr {
 	union {
 		struct virtio_net_hdr hdr;
@@ -211,6 +215,10 @@ static void skb_xmit_done(struct virtqueue *vq)
 	/* Suppress further interrupts. */
 	virtqueue_disable_cb(vq);
 
+#ifdef DEV_NETMAP
+        if (netmap_tx_irq(vi->dev, vq2txq(vq)))
+		return;
+#endif
 	/* We were probably waiting for more output buffers. */
 	netif_wake_subqueue(vi->dev, vq2txq(vq));
 }
@@ -603,7 +611,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
 	struct virtnet_info *vi = rq->vq->vdev->priv;
 	void *buf;
 	unsigned int len, received = 0;
+#ifdef DEV_NETMAP
+        int work_done = 0;
 
+        if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) {
+		napi_complete(napi);
+		ND("called netmap_rx_irq");
+
+                return 1;
+        }
+#endif
 again:
 	while (received < budget &&
 	       (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
@@ -635,6 +652,16 @@ static int virtnet_open(struct net_device *dev)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
 	int i;
+#ifdef DEV_NETMAP
+        int ok = virtio_netmap_init_buffers(vi);
+
+        netmap_enable_all_rings(dev);
+        if (ok) {
+            for (i = 0; i < vi->max_queue_pairs; i++)
+		virtnet_napi_enable(&vi->rq[i]);
+            return 0;
+        }
+#endif
 
 	for (i = 0; i < vi->max_queue_pairs; i++) {
 		/* Make sure we have some buffers: if oom use wq. */
@@ -909,6 +936,9 @@ static int virtnet_close(struct net_device *dev)
 	struct virtnet_info *vi = netdev_priv(dev);
 	int i;
 
+#ifdef DEV_NETMAP
+        netmap_disable_all_rings(dev);
+#endif
 	/* Make sure refill_work doesn't re-enable napi! */
 	cancel_delayed_work_sync(&vi->refill);
 
@@ -1572,6 +1602,10 @@ static int virtnet_probe(struct virtio_device *vdev)
 		goto free_recv_bufs;
 	}
 
+#ifdef DEV_NETMAP
+        virtio_netmap_attach(vi);
+#endif
+
 	/* Assume link up if device can't report link status,
 	   otherwise get link status from config. */
 	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1618,6 +1652,9 @@ static void virtnet_remove(struct virtio_device *vdev)
 {
 	struct virtnet_info *vi = vdev->priv;
 
+#ifdef DEV_NETMAP
+        netmap_detach(vi->dev);
+#endif
 	unregister_hotcpu_notifier(&vi->nb);
 
 	/* Prevent config work handler from accessing the device. */
