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

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

Loading…
Cancel
Save