Adding auto runmodes based on available core/cpu's. Setting thread priorities

remotes/origin/master-1.0.x
Pablo Rincon 16 years ago committed by Victor Julien
parent 34216fd3e2
commit b482471a7d

@ -11,6 +11,8 @@
#include "tm-threads.h"
#include "util-debug.h"
#include "util-time.h"
#include "util-cpu.h"
#include "util-byte.h"
#include "conf.h"
#include "queue.h"
@ -1851,3 +1853,791 @@ int RunModeIdsPfring4(DetectEngineCtx *de_ctx, char *iface) {
return 0;
}
/**
* \brief RunModeIdsPcapAuto set up the following thread packet handlers:
* - Receive thread (from iface pcap)
* - Decode thread
* - Stream thread
* - Detect: If we have only 1 cpu, it will setup one Detect thread
* If we have more than one, it will setup num_cpus - 1
* starting from the second cpu available.
* - Respond/Reject thread
* - Outputs thread
* By default the threads will use the first cpu available
* except the Detection threads if we have more than one cpu
*
* \param de_ctx pointer to the Detection Engine
* \param iface pointer to the name of the interface from which we will
* fetch the packets
* \retval 0 if all goes well. (If any problem is detected the engine will
* exit())
*/
int RunModeIdsPcapAuto(DetectEngineCtx *de_ctx, char *iface) {
SCEnter();
/* tname = Detect + cpuid, this is 11bytes length as max */
char tname[12];
uint16_t cpu = 0;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
TimeModeSetLive();
/* create the threads */
ThreadVars *tv_receivepcap = TmThreadCreatePacketHandler("ReceivePcap","packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receivepcap == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("ReceivePcap");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceivePcap\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_receivepcap,tm_module,(void *)iface);
TmThreadSetCPUAffinity(tv_receivepcap, 0);
if (TmThreadSpawn(tv_receivepcap) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_decode1 = TmThreadCreatePacketHandler("Decode1","pickup-queue","simple","decode-queue1","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("DecodePcap");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodePcap failed\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode1, 0);
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);
}
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_stream1, 0);
if (TmThreadSpawn(tv_stream1) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
for (cpu = 0; cpu < ncpus; cpu++) {
snprintf(tname, 11,"Detect%"PRIu16, cpu);
if (tname == NULL)
break;
char *thread_name = strdup(tname);
SCLogInfo("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);
}
Tm1SlotSetFunc(tv_detect_ncpu,tm_module,(void *)de_ctx);
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);
}
if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
ThreadVars *tv_rreject = TmThreadCreatePacketHandler("RespondReject","verdict-queue","simple","alert-queue","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);
}
Tm1SlotSetFunc(tv_rreject,tm_module,NULL);
TmThreadSetCPUAffinity(tv_rreject, 0);
if (TmThreadSpawn(tv_rreject) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_outputs = TmThreadCreatePacketHandler("Outputs",
"alert-queue", "simple", "packetpool", "packetpool", "varslot");
SetupOutputs(tv_outputs);
TmThreadSetCPUAffinity(tv_outputs, 0);
if (TmThreadSpawn(tv_outputs) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
return 0;
}
/**
* \brief RunModeFilePcapAuto set up the following thread packet handlers:
* - Receive thread (from pcap file)
* - Decode thread
* - Stream thread
* - Detect: If we have only 1 cpu, it will setup one Detect thread
* If we have more than one, it will setup num_cpus - 1
* starting from the second cpu available.
* - Outputs thread
* By default the threads will use the first cpu available
* except the Detection threads if we have more than one cpu
*
* \param de_ctx pointer to the Detection Engine
* \param file pointer to the name of the file from which we will fetch
* the packets
* \retval 0 if all goes well. (If any problem is detected the engine will
* exit())
*/
int RunModeFilePcapAuto(DetectEngineCtx *de_ctx, char *file) {
SCEnter();
char tname[12];
uint16_t cpu = 0;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
SCLogDebug("file %s", file);
TimeModeSetOffline();
/* create the threads */
ThreadVars *tv_receivepcap = TmThreadCreatePacketHandler("ReceivePcapFile","packetpool","packetpool","pickup-queue","simple","1slot");
if (tv_receivepcap == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("ReceivePcapFile");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceivePcap\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_receivepcap,tm_module,file);
TmThreadSetCPUAffinity(tv_receivepcap, 0);
if (TmThreadSpawn(tv_receivepcap) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_decode1 = TmThreadCreatePacketHandler("Decode1","pickup-queue","simple","decode-queue1","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("DecodePcapFile");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodePcap failed\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode1, 0);
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);
}
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_stream1, 0);
if (TmThreadSpawn(tv_stream1) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
for (cpu = 0; cpu < ncpus; cpu++) {
snprintf(tname, 11,"Detect%"PRIu16, cpu);
if (tname == NULL)
break;
char *thread_name = strdup(tname);
SCLogInfo("Assigning %s affinity to cpu %u", thread_name, cpu);
ThreadVars *tv_detect_ncpu = TmThreadCreatePacketHandler(thread_name,"stream-queue1","simple","alert-queue1","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);
}
Tm1SlotSetFunc(tv_detect_ncpu,tm_module,(void *)de_ctx);
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);
}
if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
ThreadVars *tv_outputs = TmThreadCreatePacketHandler("Outputs",
"alert-queue1", "simple", "packetpool", "packetpool", "varslot");
SetupOutputs(tv_outputs);
TmThreadSetCPUAffinity(tv_outputs, 0);
if (TmThreadSpawn(tv_outputs) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
return 0;
}
/**
* \brief RunModeIpsIPFWAuto set up the following thread packet handlers:
* - Receive thread (from IPFW)
* - Decode thread
* - Stream thread
* - Detect: If we have only 1 cpu, it will setup one Detect thread
* If we have more than one, it will setup num_cpus - 1
* starting from the second cpu available.
* - Veredict thread (IPFW)
* - Respond/Reject thread
* - Outputs thread
* By default the threads will use the first cpu available
* except the Detection threads if we have more than one cpu
*
* \param de_ctx pointer to the Detection Engine
* \retval 0 if all goes well. (If any problem is detected the engine will
* exit())
*/
int RunModeIpsIPFWAuto(DetectEngineCtx *de_ctx) {
SCEnter();
char tname[12];
uint16_t cpu = 0;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
TimeModeSetLive();
/* create the threads */
ThreadVars *tv_receiveipfw = TmThreadCreatePacketHandler("ReceiveIPFW","packetpool","packetpool","pickup-queue","simple","1slot_noinout");
if (tv_receiveipfw == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
TmModule *tm_module = TmModuleGetByName("ReceiveIPFW");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName failed for ReceiveIPFW\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_receiveipfw,tm_module,NULL);
TmThreadSetCPUAffinity(tv_receiveipfw, 0);
if (TmThreadSpawn(tv_receiveipfw) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_decode1 = TmThreadCreatePacketHandler("Decode1","pickup-queue","simple","decode-queue1","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("DecodeIPFW");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeIPFW failed\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode1, 0);
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);
}
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_stream1, 0);
if (TmThreadSpawn(tv_stream1) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
for (cpu = 0; cpu < ncpus; cpu++) {
snprintf(tname, 11,"Detect%"PRIu16, cpu);
if (tname == NULL)
break;
char *thread_name = strdup(tname);
SCLogInfo("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);
}
Tm1SlotSetFunc(tv_detect_ncpu,tm_module,(void *)de_ctx);
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);
}
if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
ThreadVars *tv_verdict = TmThreadCreatePacketHandler("Verdict","verdict-queue","simple","respond-queue","simple","1slot");
if (tv_verdict == NULL) {
printf("ERROR: TmThreadsCreate failed\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("VerdictIPFW");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictIPFW failed\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_verdict,tm_module,NULL);
TmThreadSetCPUAffinity(tv_verdict, 0);
if (TmThreadSpawn(tv_verdict) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_rreject = TmThreadCreatePacketHandler("RespondReject","respond-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);
}
Tm1SlotSetFunc(tv_rreject,tm_module,NULL);
TmThreadSetCPUAffinity(tv_rreject, 0);
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");
TmThreadSetCPUAffinity(tv_outputs, 0);
SetupOutputs(tv_outputs);
if (TmThreadSpawn(tv_outputs) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
return 0;
}
/**
* \brief RunModeIpsNFQAuto set up the following thread packet handlers:
* - Receive thread (from NFQ)
* - Decode thread
* - Stream thread
* - Detect: If we have only 1 cpu, it will setup one Detect thread
* If we have more than one, it will setup num_cpus - 1
* starting from the second cpu available.
* - Veredict thread (NFQ)
* - Respond/Reject thread
* - Outputs thread
* By default the threads will use the first cpu available
* except the Detection threads if we have more than one cpu
*
* \param de_ctx pointer to the Detection Engine
* \param nfqid pointer to the netfilter queue id
* \retval 0 if all goes well. (If any problem is detected the engine will
* exit())
*/
int RunModeIpsNFQAuto(DetectEngineCtx *de_ctx, char *nfq_id) {
SCEnter();
char tname[12];
uint16_t cpu = 0;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
TimeModeSetLive();
/* create the threads */
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);
TmThreadSetCPUAffinity(tv_receivenfq, 0);
if (TmThreadSpawn(tv_receivenfq) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_decode1 = TmThreadCreatePacketHandler("Decode1","pickup-queue","simple","decode-queue1","simple","1slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
exit(EXIT_FAILURE);
}
tm_module = TmModuleGetByName("DecodeNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(EXIT_FAILURE);
}
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode1, 0);
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);
}
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_stream1, 0);
if (TmThreadSpawn(tv_stream1) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
for (cpu = 0; cpu < ncpus; cpu++) {
snprintf(tname, 11,"Detect%"PRIu16, cpu);
if (tname == NULL)
break;
char *thread_name = strdup(tname);
SCLogInfo("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);
}
Tm1SlotSetFunc(tv_detect_ncpu,tm_module,(void *)de_ctx);
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);
}
if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
ThreadVars *tv_verdict = TmThreadCreatePacketHandler("Verdict","verdict-queue","simple","respond-queue","simple","1slot");
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);
}
Tm1SlotSetFunc(tv_verdict,tm_module,nfq_id);
TmThreadSetCPUAffinity(tv_verdict, 0);
if (TmThreadSpawn(tv_verdict) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
ThreadVars *tv_rreject = TmThreadCreatePacketHandler("RespondReject","respond-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);
}
Tm1SlotSetFunc(tv_rreject,tm_module,NULL);
TmThreadSetCPUAffinity(tv_rreject, 0);
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");
SetupOutputs(tv_outputs);
TmThreadSetCPUAffinity(tv_outputs, 0);
if (TmThreadSpawn(tv_outputs) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
return 0;
}
/**
* \brief RunModeIdsPfringAuto set up the following thread packet handlers:
* - Receive thread (from pfring)
* - Decode thread
* - Stream thread
* - Detect: If we have only 1 cpu, it will setup one Detect thread
* If we have more than one, it will setup num_cpus - 1
* starting from the second cpu available.
* - Respond/Reject thread
* - Outputs thread
* By default the threads will use the first cpu available
* except the Detection threads if we have more than one cpu
*
* \param de_ctx pointer to the Detection Engine
* \param iface pointer to the name of the network interface to listen packets
* \retval 0 if all goes well. (If any problem is detected the engine will
* exit())
*/
int RunModeIdsPfringAuto(DetectEngineCtx *de_ctx, char *iface) {
SCEnter();
char tname[12];
uint16_t cpu = 0;
/* Available cpus */
uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
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);
}
Tm1SlotSetFunc(tv_receivepfring,tm_module,(void *)iface);
TmThreadSetCPUAffinity(tv_receivepfring, 0);
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);
}
Tm1SlotSetFunc(tv_decode1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode1, 0);
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);
}
Tm1SlotSetFunc(tv_stream1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_stream1, 0);
if (TmThreadSpawn(tv_stream1) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
for (cpu = 0; cpu < ncpus; cpu++) {
snprintf(tname, 11,"Detect%"PRIu16, cpu);
if (tname == NULL)
break;
char *thread_name = strdup(tname);
SCLogInfo("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);
}
Tm1SlotSetFunc(tv_detect_ncpu,tm_module,(void *)de_ctx);
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);
}
if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
}
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);
}
Tm1SlotSetFunc(tv_rreject,tm_module,NULL);
TmThreadSetCPUAffinity(tv_rreject, 0);
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");
SetupOutputs(tv_outputs);
TmThreadSetCPUAffinity(tv_outputs, 0);
if (TmThreadSpawn(tv_outputs) != TM_ECODE_OK) {
printf("ERROR: TmThreadSpawn failed\n");
exit(EXIT_FAILURE);
}
return 0;
}

