aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/source-pfring.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/suricata/src/source-pfring.c')
-rw-r--r--framework/src/suricata/src/source-pfring.c46
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(&current_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;
+ }
}
}