diff --git a/src/runmode-pfring.c b/src/runmode-pfring.c index db53b291e9..77007e5b39 100644 --- a/src/runmode-pfring.c +++ b/src/runmode-pfring.c @@ -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; diff --git a/src/source-pfring.c b/src/source-pfring.c index e532d10b76..5eb26178f4 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -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; diff --git a/src/source-pfring.h b/src/source-pfring.h index 11fc96e4d1..cfe3335ef5 100644 --- a/src/source-pfring.h +++ b/src/source-pfring.h @@ -24,6 +24,27 @@ #ifndef __SOURCE_PFRING_H__ #define __SOURCE_PFRING_H__ +#define PFRING_IFACE_NAME_LENGTH 48 + +#include +#ifdef HAVE_PFRING +#include +#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); diff --git a/src/suricata.c b/src/suricata.c index 3524bfbc0c..328ac64593 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -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 */