Add multi queue support to NFQ run mode

This patch adds support for multiple Netfilter queue
in the NFQ run mode. Suricata can now be started on
multiple queue by using a comma separated list of
queue identifier on the command line. The following syntax:
	suricata -q 0 -q 1 -c /opt/suricata/etc/suricata.yaml
will start a suricata listening to Netfilter queue 0 and 1.

Signed-off-by: Eric Leblond <eric@regit.org>
remotes/origin/master-1.1.x
Eric Leblond 15 years ago committed by Victor Julien
parent 1375e90030
commit 8330747234

@ -3155,36 +3155,54 @@ int RunModeIpsIPFWAuto(DetectEngineCtx *de_ctx) {
*/
int RunModeIpsNFQAuto(DetectEngineCtx *de_ctx, char *nfq_id) {
SCEnter();
char tname[12];
#ifdef NFQ
char tname[16];
TmModule *tm_module ;
int cur_queue = 0;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
int nqueue = NFQGetQueueCount();
RunModeInitialize();
TimeModeSetLive();
for (int i = 0; i < nqueue; i++) {
/* create the threads */
cur_queue = NFQGetQueueNum(i);
if (cur_queue == -1) {
printf("ERROR: Invalid thread number\n");
exit(EXIT_FAILURE);
}
memset(tname, 0, sizeof(tname));
snprintf(tname, sizeof(tname),"RecvNFQ-Q%"PRIu16, cur_queue);
if (tname == NULL) {
printf("ERROR: Unable to build thread name\n");
exit(EXIT_FAILURE);
}
/* receive nfq */
ThreadVars *tv_receivenfq = TmThreadCreatePacketHandler("ReceiveNFQ",
"packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivenfq == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("ReceiveNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_receivenfq,tm_module,nfq_id);
char *thread_name = SCStrdup(tname);
ThreadVars *tv_receivenfq = TmThreadCreatePacketHandler(thread_name,
"packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivenfq == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("ReceiveNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
exit(EXIT_FAILURE);
}
TmThreadSetCPU(tv_receivenfq, RECEIVE_CPU_SET);
Tm1SlotSetFunc(tv_receivenfq,tm_module, (void *) NFQGetThread(i));
if (TmThreadSpawn(tv_receivenfq) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
TmThreadSetCPU(tv_receivenfq, RECEIVE_CPU_SET);
if (TmThreadSpawn(tv_receivenfq) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
/* decode and stream */
@ -3225,6 +3243,7 @@ int RunModeIpsNFQAuto(DetectEngineCtx *de_ctx, char *nfq_id) {
int thread;
for (thread = 0; thread < thread_max; thread++) {
memset(tname, 0, sizeof(tname));
snprintf(tname, sizeof(tname),"Detect%"PRIu16, thread+1);
if (tname == NULL)
break;
@ -3260,32 +3279,43 @@ int RunModeIpsNFQAuto(DetectEngineCtx *de_ctx, char *nfq_id) {
}
}
ThreadVars *tv_verdict = TmThreadCreatePacketHandler("Verdict",
"verdict-queue","simple","alert-queue","simple","varslot");
if (tv_verdict == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(EXIT_FAILURE);
}
TmVarSlotSetFuncAppend(tv_verdict,tm_module,nfq_id);
/* create the threads */
for (int i = 0; i < nqueue; i++) {
memset(tname, 0, sizeof(tname));
snprintf(tname, sizeof(tname),"VerdictNFQ%"PRIu16, i);
if (tname == NULL) {
printf("ERROR: Unable to build thread name\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("RespondReject");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for RespondReject failed\n");
exit(EXIT_FAILURE);
}
TmVarSlotSetFuncAppend(tv_verdict,tm_module,NULL);
char *thread_name = SCStrdup(tname);
ThreadVars *tv_verdict = TmThreadCreatePacketHandler(thread_name,
"verdict-queue","simple","alert-queue","simple","varslot");
if (tv_verdict == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(EXIT_FAILURE);
}
TmVarSlotSetFuncAppend(tv_verdict,tm_module, (void *)NFQGetThread(i));
tm_module = TmModuleGetByName("RespondReject");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName for RespondReject failed\n");
exit(EXIT_FAILURE);
}
TmVarSlotSetFuncAppend(tv_verdict,tm_module,NULL);
TmThreadSetCPU(tv_verdict, VERDICT_CPU_SET);
TmThreadSetCPU(tv_verdict, VERDICT_CPU_SET);
if (TmThreadSpawn(tv_verdict) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
if (TmThreadSpawn(tv_verdict) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
};
ThreadVars *tv_outputs = TmThreadCreatePacketHandler("Outputs",
"alert-queue", "simple", "packetpool", "packetpool", "varslot");
@ -3298,6 +3328,7 @@ int RunModeIpsNFQAuto(DetectEngineCtx *de_ctx, char *nfq_id) {
exit(EXIT_FAILURE);
}
#endif /* NFQ */
return 0;
}

@ -668,7 +668,7 @@ int main(int argc, char **argv)
}
if (stat(optarg, &buf) != 0) {
SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\" "
"upplied at the commandline (-l %s) doesn't "
"supplied at the commandline (-l %s) doesn't "
"exist. Shutting down the engine.", optarg, optarg);
exit(EXIT_FAILURE);
}
@ -678,11 +678,16 @@ int main(int argc, char **argv)
if (run_mode == MODE_UNKNOWN) {
run_mode = MODE_NFQ;
SET_ENGINE_MODE_IPS(engine_mode);
if (NFQRegisterQueue(optarg) == -1)
exit(EXIT_FAILURE);
} else if (run_mode == MODE_NFQ) {
if (NFQRegisterQueue(optarg) == -1)
exit(EXIT_FAILURE);
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
usage(argv[0]);
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
}
nfq_id = optarg;
#else

Loading…
Cancel
Save