]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
netmap: fixed autofp mode.
authorAleksey Katargin <gureedo@gmail.com>
Thu, 16 Jul 2015 13:35:23 +0000 (18:35 +0500)
committerVictor Julien <victor@inliniac.net>
Tue, 21 Jul 2015 21:26:13 +0000 (23:26 +0200)
Previous implementation does not work with this mode.

src/source-netmap.c

index 2b42fc29fa61938c6e9683e45d9e9ee3af3f6f01..7d56e623b97dddb17ab8a3734d67da61579fe458 100644 (file)
@@ -635,7 +635,6 @@ static TmEcode NetmapWritePacket(NetmapThreadVars *ntv, Packet *p)
     /* map src ring_id to dst ring_id */
     int dst_ring_id = p->netmap_v.ring_id % ntv->ifdst->tx_rings_cnt;
     NetmapRing *txring = &ntv->ifdst->rings[dst_ring_id];
-    NetmapRing *rxring = &ntv->ifsrc->rings[p->netmap_v.ring_id];
 
     SCSpinLock(&txring->tx_lock);
 
@@ -645,21 +644,33 @@ static TmEcode NetmapWritePacket(NetmapThreadVars *ntv, Packet *p)
         return TM_ECODE_FAILED;
     }
 
-    struct netmap_slot *rs = &rxring->rx->slot[p->netmap_v.slot_id];
     struct netmap_slot *ts = &txring->tx->slot[txring->tx->cur];
 
-    /* swap slot buffers */
-    uint32_t tmp_idx;
-    tmp_idx = ts->buf_idx;
-    ts->buf_idx = rs->buf_idx;
-    rs->buf_idx = tmp_idx;
-
-    ts->len = rs->len;
-
-    ts->flags |= NS_BUF_CHANGED;
-    rs->flags |= NS_BUF_CHANGED;
+    if (ntv->flags & NETMAP_FLAG_ZERO_COPY) {
+        NetmapRing *rxring = &ntv->ifsrc->rings[p->netmap_v.ring_id];
+        struct netmap_slot *rs = &rxring->rx->slot[p->netmap_v.slot_id];
+
+        /* swap slot buffers */
+        uint32_t tmp_idx;
+        tmp_idx = ts->buf_idx;
+        ts->buf_idx = rs->buf_idx;
+        rs->buf_idx = tmp_idx;
+
+        ts->len = rs->len;
+
+        ts->flags |= NS_BUF_CHANGED;
+        rs->flags |= NS_BUF_CHANGED;
+    } else {
+        unsigned char *slot_data = (unsigned char *)NETMAP_BUF(txring->tx, ts->buf_idx);
+        memcpy(slot_data, GET_PKT_DATA(p), GET_PKT_LEN(p));
+        ts->len = GET_PKT_LEN(p);
+        ts->flags |= NS_BUF_CHANGED;
+    }
 
     txring->tx->head = txring->tx->cur = nm_ring_next(txring->tx, txring->tx->cur);
+    if ((ntv->flags & NETMAP_FLAG_ZERO_COPY) == 0) {
+        ioctl(txring->fd, NIOCTXSYNC, 0);
+    }
 
     SCSpinUnlock(&txring->tx_lock);
 
@@ -739,11 +750,6 @@ static int NetmapRingRead(NetmapThreadVars *ntv, int ring_id)
             if (PacketSetData(p, slot_data, slot->len) == -1) {
                 TmqhOutputPacketpool(ntv->tv, p);
                 SCReturnInt(NETMAP_FAILURE);
-            } else {
-                p->ReleasePacket = NetmapReleasePacket;
-                p->netmap_v.ring_id = ring_id;
-                p->netmap_v.slot_id = cur;
-                p->netmap_v.ntv = ntv;
             }
         } else {
             if (PacketCopyData(p, slot_data, slot->len) == -1) {
@@ -752,6 +758,11 @@ static int NetmapRingRead(NetmapThreadVars *ntv, int ring_id)
             }
         }
 
+        p->ReleasePacket = NetmapReleasePacket;
+        p->netmap_v.ring_id = ring_id;
+        p->netmap_v.slot_id = cur;
+        p->netmap_v.ntv = ntv;
+
         SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
                    GET_PKT_LEN(p), p, GET_PKT_DATA(p));
 
@@ -834,10 +845,13 @@ static TmEcode ReceiveNetmapLoop(ThreadVars *tv, void *data, void *slot)
                 int src_ring_id = ntv->ring_from + i;
                 NetmapRingRead(ntv, src_ring_id);
 
-                if (ntv->copy_mode != NETMAP_COPY_MODE_NONE) {
+                if ((ntv->copy_mode != NETMAP_COPY_MODE_NONE) &&
+                    (ntv->flags & NETMAP_FLAG_ZERO_COPY)) {
+
                     /* sync dst tx rings */
                     int dst_ring_id = src_ring_id % ntv->ifdst->tx_rings_cnt;
                     NetmapRing *dst_ring = &ntv->ifdst->rings[dst_ring_id];
+                    /* if locked, another loop already do sync */
                     if (SCSpinTrylock(&dst_ring->tx_lock) == 0) {
                         ioctl(dst_ring->fd, NIOCTXSYNC, 0);
                         SCSpinUnlock(&dst_ring->tx_lock);