@ -6,18 +6,24 @@ void RunModeInitializeOutputs(void);
int RunModeIdsPcap(DetectEngineCtx *, char *);
int RunModeIdsPcap2(DetectEngineCtx *, char *);
int RunModeIdsPcap3(DetectEngineCtx *, char *);
int RunModeIdsPcapAuto(DetectEngineCtx *, char *);
int RunModeIpsNFQ(DetectEngineCtx *, char *);
int RunModeIpsNFQAuto(DetectEngineCtx *, char *);
int RunModeFilePcap(DetectEngineCtx *, char *);
int RunModeFilePcap2(DetectEngineCtx *, char *);
int RunModeFilePcapAuto(DetectEngineCtx *, char *);
int RunModeIdsPfring(DetectEngineCtx *, char *);
int RunModeIdsPfring2(DetectEngineCtx *, char *);
int RunModeIdsPfring3(DetectEngineCtx *, char *);
int RunModeIdsPfring4(DetectEngineCtx *, char *);
int RunModeIdsPfringAuto(DetectEngineCtx *, char *);
int RunModeIpsIPFW(DetectEngineCtx *);
int RunModeIpsIPFWAuto(DetectEngineCtx *);
void RunModeShutDown(void);
#endif /* __RUNMODES_H__ */

@ -777,30 +777,37 @@ int main(int argc, char **argv)
RunModeInitializeOutputs();
if (run_mode == MODE_PCAP_DEV) {
//RunModeIdsPcap3(de_ctx, pcap_dev);
RunModeIdsPcap2(de_ctx, pcap_dev);
//RunModeIdsPcap2(de_ctx, pcap_dev);
//RunModeIdsPcap(de_ctx, pcap_dev);
RunModeIdsPcapAuto(de_ctx, pcap_dev);
}
else if (run_mode == MODE_PCAP_FILE) {
RunModeFilePcap(de_ctx, pcap_file);
//RunModeFilePcap(de_ctx, pcap_file);
//RunModeFilePcap2(de_ctx, pcap_file);
RunModeFilePcapAuto(de_ctx, pcap_file);
}
else if (run_mode == MODE_PFRING) {
//RunModeIdsPfring3(de_ctx, pfring_dev);
//RunModeIdsPfring2(de_ctx, pfring_dev);
//RunModeIdsPfring(de_ctx, pfring_dev);
RunModeIdsPfring4(de_ctx, pfring_dev);
//RunModeIdsPfring4(de_ctx, pfring_dev);
RunModeIdsPfringAuto(de_ctx, pfring_dev);
}
else if (run_mode == MODE_NFQ) {
RunModeIpsNFQ(de_ctx, nfq_id);
//RunModeIpsNFQ(de_ctx, nfq_id);
RunModeIpsNFQAuto(de_ctx, nfq_id);
}
else if (run_mode == MODE_IPFW) {
RunModeIpsIPFW(de_ctx);
//RunModeIpsIPFW(de_ctx);
RunModeIpsIPFWAuto(de_ctx);
}
else {
SCLogError(SC_ERR_UNKNOWN_RUN_MODE, "Unknown runtime mode. Aborting");
exit(EXIT_FAILURE);
}
TmThreadPrioSummary("Suricata main()");
/* Spawn the flow manager thread */
FlowManagerThreadSpawn();

