You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/src/runmode-napatech.c

380 lines
12 KiB
C

/* Copyright (C) 2011 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "suricata-common.h"
#include "tm-threads.h"
#include "conf.h"
#include "runmodes.h"
#include "runmode-napatech.h"
#include "log-httplog.h"
#include "output.h"
#include "alert-fastlog.h"
#include "alert-prelude.h"
#include "alert-unified2-alert.h"
#include "alert-debuglog.h"
#include "util-debug.h"
#include "util-time.h"
#include "util-cpu.h"
#include "util-affinity.h"
#include "runmode-napatech.h"
static const char *default_mode = NULL;
int RunModeNapatechAuto2(DetectEngineCtx *de_ctx);
const char *RunModeNapatechGetDefaultMode(void)
{
return default_mode;
}
void RunModeNapatechRegister(void)
{
#ifdef HAVE_NAPATECH
default_mode = "auto";
RunModeRegisterNewRunMode(RUNMODE_NAPATECH, "auto",
"Multi threaded Napatech mode",
RunModeNapatechAuto2);
return;
#endif
}
int RunModeNapatechAuto(DetectEngineCtx *de_ctx) {
#ifdef HAVE_NAPATECH
int i;
uint16_t feed, cpu;
char tname [128];
char *feedName = NULL;
char *threadName = NULL;
char *inQueueName = NULL;
char *outQueueName = NULL;
char *thread_group_name = NULL;
RunModeInitialize ();
TimeModeSetLive();
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
char *device = NULL;
if (ConfGet("napatech.adapter", &device) == 0) {
SCLogError(SC_ERR_RUNMODE, "Failed retrieving napatech.adapter from Conf");
exit(EXIT_FAILURE);
}
uint16_t adapter = atoi (device);
SCLogDebug("Napatech adapter %s", adapter);
/* 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;
int32_t feed_count = napatech_count (adapter);
if (feed_count <= 0) {
printf("ERROR: No Napatech feeds defined for adapter %i\n", adapter);
exit(EXIT_FAILURE);
}
for (feed=0; feed < feed_count; feed++) {
snprintf(tname, sizeof(tname),"%"PRIu16":%"PRIu16, adapter, feed);
feedName = SCStrdup(tname);
snprintf(tname, sizeof(tname),"Feed%"PRIu16,feed);
threadName = SCStrdup(tname);
snprintf(tname, sizeof(tname),"feed-queue%"PRIu16,feed);
outQueueName = SCStrdup(tname);
/* create the threads */
ThreadVars *tv_napatechFeed = TmThreadCreatePacketHandler(threadName,"packetpool",
"packetpool",outQueueName,
"simple","pktacqloop");
if (tv_napatechFeed == NULL) {
fprintf(stderr, "ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("NapatechFeed");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName failed for NapatechFeed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend (tv_napatechFeed,tm_module,feedName);
tm_module = TmModuleGetByName("NapatechDecode");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName failed for NapatechDecode\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_napatechFeed,tm_module,feedName);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_napatechFeed, feed);
}
if (TmThreadSpawn(tv_napatechFeed) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
/*
* -------------------------------------------
*/
/* hard code it for now */
uint16_t detect=0;
/* 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;
for (i=0; i< thread_max; i++)
{
snprintf(tname, sizeof(tname),"Detect%"PRIu16"/%"PRIu16,feed,detect++);
threadName = SCStrdup(tname);
snprintf(tname, sizeof(tname),"feed-queue%"PRIu16,feed);
inQueueName = SCStrdup(tname);
ThreadVars *tv_detect = TmThreadCreatePacketHandler(threadName,
inQueueName,"simple",
"packetpool","packetpool","varslot");
if (tv_detect == NULL) {
fprintf(stderr,"ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName StreamTcp failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_detect,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName Detect failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_detect,tm_module,(void *)de_ctx);
thread_group_name = SCStrdup("Detect");
if (thread_group_name == NULL) {
fprintf(stderr, "Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_detect->thread_group_name = thread_group_name;
SetupOutputs(tv_detect);
thread_group_name = SCStrdup("Outputs");
if (thread_group_name == NULL) {
fprintf(stderr, "Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_detect->thread_group_name = thread_group_name;
if (TmThreadSpawn(tv_detect) != TM_ECODE_OK) {
fprintf(stderr, "ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
}
#endif
return 0;
}
int RunModeNapatechAuto2(DetectEngineCtx *de_ctx) {
#ifdef HAVE_NAPATECH
int i;
uint16_t feed, cpu;
char tname [128];
char *feedName = NULL;
char *threadName = NULL;
char *inQueueName = NULL;
char *outQueueName = NULL;
char *thread_group_name = NULL;
RunModeInitialize ();
TimeModeSetLive();
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
char *device = NULL;
if (ConfGet("napatech.adapter", &device) == 0) {
SCLogError(SC_ERR_RUNMODE, "Failed retrieving napatech.adapter from Conf");
exit(EXIT_FAILURE);
}
uint16_t adapter = atoi (device);
SCLogDebug("Napatech adapter %s", adapter);
/* 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;
int32_t feed_count = napatech_count (adapter);
if (feed_count <= 0) {
printf("ERROR: No Napatech feeds defined for adapter %i\n", adapter);
exit(EXIT_FAILURE);
}
for (feed=0; feed < feed_count; feed++) {
snprintf(tname, sizeof(tname),"%"PRIu16":%"PRIu16, adapter, feed);
feedName = SCStrdup(tname);
snprintf(tname, sizeof(tname),"Feed%"PRIu16,feed);
threadName = SCStrdup(tname);
snprintf(tname, sizeof(tname),"feed-queue%"PRIu16,feed);
outQueueName = SCStrdup(tname);
/* create the threads */
ThreadVars *tv_napatechFeed = TmThreadCreatePacketHandler(threadName,"packetpool",
"packetpool","packetpool",
"packetpool","pktacqloop");
if (tv_napatechFeed == NULL) {
fprintf(stderr, "ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("NapatechFeed");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName failed for NapatechFeed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend (tv_napatechFeed,tm_module,feedName);
tm_module = TmModuleGetByName("NapatechDecode");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName failed for NapatechDecode\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_napatechFeed,tm_module,feedName);
if (threading_set_cpu_affinity) {
TmThreadSetCPUAffinity(tv_napatechFeed, feed);
}
tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName StreamTcp failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_napatechFeed,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName Detect failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_napatechFeed,tm_module,(void *)de_ctx);
thread_group_name = SCStrdup("Detect");
if (thread_group_name == NULL) {
fprintf(stderr, "Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_napatechFeed->thread_group_name = thread_group_name;
SetupOutputs(tv_napatechFeed);
thread_group_name = SCStrdup("Outputs");
if (thread_group_name == NULL) {
fprintf(stderr, "Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_napatechFeed->thread_group_name = thread_group_name;
if (TmThreadSpawn(tv_napatechFeed) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
#if 0
/*
* -------------------------------------------
*/
/* hard code it for now */
uint16_t detect=0;
/* 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;
for (i=0; i< thread_max; i++)
{
snprintf(tname, sizeof(tname),"Detect%"PRIu16"/%"PRIu16,feed,detect++);
threadName = SCStrdup(tname);
snprintf(tname, sizeof(tname),"feed-queue%"PRIu16,feed);
inQueueName = SCStrdup(tname);
ThreadVars *tv_detect = TmThreadCreatePacketHandler(threadName,
inQueueName,"simple",
"packetpool","packetpool","varslot");
if (tv_detect == NULL) {
fprintf(stderr,"ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("StreamTcp");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName StreamTcp failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_detect,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
fprintf(stderr, "ERROR: TmModuleGetByName Detect failed\n");
exit(EXIT_FAILURE);
}
TmSlotSetFuncAppend(tv_detect,tm_module,(void *)de_ctx);
thread_group_name = SCStrdup("Detect");
if (thread_group_name == NULL) {
fprintf(stderr, "Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_detect->thread_group_name = thread_group_name;
SetupOutputs(tv_detect);
thread_group_name = SCStrdup("Outputs");
if (thread_group_name == NULL) {
fprintf(stderr, "Error allocating memory\n");
exit(EXIT_FAILURE);
}
tv_detect->thread_group_name = thread_group_name;
if (TmThreadSpawn(tv_detect) != TM_ECODE_OK) {
fprintf(stderr, "ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
#endif
}
#endif /* HAVE_NAPATECH */
return 0;
}