diff options
Diffstat (limited to 'framework/src/suricata/src/source-pfring.c')
-rw-r--r-- | framework/src/suricata/src/source-pfring.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/framework/src/suricata/src/source-pfring.c b/framework/src/suricata/src/source-pfring.c index 3b2b52df..527086f5 100644 --- a/framework/src/suricata/src/source-pfring.c +++ b/framework/src/suricata/src/source-pfring.c @@ -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; @@ -295,7 +301,8 @@ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot) struct pfring_pkthdr hdr; 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 +332,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); } @@ -350,10 +364,9 @@ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot) } /* Trigger one dump of stats every second */ - TimeGet(¤t_time); - if (current_time.tv_sec != last_dump) { + if (p->ts.tv_sec != last_dump) { PfringDumpCounters(ptv); - last_dump = current_time.tv_sec; + last_dump = p->ts.tv_sec; } } else { SCLogError(SC_ERR_PF_RING_RECV,"pfring_recv error %" PRId32 "", r); @@ -386,7 +399,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,9 +428,15 @@ 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; + opflag = PF_RING_PROMISC; /* if suri uses VLAN and if we have a recent kernel, we need * to use parsed_pkt to get VLAN info */ @@ -466,8 +485,11 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) if (rc != 0) { SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster " "returned %d for cluster-id: %d", rc, ptv->cluster_id); - pfconf->DerefFunc(pfconf); - return TM_ECODE_FAILED; + if (rc != PF_RING_ERROR_NOT_SUPPORTED || (pfconf->flags & PFRING_CONF_FLAGS_CLUSTER)) { + /* cluster is mandatory as explicitly specified in the configuration */ + pfconf->DerefFunc(pfconf); + return TM_ECODE_FAILED; + } } } |