runmode: introduce configuration dereferencing.

A devide configuration can be used by multiple threads. It is thus
necessary to wait that all threads stop using the configuration before
freeing it. This patch introduces an atomic counter and a free function
which has to be called by each thread when it will not use anymore
the structure. If the configuration is not used anymore, it is freed
by the free function.
remotes/origin/master-1.1.x
Eric Leblond 15 years ago
parent 3261b814db
commit 45d5c3ca59

@ -78,6 +78,15 @@ void RunModeIdsAFPRegister(void)
return; return;
} }
void AFPDerefConfig(void *conf)
{
AFPIfaceConfig *pfp = (AFPIfaceConfig *)conf;
/* Pcap config is used only once but cost of this low. */
if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) {
SCFree(pfp);
}
}
/** /**
* \brief extract information from config file * \brief extract information from config file
* *
@ -108,10 +117,13 @@ void *ParseAFPConfig(const char *iface)
} }
strlcpy(aconf->iface, iface, sizeof(aconf->iface)); strlcpy(aconf->iface, iface, sizeof(aconf->iface));
aconf->threads = 1; aconf->threads = 1;
SC_ATOMIC_INIT(aconf->ref);
SC_ATOMIC_ADD(aconf->ref, 1);
aconf->buffer_size = 0; aconf->buffer_size = 0;
aconf->cluster_id = 1; aconf->cluster_id = 1;
aconf->cluster_type = PACKET_FANOUT_HASH; aconf->cluster_type = PACKET_FANOUT_HASH;
aconf->promisc = 1; aconf->promisc = 1;
aconf->DerefFunc = AFPDerefConfig;
/* Find initial node */ /* Find initial node */
af_packet_node = ConfGetNode("af-packet"); af_packet_node = ConfGetNode("af-packet");
@ -138,6 +150,10 @@ void *ParseAFPConfig(const char *iface)
if (aconf->threads == 0) { if (aconf->threads == 0) {
aconf->threads = 1; aconf->threads = 1;
} }
SC_ATOMIC_RESET(aconf->ref);
SC_ATOMIC_ADD(aconf->ref, aconf->threads);
if (ConfGetChildValue(if_root, "cluster-id", &tmpclusterid) != 1) { if (ConfGetChildValue(if_root, "cluster-id", &tmpclusterid) != 1) {
SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config"); SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config");
} else { } else {

@ -39,6 +39,7 @@
#include "util-affinity.h" #include "util-affinity.h"
#include "util-device.h" #include "util-device.h"
#include "util-runmodes.h" #include "util-runmodes.h"
#include "util-atomic.h"
static const char *default_mode = NULL; static const char *default_mode = NULL;
@ -67,6 +68,18 @@ void RunModeIdsPcapRegister(void)
return; return;
} }
void PcapDerefConfig(void *conf)
{
PcapIfaceConfig *pfp = (PcapIfaceConfig *)conf;
/* Pcap config is used only once but cost of this low. */
if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) {
if (pfp->bpf_filter) {
SCFree(pfp->bpf_filter);
}
SCFree(pfp);
}
}
void *ParsePcapConfig(const char *iface) void *ParsePcapConfig(const char *iface)
{ {
@ -96,6 +109,10 @@ void *ParsePcapConfig(const char *iface)
aconf->bpf_filter = tmpbpf; aconf->bpf_filter = tmpbpf;
} }
SC_ATOMIC_INIT(aconf->ref);
SC_ATOMIC_ADD(aconf->ref, 1);
aconf->DerefFunc = PcapDerefConfig;
/* Find initial node */ /* Find initial node */
pcap_node = ConfGetNode("pcap"); pcap_node = ConfGetNode("pcap");
if (pcap_node == NULL) { if (pcap_node == NULL) {

@ -75,6 +75,14 @@ void RunModeIdsPfringRegister(void)
return; return;
} }
void PfringDerefConfig(void *conf)
{
PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf;
if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) {
SCFree(pfp);
}
}
/** /**
* \brief extract information from config file * \brief extract information from config file
* *
@ -111,6 +119,9 @@ void *OldParsePfringConfig(const char *iface)
#ifdef HAVE_PFRING_CLUSTER_TYPE #ifdef HAVE_PFRING_CLUSTER_TYPE
pfconf->ctype = (cluster_type)default_ctype; pfconf->ctype = (cluster_type)default_ctype;
#endif #endif
pfconf->DerefFunc = PfringDerefConfig;
SC_ATOMIC_INIT(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, 1);
/* Find initial node */ /* Find initial node */
if (ConfGet("pfring.threads", &threadsstr) != 1) { if (ConfGet("pfring.threads", &threadsstr) != 1) {
@ -123,6 +134,10 @@ void *OldParsePfringConfig(const char *iface)
if (pfconf->threads == 0) { if (pfconf->threads == 0) {
pfconf->threads = 1; pfconf->threads = 1;
} }
SC_ATOMIC_RESET(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, pfconf->threads);
if (ConfGet("pfring.cluster-id", &tmpclusterid) != 1) { if (ConfGet("pfring.cluster-id", &tmpclusterid) != 1) {
SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config"); SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config");
} else { } else {
@ -190,6 +205,9 @@ void *ParsePfringConfig(const char *iface)
#ifdef HAVE_PFRING_CLUSTER_TYPE #ifdef HAVE_PFRING_CLUSTER_TYPE
pfconf->ctype = (cluster_type)default_ctype; pfconf->ctype = (cluster_type)default_ctype;
#endif #endif
pfconf->DerefFunc = PfringDerefConfig;
SC_ATOMIC_INIT(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, 1);
/* Find initial node */ /* Find initial node */
pf_ring_node = ConfGetNode("pfring"); pf_ring_node = ConfGetNode("pfring");
@ -220,6 +238,9 @@ void *ParsePfringConfig(const char *iface)
pfconf->threads = 1; pfconf->threads = 1;
} }
SC_ATOMIC_RESET(pfconf->ref);
SC_ATOMIC_ADD(pfconf->ref, pfconf->threads);
/* command line value has precedence */ /* command line value has precedence */
if (ConfGet("pfring.cluster-id", &tmpclusterid) == 1) { if (ConfGet("pfring.cluster-id", &tmpclusterid) == 1) {
pfconf->cluster_id = (uint16_t)atoi(tmpclusterid); pfconf->cluster_id = (uint16_t)atoi(tmpclusterid);

@ -556,8 +556,10 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
} }
AFPThreadVars *ptv = SCMalloc(sizeof(AFPThreadVars)); AFPThreadVars *ptv = SCMalloc(sizeof(AFPThreadVars));
if (ptv == NULL) if (ptv == NULL) {
afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
}
memset(ptv, 0, sizeof(AFPThreadVars)); memset(ptv, 0, sizeof(AFPThreadVars));
ptv->tv = tv; ptv->tv = tv;
@ -586,6 +588,7 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (r < 0) { if (r < 0) {
SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket"); SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket");
SCFree(ptv); SCFree(ptv);
afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
@ -599,6 +602,7 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
#define T_DATA_SIZE 70000 #define T_DATA_SIZE 70000
ptv->data = SCMalloc(T_DATA_SIZE); ptv->data = SCMalloc(T_DATA_SIZE);
if (ptv->data == NULL) { if (ptv->data == NULL) {
afpconfig->DerefFunc(afpconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
ptv->datalen = T_DATA_SIZE; ptv->datalen = T_DATA_SIZE;
@ -607,8 +611,7 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
*data = (void *)ptv; *data = (void *)ptv;
/* we've received a single use structure, we can free it */ afpconfig->DerefFunc(afpconfig);
SCFree(initdata);
SCReturnInt(TM_ECODE_OK); SCReturnInt(TM_ECODE_OK);
} }

@ -51,6 +51,8 @@ typedef struct AFPIfaceConfig_
int cluster_type; int cluster_type;
/* promisc mode */ /* promisc mode */
int promisc; int promisc;
SC_ATOMIC_DECLARE(unsigned int, ref);
void (*DerefFunc)(void *);
} AFPIfaceConfig; } AFPIfaceConfig;
void TmModuleReceiveAFPRegister (void); void TmModuleReceiveAFPRegister (void);

@ -295,8 +295,10 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
} }
PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars)); PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars));
if (ptv == NULL) if (ptv == NULL) {
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
}
memset(ptv, 0, sizeof(PcapThreadVars)); memset(ptv, 0, sizeof(PcapThreadVars));
ptv->tv = tv; ptv->tv = tv;
@ -308,6 +310,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (ptv->pcap_handle == NULL) { if (ptv->pcap_handle == NULL) {
SCLogError(SC_ERR_PCAP_CREATE, "Coudn't create a new pcap handler, error %s", pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_PCAP_CREATE, "Coudn't create a new pcap handler, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
@ -317,6 +320,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_snaplen_r != 0) { if (pcap_set_snaplen_r != 0) {
SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
@ -325,6 +329,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_promisc_r != 0) { if (pcap_set_promisc_r != 0) {
SCLogError(SC_ERR_PCAP_SET_PROMISC, "Couldn't set promisc mode, error %s", pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_PCAP_SET_PROMISC, "Couldn't set promisc mode, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
@ -333,6 +338,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_timeout_r != 0) { if (pcap_set_timeout_r != 0) {
SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "Problems setting timeout, error %s", pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "Problems setting timeout, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
#ifdef HAVE_PCAP_SET_BUFF #ifdef HAVE_PCAP_SET_BUFF
@ -345,6 +351,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_set_buffer_size_r != 0) { if (pcap_set_buffer_size_r != 0) {
SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
} }
@ -356,6 +363,7 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (pcap_activate_r != 0) { if (pcap_activate_r != 0) {
SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "Couldn't activate the pcap handler, error %s", pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "Couldn't activate the pcap handler, error %s", pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
ptv->pcap_state = PCAP_STATE_DOWN; ptv->pcap_state = PCAP_STATE_DOWN;
} else { } else {
@ -365,28 +373,34 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
/* set bpf filter if we have one */ /* set bpf filter if we have one */
if (pcapconfig->bpf_filter) { if (pcapconfig->bpf_filter) {
ptv->bpf_filter = SCStrdup(pcapconfig->bpf_filter); ptv->bpf_filter = SCStrdup(pcapconfig->bpf_filter);
/* free bpf as we are using a copy */
SCFree(pcapconfig->bpf_filter);
if(pcap_compile(ptv->pcap_handle,&ptv->filter,ptv->bpf_filter,1,0) < 0) { if(pcap_compile(ptv->pcap_handle,&ptv->filter,ptv->bpf_filter,1,0) < 0) {
SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) {
SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
} }
ptv->datalink = pcap_datalink(ptv->pcap_handle); ptv->datalink = pcap_datalink(ptv->pcap_handle);
pcapconfig->DerefFunc(pcapconfig);
*data = (void *)ptv; *data = (void *)ptv;
SCReturnInt(TM_ECODE_OK); SCReturnInt(TM_ECODE_OK);
} }
#else /* implied LIBPCAP_VERSION_MAJOR == 0 */ #else /* implied LIBPCAP_VERSION_MAJOR == 0 */
TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
SCEnter(); SCEnter();
PcapIfaceConfig *pcapconfig = initdata;
char *tmpbpfstring; char *tmpbpfstring;
if (initdata == NULL) { if (initdata == NULL) {
@ -395,8 +409,11 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
} }
PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars)); PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars));
if (ptv == NULL) if (ptv == NULL) {
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
}
memset(ptv, 0, sizeof(PcapThreadVars)); memset(ptv, 0, sizeof(PcapThreadVars));
ptv->tv = tv; ptv->tv = tv;
@ -404,6 +421,8 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
SCLogInfo("using interface %s", (char *)initdata); SCLogInfo("using interface %s", (char *)initdata);
if(strlen(initdata)>PCAP_IFACE_NAME_LENGTH) { if(strlen(initdata)>PCAP_IFACE_NAME_LENGTH) {
SCFree(ptv); SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
strlcpy(ptv->iface, (char *)initdata, PCAP_IFACE_NAME_LENGTH); strlcpy(ptv->iface, (char *)initdata, PCAP_IFACE_NAME_LENGTH);
@ -414,6 +433,8 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (ptv->pcap_handle == NULL) { if (ptv->pcap_handle == NULL) {
SCLogError(SC_ERR_PCAP_OPEN_LIVE, "Problem creating pcap handler for live mode, error %s", errbuf); SCLogError(SC_ERR_PCAP_OPEN_LIVE, "Problem creating pcap handler for live mode, error %s", errbuf);
SCFree(ptv); SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_FAILED); SCReturnInt(TM_ECODE_FAILED);
} }
@ -425,20 +446,25 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) {
if(pcap_compile(ptv->pcap_handle,&ptv->filter, ptv->bpf_filter,1,0) < 0) { if(pcap_compile(ptv->pcap_handle,&ptv->filter, ptv->bpf_filter,1,0) < 0) {
SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) {
SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle));
SCFree(ptv); SCFree(ptv);
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
} }
ptv->datalink = pcap_datalink(ptv->pcap_handle); ptv->datalink = pcap_datalink(ptv->pcap_handle);
*data = (void *)ptv; *data = (void *)ptv;
/* Dereference config */
pcapconfig->DerefFunc(pcapconfig);
SCReturnInt(TM_ECODE_OK); SCReturnInt(TM_ECODE_OK);
} }
#endif /* LIBPCAP_VERSION_MAJOR */ #endif /* LIBPCAP_VERSION_MAJOR */

@ -51,6 +51,8 @@ typedef struct PcapIfaceConfig_
int buffer_size; int buffer_size;
/* BPF filter */ /* BPF filter */
char *bpf_filter; char *bpf_filter;
SC_ATOMIC_DECLARE(unsigned int, ref);
void (*DerefFunc)(void *);
} PcapIfaceConfig; } PcapIfaceConfig;