@ -10,6 +10,20 @@
#ifdef OS_FREEBSD
#include <sys/thr.h>
#define PRIO_LOW 20
#define PRIO_MEDIUM 31
#define PRIO_HIGH 40
#else
#ifdef OS_DARWIN
#include <mach/mach_init.h>
#define PRIO_LOW 20
#define PRIO_MEDIUM 31
#define PRIO_HIGH 40
#else /* LINUX */
#define PRIO_LOW 40
#define PRIO_MEDIUM 50
#define PRIO_HIGH 60
#endif /* DARWIN */
#endif /* OS_FREEBSD */
#include <pthread.h>
@ -37,12 +51,21 @@
tid; \
})
#else
#ifdef OS_DARWIN
#define SCGetThreadIdLong(...) ({ \
thread_port_t tpid; \
tpid = mach_thread_self(); \
u_long tid = (u_long)tpid; \
tid; \
})
#else
#define SCGetThreadIdLong(...) ({ \
pid_t tmpthid; \
tmpthid = syscall(SYS_gettid); \
u_long tid = (u_long)tmpthid; \
tid; \
})
#endif /* OS DARWIN*/
#endif /* OS FREEBSD */
/** Mutex Functions */

@ -55,8 +55,9 @@ typedef struct ThreadVars_ {
void *(*tm_func)(void *);
void *tm_slots;
char set_cpu_affinity; /** bool: 0 no, 1 yes */
int cpu_affinity; /** cpu or core number to set affinity to */
uint8_t thread_setup_flags;
uint16_t cpu_affinity; /** cpu or core number to set affinity to */
int thread_priority; /** priority (real time) for this thread. Look at threads.h */
/* the perf counter context and the perf counter array */
SCPerfContext sc_perf_pctx;
@ -69,5 +70,9 @@ typedef struct ThreadVars_ {
struct ThreadVars_ *prev;
} ThreadVars;
/** Thread setup flags: */
#define THREAD_SET_AFFINITY 0x01 /** CPU/Core affinity */
#define THREAD_SET_PRIORITY 0x02 /** Real time priority */
#endif /* __THREADVARS_H__ */

@ -14,6 +14,9 @@
#include "tmqh-packetpool.h"
#include "threads.h"
#include "util-debug.h"
#include <pthread.h>
#include <unistd.h>
#ifdef OS_FREEBSD
#include <sched.h>
@ -32,7 +35,7 @@
#endif /* OS_FREEBSD */
/* prototypes */
static int SetCPUAffinity(int cpu);
static int SetCPUAffinity(uint16_t cpu);
/* root of the threadvars list */
ThreadVars *tv_root[TVT_MAX] = { NULL };
@ -115,8 +118,8 @@ void *TmThreadsSlot1NoIn(void *td) {
char run = 1;
TmEcode r = TM_ECODE_OK;
if (tv->set_cpu_affinity == 1)
SetCPUAffinity(tv->cpu_affinity);
if (tv->thread_setup_flags != 0)
TmThreadSetupOptions(tv);
if (s->s.SlotThreadInit != NULL) {
r = s->s.SlotThreadInit(tv, s->s.slot_initdata, &s->s.slot_data);
@ -179,8 +182,8 @@ void *TmThreadsSlot1NoOut(void *td) {
char run = 1;
TmEcode r = TM_ECODE_OK;
if (tv->set_cpu_affinity == 1)
SetCPUAffinity(tv->cpu_affinity);
if (tv->thread_setup_flags != 0)
TmThreadSetupOptions(tv);
if (s->s.SlotThreadInit != NULL) {
r = s->s.SlotThreadInit(tv, s->s.slot_initdata, &s->s.slot_data);
@ -236,8 +239,8 @@ void *TmThreadsSlot1NoInOut(void *td) {
char run = 1;
TmEcode r = TM_ECODE_OK;
if (tv->set_cpu_affinity == 1)
SetCPUAffinity(tv->cpu_affinity);
if (tv->thread_setup_flags != 0)
TmThreadSetupOptions(tv);
SCLogDebug("%s starting", tv->name);
@ -297,8 +300,8 @@ void *TmThreadsSlot1(void *td) {
char run = 1;
TmEcode r = TM_ECODE_OK;
if (tv->set_cpu_affinity == 1)
SetCPUAffinity(tv->cpu_affinity);
if (tv->thread_setup_flags != 0)
TmThreadSetupOptions(tv);
SCLogDebug("%s starting", tv->name);
@ -414,8 +417,8 @@ void *TmThreadsSlotVar(void *td) {
TmEcode r = TM_ECODE_OK;
TmSlot *slot = NULL;
if (tv->set_cpu_affinity == 1)
SetCPUAffinity(tv->cpu_affinity);
if (tv->thread_setup_flags != 0)
TmThreadSetupOptions(tv);
//printf("TmThreadsSlot1: %s starting\n", tv->name);
@ -575,10 +578,14 @@ void TmVarSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, void *data) {
}
}
/* called from the thread */
static int SetCPUAffinity(int cpu) {
/**
* \brief Set the thread affinity on the calling thread
* \param cpuid id of the core/cpu to setup the affinity
* \retval 0 if all goes well; -1 if something is wrong
*/
static int SetCPUAffinity(uint16_t cpuid) {
printf("Setting CPU Affinity for thread %lu to CPU %" PRId32 "\n", SCGetThreadIdLong(), cpu);
int cpu = (int)cpuid;
cpu_set_t cs;
@ -596,17 +603,73 @@ static int SetCPUAffinity(int cpu) {
if (r != 0) {
printf("Warning: sched_setaffinity failed (%" PRId32 "): %s\n", r, strerror(errno));
return -1;
}
SCLogInfo("CPU Affinity for thread %lu set to CPU %" PRId32, SCGetThreadIdLong(), cpu);
return 0;
}
TmEcode TmThreadSetCPUAffinity(ThreadVars *tv, int cpu) {
tv->set_cpu_affinity = 1;
/**
* \brief Set the thread options (thread priority)
* \param tv pointer to the ThreadVars to setup the thread priority
* \retval TM_ECOE_OK
*/
TmEcode TmThreadSetThreadPriority(ThreadVars *tv, int prio) {
tv->thread_setup_flags |= THREAD_SET_PRIORITY;
tv->thread_priority = prio;
return TM_ECODE_OK;
}
/**
* \brief Print a summary of the default thread priority, and the min and max values
* supported by the system/policy
*/
void TmThreadPrioSummary(char *tname)
{
SCEnter();
pthread_attr_t attr;
pthread_attr_init(&attr);
int my_policy;
struct sched_param my_param;
pthread_getschedparam (pthread_self (), &my_policy, &my_param);
SCLogInfo("at %s, threading policy: %s, priority %"PRId32"\n", tname,
(my_policy == SCHED_FIFO ? "Fifo" : (my_policy == SCHED_RR ? "RR"
: (my_policy == SCHED_OTHER ? "Other" : "unknown"))),
my_param.sched_priority);
SCLogInfo("at %s, Min prio: %"PRId32" Max prio: %"PRId32"", tname, sched_get_priority_min(my_policy), sched_get_priority_max(my_policy));
}
/**
* \brief Set the thread options (cpu affinity)
* \param tv pointer to the ThreadVars to setup the affinity
* \retval TM_ECOE_OK
*/
TmEcode TmThreadSetCPUAffinity(ThreadVars *tv, uint16_t cpu) {
tv->thread_setup_flags |= THREAD_SET_AFFINITY;
tv->cpu_affinity = cpu;
return TM_ECODE_OK;
}
/**
* \brief Set the thread options (cpu affinitythread)
* Priority should be already set by pthread_create
* \param tv pointer to the ThreadVars of the calling thread
*/
TmEcode TmThreadSetupOptions(ThreadVars *tv) {
if (tv->thread_setup_flags & THREAD_SET_AFFINITY) {
SCLogInfo("Setting affinity for \"%s\" Module to cpu/core %"PRIu16", thread id %lu", tv->name, tv->cpu_affinity, SCGetThreadIdLong());
SetCPUAffinity(tv->cpu_affinity);
}
TmThreadPrioSummary(tv->name);
return TM_ECODE_OK;
}
/**
* \brief Creates and returns the TV instance for a new thread.
*
@ -879,6 +942,8 @@ void TmThreadKillThreads(void) {
TmEcode TmThreadSpawn(ThreadVars *tv)
{
pthread_attr_t attr;
struct sched_param param;
int ret = 0;
if (tv->tm_func == NULL) {
printf("ERROR: no thread function set\n");
@ -887,6 +952,38 @@ TmEcode TmThreadSpawn(ThreadVars *tv)
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_getschedparam(&attr, &param);
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (ret != 0) {
SCLogInfo("Error setting thread explicit Scheduling");
} else {
if (tv->thread_setup_flags & THREAD_SET_PRIORITY) {
/* Then we need to change the policy. SCHED_OTHER doesn't allow
* to change it. So we have to choose SCHED_RR or SCHED_FIFO
*/
ret = pthread_attr_setschedpolicy(&attr, SCHED_RR);
if (ret != 0) {
SCLogInfo("Error setting thread policy to SCHED_RR");
} else {
SCLogInfo("Thread policy SCHED_RR set for thread %s. Old prio: %"PRId32, tv->name, param.sched_priority);
param.sched_priority = tv->thread_priority;
ret = pthread_attr_setschedparam(&attr, &param);
if (ret != 0) {
SCLogInfo("Error setting thread priority");
/* Get the old default priority */
pthread_attr_getschedparam(&attr, &param);
} else {
SCLogInfo("Thread priority %"PRId32" set for thread %s", tv->thread_priority, tv->name);
}
}
}
}
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int rc = pthread_create(&tv->t, &attr, tv->tm_func, (void *)tv);

@ -36,7 +36,13 @@ void TmThreadKillThreads(void);
void TmThreadAppend(ThreadVars *, int);
TmEcode TmThreadSetCPUAffinity(ThreadVars *, int);
TmEcode TmThreadSetCPUAffinity(ThreadVars *, uint16_t);
TmEcode TmThreadSetThreadPriority(ThreadVars *, int);
TmEcode TmThreadSetupOptions(ThreadVars *);
void TmThreadPrioSummary(char *);
void TmThreadInitMC(ThreadVars *);

Loading…
Cancel
Save