]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
pfring pkt acq: use zero-copy recv in workers runmode
authorcardigliano <cardigliano@ntop.org>
Wed, 21 Oct 2015 23:26:54 +0000 (01:26 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 22 Oct 2015 08:12:47 +0000 (10:12 +0200)
This patch removes packet copy when suricata is running in workers runmode,
packet copy is not needed in this case since packets are processed in sequence.

src/source-pfring.c

index 3b2b52df23e0a710f07704a5e87eba929d68af3a..bac91939abcb5e8b2b4444bdb138c1c9124a3e1c 100644 (file)
@@ -125,6 +125,10 @@ static SCMutex pfring_bpf_set_filter_lock = SCMUTEX_INITIALIZER;
 #define LIBPFRING_REENTRANT   0
 #define LIBPFRING_WAIT_FOR_INCOMING 1
 
+typedef enum {
+    PFRING_FLAGS_ZERO_COPY = 0x1
+} PfringThreadVarsFlags;
+
 /**
  * \brief Structure to hold thread specific variables.
  */
@@ -140,6 +144,8 @@ typedef struct PfringThreadVars_
     uint16_t capture_kernel_packets;
     uint16_t capture_kernel_drops;
 
+    uint32_t flags;
+
     ThreadVars *tv;
     TmSlot *slot;
 
@@ -296,6 +302,8 @@ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
     TmSlot *s = (TmSlot *)slot;
     time_t last_dump = 0;
     struct timeval current_time;
+    u_int buffer_size;
+    u_char *pkt_buffer;
 
     ptv->slot = s->slot_next;
 
@@ -325,16 +333,23 @@ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
         /* Some flavours of PF_RING may fail to set timestamp - see PF-RING-enabled libpcap code*/
         hdr.ts.tv_sec = hdr.ts.tv_usec = 0;
 
+        /* Check for Zero-copy mode */
+        if (ptv->flags & PFRING_FLAGS_ZERO_COPY) {
+            buffer_size = 0;
+            pkt_buffer = NULL;
+        } else {
+            buffer_size = GET_PKT_DIRECT_MAX_SIZE(p);
+            pkt_buffer = GET_PKT_DIRECT_DATA(p);
+        }
+
         /* Depending on what compile time options are used for pfring we either return 0 or -1 on error and always 1 for success */
-        u_char *pkt_buffer = GET_PKT_DIRECT_DATA(p);
-        u_int buffer_size = GET_PKT_DIRECT_MAX_SIZE(p);
         int r = pfring_recv(ptv->pd, &pkt_buffer,
                 buffer_size,
                 &hdr,
                 LIBPFRING_WAIT_FOR_INCOMING);
 
-        /* Check for Zero-copy if buffer size is zero */
-        if (buffer_size == 0) {
+        /* Check for Zero-copy mode */
+        if (ptv->flags & PFRING_FLAGS_ZERO_COPY) {
             PacketSetData(p, pkt_buffer, hdr.caplen);
         }
 
@@ -386,7 +401,7 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data)
     u_int32_t version = 0;
     PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata;
     unsigned int opflag;
-
+    char const *active_runmode = RunmodeGetActive();
 
     if (pfconf == NULL)
         return TM_ECODE_FAILED;
@@ -415,6 +430,12 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data)
         SCReturnInt(TM_ECODE_FAILED);
     }
 
+    /* enable zero-copy mode for workers runmode */
+    if (active_runmode && strcmp("workers", active_runmode) == 0) {
+        ptv->flags |= PFRING_FLAGS_ZERO_COPY;
+        SCLogInfo("Enabling zero-copy for %s", ptv->interface);
+    }
+
     ptv->checksum_mode = pfconf->checksum_mode;
 
     opflag = PF_RING_REENTRANT | PF_RING_PROMISC;