pfring: call enable_ring after set_cluster

Move pfring_enable_ring to the start of ReceivePfringLoop() so that
it's guaranteed to be called after all threads have called
pfring_set_cluster first.

This is necessary because pfring will already make packets available
to thread N, while thread N+1 is still registering itself. This leads
to cases where the first packet(s) of a flow are processed by a
different thread in Suricata than the later ones.

This is a race condition only at start up. New flows after the pfring
initialization is complete will not be influenced by this.

Bug #1129.
pull/881/head
Victor Julien 11 years ago
parent 845cbcce90
commit fdb1bd9668

@ -299,6 +299,16 @@ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
ptv->slot = s->slot_next;
/* we have to enable the ring here as we need to do it after all
* the threads have called pfring_set_cluster(). */
#ifdef HAVE_PFRING_ENABLE
int rc = pfring_enable_ring(ptv->pd);
if (rc != 0) {
SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable_ring failed returned %d ", rc);
SCReturnInt(TM_ECODE_FAILED);
}
#endif /* HAVE_PFRING_ENABLE */
while(1) {
if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) {
SCReturnInt(TM_ECODE_OK);
@ -514,17 +524,6 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
SC_PERF_TYPE_UINT64,
"NULL");
/* It seems that as of 4.7.1 this is required */
#ifdef HAVE_PFRING_ENABLE
rc = pfring_enable_ring(ptv->pd);
if (rc != 0) {
SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable failed returned %d ", rc);
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED;
}
#endif /* HAVE_PFRING_ENABLE */
/* A bit strange to have this here but we only have vlan information
* during reading so we need to know if we want to keep vlan during
* the capture phase */

Loading…
Cancel
Save