From: Victor Julien Date: Mon, 10 Mar 2014 07:54:40 +0000 (+0100) Subject: pfring: call enable_ring after set_cluster X-Git-Tag: suricata-2.0rc3~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F881%2Fhead;p=thirdparty%2Fsuricata.git 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. --- diff --git a/src/source-pfring.c b/src/source-pfring.c index 1085cf0e1e..44c91cc61f 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -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 */