pfring: use factorisation function

This patch convert pfring to pktacqloop and use the new factorisation
function. This also fixes commmand line parsing of pfring which is now
able to work like af-packet:
 - 'suricata -c s.yaml --pfring' start suricata with all interfaces in
 conf
 - 'suricata -c s.yaml --pfring=eth2' start suricata on eth2
remotes/origin/master-1.1.x
Eric Leblond 15 years ago
parent cbb36b5182
commit a64dcfeba2

@ -37,6 +37,7 @@
#include "util-time.h"
#include "util-cpu.h"
#include "util-affinity.h"
#include "util-runmodes.h"
static const char *default_mode_auto = NULL;
static const char *default_mode_autofp = NULL;
@ -44,11 +45,7 @@ static const char *default_mode_autofp = NULL;
const char *RunModeIdsPfringGetDefaultMode(void)
{
#ifdef HAVE_PFRING
if (PfringConfGetThreads() <= 1) {
return default_mode_auto;
} else {
return default_mode_autofp;
}
return default_mode_autofp;
#else
return NULL;
#endif
@ -72,6 +69,103 @@ void RunModeIdsPfringRegister(void)
return;
}
/**
* \brief extract information from config file
*
* The returned structure will be freed by the thread init function.
* This is thus necessary to or copy the structure before giving it
* to thread or to reparse the file for each thread (and thus have
* new structure.
*
* If old config system is used, then return the smae parameters
* value for each interface.
*
* \return a PfringIfaceConfig corresponding to the interface name
*/
void *ParsePfringConfig(const char *iface)
{
char *threadsstr = NULL;
ConfNode *if_root;
ConfNode *pf_ring_node;
PfringIfaceConfig *pfconf = SCMalloc(sizeof(*pfconf));
char *tmpclusterid;
#ifdef HAVE_PFRING_CLUSTER_TYPE
char *tmpctype = NULL;
char * default_ctype = strdup("cluster_round_robin");
#endif
if (iface == NULL) {
return NULL;
}
if (pfconf == NULL) {
return NULL;
}
strlcpy(pfconf->iface, iface, sizeof(pfconf->iface));
pfconf->threads = 1;
pfconf->cluster_id = 1;
#ifdef HAVE_PFRING_CLUSTER_TYPE
pfconf->ctype = (cluster_type)default_ctype;
#endif
/* Find initial node */
pf_ring_node = ConfGetNode("pfring");
if (pf_ring_node == NULL) {
SCLogInfo("Unable to find pfring config using default value");
return pfconf;
}
if_root = ConfNodeLookupKeyValue(pf_ring_node, "interface", iface);
if (if_root == NULL) {
SCLogInfo("Unable to find af-packet config for "
"interface %s, using default value",
iface);
return pfconf;
}
if (ConfGetChildValue(if_root, "threads", &threadsstr) != 1) {
pfconf->threads = 1;
} else {
if (threadsstr != NULL) {
pfconf->threads = (uint8_t)atoi(threadsstr);
}
}
if (pfconf->threads == 0) {
pfconf->threads = 1;
}
if (ConfGetChildValue(if_root, "cluster-id", &tmpclusterid) != 1) {
SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config");
} else {
pfconf->cluster_id = (uint16_t)atoi(tmpclusterid);
SCLogDebug("Going to use cluster-id %" PRId32, pfconf->cluster_id);
}
#ifdef HAVE_PFRING_CLUSTER_TYPE
if (ConfGetChildValue(if_root, "cluster-type", &tmpctype) != 1) {
SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get cluster-type fron config");
} else if (strcmp(tmpctype, "cluster_round_robin") == 0) {
SCLogInfo("Using round-robin cluster mode for PF_RING (iface %s)",
pfconf->iface);
pfconf->ctype = (cluster_type)tmpctype;
} else if (strcmp(tmpctype, "cluster_flow") == 0) {
SCLogInfo("Using flow cluster mode for PF_RING (iface %s)",
pfconf->iface);
pfconf->ctype = (cluster_type)tmpctype;
} else {
SCLogError(SC_ERR_INVALID_CLUSTER_TYPE,"invalid cluster-type %s",tmpctype);
return NULL;
}
#endif
return pfconf;
}
int PfringConfigGeThreadsCount(void *conf)
{
PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf;
return pfp->threads;
}
/**
* \brief RunModeIdsPfringAuto set up the following thread packet handlers:
* - Receive thread (from pfring)
@ -95,214 +189,21 @@ int RunModeIdsPfringAuto(DetectEngineCtx *de_ctx)
SCEnter();
/* We include only if pfring is enabled */
#ifdef HAVE_PFRING
char tname[12];
uint16_t cpu = 0;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
int ret;
char live_dev = NULL;
RunModeInitialize();
TimeModeSetLive();
/* create the threads */
ThreadVars *tv_receivepfring =
TmThreadCreatePacketHandler("ReceivePfring",
"packetpool", "packetpool",
"pickup-queue1", "simple",
"1slot");
if (tv_receivepfring == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("ReceivePfring");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceivePfring\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_receivepfring, tm_module, NULL);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_receivepfring, 0);
if (ncpus > 1)
TmThreadSetThreadPriority(tv_receivepfring, PRIO_MEDIUM);
}
if (TmThreadSpawn(tv_receivepfring) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_decode1 =
TmThreadCreatePacketHandler("Decode1",
"pickup-queue1", "simple",
"decode-queue1", "simple",
"1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("DecodePfring");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodePfring failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_decode1, tm_module, NULL);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_decode1, 0);
if (ncpus > 1)
TmThreadSetThreadPriority(tv_decode1, PRIO_MEDIUM);
}
if (TmThreadSpawn(tv_decode1) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_stream1 =
TmThreadCreatePacketHandler("Stream1",
"decode-queue1", "simple",
"stream-queue1", "simple",
"1slot");
if (tv_stream1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Stream1\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName StreamTcp failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_stream1, tm_module, NULL);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_stream1, 0);
if (ncpus > 1)
TmThreadSetThreadPriority(tv_stream1, PRIO_MEDIUM);
}
if (TmThreadSpawn(tv_stream1) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
/* start with cpu 1 so that if we're creating an odd number of detect
* threads we're not creating the most on CPU0. */
if (ncpus > 0)
cpu = 1;
/* always create at least one thread */
int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET);
if (thread_max == 0)
thread_max = ncpus * threading_detect_ratio;
if (thread_max < 1)
thread_max = 1;
int thread;
for (thread = 0; thread < thread_max; thread++) {
snprintf(tname, sizeof(tname), "Detect%"PRIu16, thread+1);
char *thread_name = SCStrdup(tname);
SCLogDebug("Assigning %s affinity to cpu %u", thread_name, cpu);
ThreadVars *tv_detect_ncpu =
TmThreadCreatePacketHandler(thread_name,
"stream-queue1", "simple",
"verdict-queue", "simple",
"1slot");
if (tv_detect_ncpu == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName Detect failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, (void *)de_ctx);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_detect_ncpu, (int)cpu);
/* If we have more than one core/cpu, the first Detect thread
* (at cpu 0) will have less priority (higher 'nice' value)
* In this case we will set the thread priority to +10 (default is 0)
*/
if (cpu == 0 && ncpus > 1) {
TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_LOW);
} else if (ncpus > 1) {
TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_MEDIUM);
}
}
ConfGet("pfring.live-interface", &live_dev);
char *thread_group_name = SCStrdup("Detect");
if (thread_group_name == NULL) {
printf("Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_detect_ncpu->thread_group_name = thread_group_name;
if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
if ((cpu + 1) == ncpus)
cpu = 0;
else
cpu++;
}
ThreadVars *tv_rreject =
TmThreadCreatePacketHandler("RespondReject",
"verdict-queue", "simple",
"alert-queue1", "simple",
"1slot");
if (tv_rreject == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("RespondReject");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for RespondReject failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_rreject, tm_module, NULL);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_rreject, 0);
if (ncpus > 1)
TmThreadSetThreadPriority(tv_rreject, PRIO_MEDIUM);
}
if (TmThreadSpawn(tv_rreject) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_outputs =
TmThreadCreatePacketHandler("Outputs",
"alert-queue1", "simple",
"packetpool", "packetpool",
"varslot");
if (tv_outputs == NULL) {
printf("ERROR: TmThreadCreatePacketHandler for Outputs failed\n");
exit(EXIT_FAILURE);
}
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_outputs, 0);
if (ncpus > 1)
TmThreadSetThreadPriority(tv_outputs, PRIO_MEDIUM);
}
SetupOutputs(tv_outputs);
if (TmThreadSpawn(tv_outputs) != TM_ECODE_OK) {
ret = RunModeSetLiveCaptureAuto(de_ctx, ParsePfringConfig, "ReceivePfring", "DecodePfring",
"RxPFR", live_dev);
if (ret != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
#endif /* HAVE_PFRING */
return 0;
}
@ -313,150 +214,34 @@ int RunModeIdsPfringAutoFp(DetectEngineCtx *de_ctx)
/* We include only if pfring is enabled */
#ifdef HAVE_PFRING
char tname[12];
char qname[12];
uint16_t cpu = 0;
char queues[2048] = "";
int ret;
char *live_dev = NULL;
RunModeInitialize();
TimeModeSetLive();
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
/* start with cpu 1 so that if we're creating an odd number of detect
* threads we're not creating the most on CPU0. */
if (ncpus > 0)
cpu = 1;
/* always create at least one thread */
int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET);
if (thread_max == 0)
thread_max = ncpus * threading_detect_ratio;
if (thread_max < 1)
thread_max = 1;
int thread;
for (thread = 0; thread < thread_max; thread++) {
if (strlen(queues) > 0)
strlcat(queues, ",", sizeof(queues));
snprintf(qname, sizeof(qname),"pickup%"PRIu16, thread+1);
strlcat(queues, qname, sizeof(queues));
}
SCLogDebug("queues %s", queues);
int pfring_threads = PfringConfGetThreads();
if (pfring_threads == 0) {
pfring_threads = 1;
}
/* create the threads */
for (thread = 0; thread < pfring_threads; thread++) {
snprintf(tname, sizeof(tname), "RxPfring%"PRIu16, thread+1);
char *thread_name = SCStrdup(tname);
ThreadVars *tv_receive =
TmThreadCreatePacketHandler(thread_name,
"packetpool", "packetpool",
queues, "flow", "varslot");
if (tv_receive == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("ReceivePfring");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceivePfring\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_receive, tm_module, NULL);
tm_module = TmModuleGetByName("DecodePfring");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodePfring failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_receive, tm_module, NULL);
ConfGet("pfring.live-interface", &live_dev);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_receive, 0);
if (ncpus > 1)
TmThreadSetThreadPriority(tv_receive, PRIO_MEDIUM);
}
SCLogDebug("live_dev %s", live_dev);
if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ret = RunModeSetLiveCaptureAutoFp(de_ctx,
ParsePfringConfig,
PfringConfigGeThreadsCount,
"ReceivePfring",
"DecodePfring", "RxPFR",
live_dev);
if (ret != 0) {
printf("ERROR: Unable to start runmode\n");
if (live_dev)
SCFree(live_dev);
exit(EXIT_FAILURE);
}
for (thread = 0; thread < thread_max; thread++) {
snprintf(tname, sizeof(tname), "Detect%"PRIu16, thread+1);
snprintf(qname, sizeof(qname), "pickup%"PRIu16, thread+1);
SCLogDebug("tname %s, qname %s", tname, qname);
char *thread_name = SCStrdup(tname);
SCLogDebug("Assigning %s affinity to cpu %u", thread_name, cpu);
ThreadVars *tv_detect_ncpu =
TmThreadCreatePacketHandler(thread_name,
qname, "flow",
"packetpool", "packetpool",
"varslot");
if (tv_detect_ncpu == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName StreamTcp failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName Detect failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, (void *)de_ctx);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_detect_ncpu, (int)cpu);
/* If we have more than one core/cpu, the first Detect thread
* (at cpu 0) will have less priority (higher 'nice' value)
* In this case we will set the thread priority to +10 (default is 0)
*/
if (cpu == 0 && ncpus > 1) {
TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_LOW);
} else if (ncpus > 1) {
TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_MEDIUM);
}
}
char *thread_group_name = SCStrdup("Detect");
if (thread_group_name == NULL) {
printf("Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_detect_ncpu->thread_group_name = thread_group_name;
/* add outputs as well */
SetupOutputs(tv_detect_ncpu);
if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
if ((cpu + 1) == ncpus)
cpu = 0;
else
cpu++;
}
if (live_dev)
SCFree(live_dev);
SCLogInfo("RunModeIdsPfringAutoFp initialised");
#endif /* HAVE_PFRING */
return 0;

@ -44,7 +44,7 @@
#include "util-debug.h"
#include "util-privs.h"
TmEcode ReceivePfring(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot);
TmEcode ReceivePfringThreadInit(ThreadVars *, void *, void **);
void ReceivePfringThreadExitStats(ThreadVars *, void *);
TmEcode ReceivePfringThreadDeinit(ThreadVars *, void *);
@ -103,9 +103,6 @@ TmEcode NoPfringSupportExit(ThreadVars *tv, void *initdata, void **data)
#define LIBPFRING_REENTRANT 0
#define LIBPFRING_WAIT_FOR_INCOMING 1
int g_pfring_threads;
/**
* \brief Structure to hold thread specific variables.
*/
@ -118,6 +115,12 @@ typedef struct PfringThreadVars_
uint64_t bytes;
uint32_t pkts;
ThreadVars *tv;
TmSlot *slot;
/* threads count */
int threads;
#ifdef HAVE_PFRING_CLUSTER_TYPE
cluster_type ctype;
#endif /* HAVE_PFRING_CLUSTER_TYPE */
@ -132,7 +135,8 @@ typedef struct PfringThreadVars_
void TmModuleReceivePfringRegister (void) {
tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring";
tmm_modules[TMM_RECEIVEPFRING].ThreadInit = ReceivePfringThreadInit;
tmm_modules[TMM_RECEIVEPFRING].Func = ReceivePfring;
tmm_modules[TMM_RECEIVEPFRING].Func = NULL;
tmm_modules[TMM_RECEIVEPFRING].PktAcqLoop = ReceivePfringLoop;
tmm_modules[TMM_RECEIVEPFRING].ThreadExitPrintStats = ReceivePfringThreadExitStats;
tmm_modules[TMM_RECEIVEPFRING].ThreadDeinit = NULL;
tmm_modules[TMM_RECEIVEPFRING].RegisterTests = NULL;
@ -151,24 +155,6 @@ void TmModuleDecodePfringRegister (void) {
tmm_modules[TMM_DECODEPFRING].RegisterTests = NULL;
}
int PfringConfGetThreads(void) {
return g_pfring_threads;
}
void PfringLoadConfig(void) {
char *threadsstr = NULL;
if (ConfGet("pfring.threads", &threadsstr) != 1) {
g_pfring_threads = 1;
} else {
if (threadsstr != NULL) {
g_pfring_threads = (uint8_t)atoi(threadsstr);
SCLogInfo("Going to use %" PRId32 " PF_RING receive thread(s)",
g_pfring_threads);
}
}
}
/**
* \brief Pfring Packet Process function.
*
@ -204,40 +190,65 @@ static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Pack
*
* \param tv pointer to ThreadVars
* \param data pointer that gets cast into PfringThreadVars for ptv
* \param pq pointer to the PacketQueue (not used here but part of the api)
* \param slot slot containing task information
* \retval TM_ECODE_OK on success
* \retval TM_ECODE_FAILED on failure
*/
TmEcode ReceivePfring(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) {
TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
{
uint16_t packet_q_len = 0;
PfringThreadVars *ptv = (PfringThreadVars *)data;
TmSlot *s = (TmSlot *)slot;
ptv->slot = s->slot_next;
Packet *p = NULL;
struct pfring_pkthdr hdr;
if (suricata_ctl_flags & SURICATA_STOP ||
suricata_ctl_flags & SURICATA_KILL) {
SCReturnInt(TM_ECODE_OK);
}
SCEnter();
/* Depending on what compile time options are used for pfring we either return 0 or -1 on error and always 1 for success */
while(1) {
if (suricata_ctl_flags & SURICATA_STOP ||
suricata_ctl_flags & SURICATA_KILL) {
SCReturnInt(TM_ECODE_FAILED);
}
/* make sure we have at least one packet in the packet pool, to prevent
* us from alloc'ing packets at line rate */
do {
packet_q_len = PacketPoolSize();
if (unlikely(packet_q_len == 0)) {
PacketPoolWait();
}
} while (packet_q_len == 0);
p = PacketGetFromQueueOrAlloc();
if (p == NULL) {
SCReturnInt(TM_ECODE_FAILED);
}
/* Depending on what compile time options are used for pfring we either return 0 or -1 on error and always 1 for success */
#ifdef HAVE_PFRING_RECV_UCHAR
int r = pfring_recv(ptv->pd, (u_char**)&GET_PKT_DIRECT_DATA(p),
(u_int)GET_PKT_DIRECT_MAX_SIZE(p),
&hdr,
LIBPFRING_WAIT_FOR_INCOMING);
int r = pfring_recv(ptv->pd, (u_char**)&GET_PKT_DIRECT_DATA(p),
(u_int)GET_PKT_DIRECT_MAX_SIZE(p),
&hdr,
LIBPFRING_WAIT_FOR_INCOMING);
#else
int r = pfring_recv(ptv->pd, (char *)GET_PKT_DIRECT_DATA(p),
(u_int)GET_PKT_DIRECT_MAX_SIZE(p),
&hdr,
LIBPFRING_WAIT_FOR_INCOMING);
int r = pfring_recv(ptv->pd, (char *)GET_PKT_DIRECT_DATA(p),
(u_int)GET_PKT_DIRECT_MAX_SIZE(p),
&hdr,
LIBPFRING_WAIT_FOR_INCOMING);
#endif /* HAVE_PFRING_RECV_UCHAR */
if (r == 1) {
//printf("RecievePfring src %" PRIu32 " sport %" PRIu32 " dst %" PRIu32 " dstport %" PRIu32 "\n",
// hdr.parsed_pkt.ipv4_src,hdr.parsed_pkt.l4_src_port, hdr.parsed_pkt.ipv4_dst,hdr.parsed_pkt.l4_dst_port);
PfringProcessPacket(ptv, &hdr, p);
} else {
SCLogError(SC_ERR_PF_RING_RECV,"pfring_recv error %" PRId32 "", r);
return TM_ECODE_FAILED;
if (r == 1) {
//printf("RecievePfring src %" PRIu32 " sport %" PRIu32 " dst %" PRIu32 " dstport %" PRIu32 "\n",
// hdr.parsed_pkt.ipv4_src,hdr.parsed_pkt.l4_src_port, hdr.parsed_pkt.ipv4_dst,hdr.parsed_pkt.l4_dst_port);
PfringProcessPacket(ptv, &hdr, p);
TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p);
} else {
SCLogError(SC_ERR_PF_RING_RECV,"pfring_recv error %" PRId32 "", r);
TmqhOutputPacketpool(ptv->tv, p);
return TM_ECODE_FAILED;
}
}
return TM_ECODE_OK;
@ -262,18 +273,17 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
u_int32_t version = 0;
char *tmpclusterid;
char *tmpctype;
PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata;
PfringThreadVars *ptv = SCMalloc(sizeof(PfringThreadVars));
if (ptv == NULL)
return TM_ECODE_FAILED;
memset(ptv, 0, sizeof(PfringThreadVars));
if (ConfGet("pfring.interface", &ptv->interface) != 1) {
SCLogError(SC_ERR_PF_RING_GET_INTERFACE_FAILED,"Could not get pfring.interface");
return TM_ECODE_FAILED;
} else {
SCLogDebug("going to use interface %s",ptv->interface);
}
ptv->tv = tv;
ptv->threads = 1;
ptv->interface = strdup(pfconf->iface);
ptv->pd = pfring_open(ptv->interface, LIBPFRING_PROMISC, (uint32_t)default_packet_size, LIBPFRING_REENTRANT);
if (ptv->pd == NULL) {
@ -283,30 +293,17 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) {
} else {
pfring_set_application_name(ptv->pd, PROG_NAME);
pfring_version(ptv->pd, &version);
}
/* We only set cluster info if the number of pfring threads is greater than 1 */
if (PfringConfGetThreads() > 1) {
if (ConfGet("pfring.cluster-id", &tmpclusterid) != 1) {
SCLogError(SC_ERR_PF_RING_GET_CLUSTERID_FAILED,"could not get pfring.cluster-id");
return TM_ECODE_FAILED;
} else {
ptv->cluster_id = (uint8_t)atoi(tmpclusterid);
SCLogDebug("Going to use cluster-id %" PRId32, ptv->cluster_id);
}
ptv->threads = pfconf->threads;
if (ptv->threads > 1) {
ptv->cluster_id = pfconf->cluster_id;
#ifdef HAVE_PFRING_CLUSTER_TYPE
if (ConfGet("pfring.cluster-type", &tmpctype) != 1) {
SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get pfring.cluster-type");
return TM_ECODE_FAILED;
} else if (strcmp(tmpctype, "cluster_round_robin") == 0 || strcmp(tmpctype, "cluster_flow") == 0) {
ptv->ctype = (cluster_type)tmpctype;
rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, ptv->ctype);
} else {
SCLogError(SC_ERR_INVALID_CLUSTER_TYPE,"invalid cluster-type %s",tmpctype);
return TM_ECODE_FAILED;
}
ptv->ctype = (cluster_type)strdup((char *)pfconf->ctype);
rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, ptv->ctype);
#else
rc = pfring_set_cluster(ptv->pd, ptv->cluster_id);
#endif /* HAVE_PFRING_CLUSTER_TYPE */
@ -370,6 +367,12 @@ void ReceivePfringThreadExitStats(ThreadVars *tv, void *data) {
*/
TmEcode ReceivePfringThreadDeinit(ThreadVars *tv, void *data) {
PfringThreadVars *ptv = (PfringThreadVars *)data;
if (ptv->interface)
SCFree(ptv->interface);
#ifdef HAVE_PFRING_CLUSTER_TYPE
if (ptv->ctype)
SCFree((char *)ptv->ctype);
#endif
pfring_remove_from_cluster(ptv->pd);
pfring_close(ptv->pd);
return TM_ECODE_OK;

@ -24,6 +24,27 @@
#ifndef __SOURCE_PFRING_H__
#define __SOURCE_PFRING_H__
#define PFRING_IFACE_NAME_LENGTH 48
#include <config.h>
#ifdef HAVE_PFRING
#include <pfring.h>
#endif
typedef struct PfringIfaceConfig_
{
/* cluster param */
int cluster_id;
#ifdef HAVE_PFRING_CLUSTER_TYPE
cluster_type ctype;
#endif /* HAVE_PFRING_CLUSTER_TYPE */
char iface[PFRING_IFACE_NAME_LENGTH];
/* number of threads */
int threads;
} PfringIfaceConfig;
void TmModuleReceivePfringRegister (void);
void TmModuleDecodePfringRegister (void);

@ -683,10 +683,11 @@ int main(int argc, char **argv)
#ifdef HAVE_PFRING
run_mode = RUNMODE_PFRING;
if (optarg != NULL) {
if (ConfSet("pfring.interface", optarg, 0) != 1) {
fprintf(stderr, "ERROR: Failed to set pfring.interface.\n");
exit(EXIT_FAILURE);
}
memset(pcap_dev, 0, sizeof(pcap_dev));
strlcpy(pcap_dev, optarg,
((strlen(optarg) < sizeof(pcap_dev)) ?
(strlen(optarg) + 1) : sizeof(pcap_dev)));
LiveRegisterDevice(optarg);
}
#else
SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure "
@ -1078,6 +1079,7 @@ int main(int argc, char **argv)
case RUNMODE_PCAP_DEV:
case RUNMODE_AFP_DEV:
case RUNMODE_PFRING:
/* FIXME this don't work effficiently in multiinterface */
/* find payload for interface and use it */
default_packet_size = GetIfaceMaxPayloadSize(pcap_dev);
if (default_packet_size)
@ -1432,7 +1434,20 @@ int main(int argc, char **argv)
}
#ifdef HAVE_PFRING
} else if (run_mode == RUNMODE_PFRING) {
PfringLoadConfig();
/* FIXME add backward compat support */
/* iface has been set on command line */
if (strlen(pcap_dev)) {
if (ConfSet("pfring.live-interface", pcap_dev, 0) != 1) {
fprintf(stderr, "ERROR: Failed to set pfring.live-interface\n");
exit(EXIT_FAILURE);
}
} else {
int ret = LiveBuildIfaceList("pfring");
if (ret == 0) {
fprintf(stderr, "ERROR: No interface found in config for pfring\n");
exit(EXIT_FAILURE);
}
}
#endif /* HAVE_PFRING */
} else if (run_mode == RUNMODE_AFP_DEV) {
/* iface has been set on command line */

Loading…
Cancel
Save