@ -275,9 +275,15 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
char *tmpctype; char *tmpctype;
PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata; PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata;
if (pfconf == NULL)
return TM_ECODE_FAILED;
PfringThreadVars *ptv = SCMalloc(sizeof(PfringThreadVars)); PfringThreadVars *ptv = SCMalloc(sizeof(PfringThreadVars));
if (ptv == NULL) if (ptv == NULL) {
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
}
memset(ptv, 0, sizeof(PfringThreadVars)); memset(ptv, 0, sizeof(PfringThreadVars));
ptv->tv = tv; ptv->tv = tv;
@ -289,6 +295,7 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (ptv->pd == NULL) { if (ptv->pd == NULL) {
SCLogError(SC_ERR_PF_RING_OPEN,"opening %s failed: pfring_open error", SCLogError(SC_ERR_PF_RING_OPEN,"opening %s failed: pfring_open error",
ptv->interface); ptv->interface);
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} else { } else {
pfring_set_application_name(ptv->pd, PROG_NAME); pfring_set_application_name(ptv->pd, PROG_NAME);
@ -311,6 +318,7 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (rc != 0) { if (rc != 0) {
SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster " SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster "
"returned %d for cluster-id: %d", rc, ptv->cluster_id); "returned %d for cluster-id: %d", rc, ptv->cluster_id);
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
SCLogInfo("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d", SCLogInfo("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d",
@ -329,12 +337,14 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
if (rc != 0) { if (rc != 0) {
SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable failed returned %d ", rc); SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable failed returned %d ", rc);
pfconf->DerefFunc(pfconf);
return TM_ECODE_FAILED; return TM_ECODE_FAILED;
} }
#endif /* HAVE_PFRING_ENABLE */ #endif /* HAVE_PFRING_ENABLE */
*data = (void *)ptv; *data = (void *)ptv;
pfconf->DerefFunc(pfconf);
return TM_ECODE_OK; return TM_ECODE_OK;
} }

@ -41,6 +41,8 @@ typedef struct PfringIfaceConfig_
char iface[PFRING_IFACE_NAME_LENGTH]; char iface[PFRING_IFACE_NAME_LENGTH];
/* number of threads */ /* number of threads */
int threads; int threads;
SC_ATOMIC_DECLARE(unsigned int, ref);
void (*DerefFunc)(void *);
} PfringIfaceConfig; } PfringIfaceConfig;

Loading…
Cancel
Save