suricata
runmode-pcap-file.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include "suricata-common.h"
19 #include "tm-threads.h"
20 #include "conf.h"
21 #include "runmodes.h"
22 #include "runmode-pcap-file.h"
23 #include "output.h"
24 
25 #include "detect-engine.h"
26 #include "source-pcap-file.h"
27 
28 #include "util-debug.h"
29 #include "util-cpu.h"
30 #include "util-affinity.h"
31 
32 #include "util-runmodes.h"
33 
35 {
36  return "autofp";
37 }
38 
40 {
41  RunModeRegisterNewRunMode(RUNMODE_PCAP_FILE, "single", "Single threaded pcap file mode",
42  RunModeFilePcapSingle, NULL);
44  "Multi-threaded pcap file mode. Packets from each flow are assigned to a consistent "
45  "detection thread",
46  RunModeFilePcapAutoFp, NULL);
47 }
48 
49 /**
50  * \brief Single thread version of the Pcap file processing.
51  */
53 {
54  const char *file = NULL;
55  char tname[TM_THREAD_NAME_MAX];
56 
57  if (SCConfGetNonNull("pcap-file.file", &file) == 0) {
58  FatalError("Failed retrieving pcap-file from Conf");
59  }
60 
62 
64 
65  snprintf(tname, sizeof(tname), "%s#01", thread_name_single);
66 
67  /* create the threads */
69  "packetpool", "packetpool",
70  "packetpool", "packetpool",
71  "pktacqloop");
72  if (tv == NULL) {
73  FatalError("threading setup failed");
74  }
75 
76  TmModule *tm_module = TmModuleGetByName("ReceivePcapFile");
77  if (tm_module == NULL) {
78  FatalError("TmModuleGetByName failed for ReceivePcap");
79  }
80  TmSlotSetFuncAppend(tv, tm_module, file);
81 
82  tm_module = TmModuleGetByName("DecodePcapFile");
83  if (tm_module == NULL) {
84  FatalError("TmModuleGetByName DecodePcap failed");
85  }
86  TmSlotSetFuncAppend(tv, tm_module, NULL);
87 
88  tm_module = TmModuleGetByName("FlowWorker");
89  if (tm_module == NULL) {
90  FatalError("TmModuleGetByName for FlowWorker failed");
91  }
92  TmSlotSetFuncAppend(tv, tm_module, NULL);
93 
95 
96  if (TmThreadSpawn(tv) != TM_ECODE_OK) {
97  FatalError("TmThreadSpawn failed");
98  }
99  return 0;
100 }
101 
102 /**
103  * \brief RunModeFilePcapAutoFp set up the following thread packet handlers:
104  * - Receive thread (from pcap file)
105  * - Decode thread
106  * - Stream thread
107  * - Detect: If we have only 1 cpu, it will setup one Detect thread
108  * If we have more than one, it will setup num_cpus - 1
109  * starting from the second cpu available.
110  * - Outputs thread
111  * By default the threads will use the first cpu available
112  * except the Detection threads if we have more than one cpu.
113  *
114  * \retval 0 If all goes well. (If any problem is detected the engine will
115  * exit()).
116  */
118 {
119  SCEnter();
120  char tname[TM_THREAD_NAME_MAX];
121  char qname[TM_QUEUE_NAME_MAX];
122  uint16_t cpu = 0;
123  char *queues = NULL;
124  uint16_t thread;
125 
126  const char *file = NULL;
127  if (SCConfGetNonNull("pcap-file.file", &file) == 0) {
128  FatalError("Failed retrieving pcap-file from Conf");
129  }
130  SCLogDebug("file %s", file);
131 
133 
135 
136  /* Available cpus */
137  uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
138 
139  /* start with cpu 1 so that if we're creating an odd number of detect
140  * threads we're not creating the most on CPU0. */
141  if (ncpus > 0)
142  cpu = 1;
143 
144  /* always create at least one thread */
145  int thread_max = TmThreadGetNbThreads(WORKER_CPU_SET);
146  if (thread_max == 0)
147  thread_max = ncpus * threading_detect_ratio;
148  if (thread_max < 1)
149  thread_max = 1;
150  if (thread_max > 1024)
151  thread_max = 1024;
152 
153  queues = RunmodeAutoFpCreatePickupQueuesString(thread_max);
154  if (queues == NULL) {
155  FatalError("RunmodeAutoFpCreatePickupQueuesString failed");
156  }
157 
158  snprintf(tname, sizeof(tname), "%s#01", thread_name_autofp);
159 
160  /* create the threads */
161  ThreadVars *tv_receivepcap =
163  "packetpool", "packetpool",
164  queues, "flow",
165  "pktacqloop");
166  SCFree(queues);
167 
168  if (tv_receivepcap == NULL) {
169  FatalError("threading setup failed");
170  }
171  TmModule *tm_module = TmModuleGetByName("ReceivePcapFile");
172  if (tm_module == NULL) {
173  FatalError("TmModuleGetByName failed for ReceivePcap");
174  }
175  TmSlotSetFuncAppend(tv_receivepcap, tm_module, file);
176 
177  tm_module = TmModuleGetByName("DecodePcapFile");
178  if (tm_module == NULL) {
179  FatalError("TmModuleGetByName DecodePcap failed");
180  }
181  TmSlotSetFuncAppend(tv_receivepcap, tm_module, NULL);
182 
183  TmThreadSetCPU(tv_receivepcap, RECEIVE_CPU_SET);
184 
185  if (TmThreadSpawn(tv_receivepcap) != TM_ECODE_OK) {
186  FatalError("TmThreadSpawn failed");
187  }
188 
189  for (thread = 0; thread < (uint16_t)thread_max; thread++) {
190  snprintf(tname, sizeof(tname), "%s#%02d", thread_name_workers, thread + 1);
191  snprintf(qname, sizeof(qname), "pickup%d", thread + 1);
192 
193  SCLogDebug("tname %s, qname %s", tname, qname);
194  SCLogDebug("Assigning %s affinity to cpu %u", tname, cpu);
195 
196  ThreadVars *tv_detect_ncpu =
198  qname, "flow",
199  "packetpool", "packetpool",
200  "varslot");
201  if (tv_detect_ncpu == NULL) {
202  FatalError("TmThreadsCreate failed");
203  }
204 
205  tm_module = TmModuleGetByName("FlowWorker");
206  if (tm_module == NULL) {
207  FatalError("TmModuleGetByName for FlowWorker failed");
208  }
209  TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);
210 
211  TmThreadSetCPU(tv_detect_ncpu, WORKER_CPU_SET);
212 
213  if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
214  FatalError("TmThreadSpawn failed");
215  }
216 
217  if ((cpu + 1) == ncpus)
218  cpu = 0;
219  else
220  cpu++;
221  }
222 
223  return 0;
224 }
thread_name_workers
const char * thread_name_workers
Definition: runmodes.c:67
tm-threads.h
RECEIVE_CPU_SET
@ RECEIVE_CPU_SET
Definition: util-affinity.h:57
TmThreadSpawn
TmEcode TmThreadSpawn(ThreadVars *tv)
Spawns a thread associated with the ThreadVars instance tv.
Definition: tm-threads.c:1710
detect-engine.h
source-pcap-file.h
TmThreadCreatePacketHandler
ThreadVars * TmThreadCreatePacketHandler(const char *name, const char *inq_name, const char *inqh_name, const char *outq_name, const char *outqh_name, const char *slots)
Creates and returns a TV instance for a Packet Processing Thread. This function doesn't support custo...
Definition: tm-threads.c:1074
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
RunModeFilePcapGetDefaultMode
const char * RunModeFilePcapGetDefaultMode(void)
Definition: runmode-pcap-file.c:34
util-runmodes.h
thread_name_autofp
const char * thread_name_autofp
Definition: runmodes.c:65
WORKER_CPU_SET
@ WORKER_CPU_SET
Definition: util-affinity.h:58
thread_name_single
const char * thread_name_single
Definition: runmodes.c:66
TM_THREAD_NAME_MAX
#define TM_THREAD_NAME_MAX
Definition: tm-threads.h:49
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
TmModuleGetByName
TmModule * TmModuleGetByName(const char *name)
get a tm module ptr by name
Definition: tm-modules.c:46
util-debug.h
RunmodeAutoFpCreatePickupQueuesString
char * RunmodeAutoFpCreatePickupQueuesString(int n)
create a queue string for autofp to pass to the flow queue handler.
Definition: util-runmodes.c:56
util-cpu.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
SCConfGetNonNull
int SCConfGetNonNull(const char *name, const char **vptr)
Retrieve the non-null value of a configuration node.
Definition: conf.c:380
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
util-affinity.h
TM_QUEUE_NAME_MAX
#define TM_QUEUE_NAME_MAX
Definition: tm-threads.h:48
conf.h
RunModeRegisterNewRunMode
void RunModeRegisterNewRunMode(enum SCRunModes runmode, const char *name, const char *description, int(*RunModeFunc)(void), int(*RunModeIsIPSEnabled)(void))
Registers a new runmode.
Definition: runmodes.c:481
runmode-pcap-file.h
runmodes.h
TmModule_
Definition: tm-modules.h:47
TmSlotSetFuncAppend
void TmSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, const void *data)
Appends a new entry to the slots.
Definition: tm-threads.c:668
TimeModeSetOffline
void TimeModeSetOffline(void)
Definition: util-time.c:105
suricata-common.h
TmThreadSetCPU
TmEcode TmThreadSetCPU(ThreadVars *tv, uint8_t type)
Definition: tm-threads.c:841
TmThreadGetNbThreads
int TmThreadGetNbThreads(uint8_t type)
Definition: tm-threads.c:857
RunModeFilePcapSingle
int RunModeFilePcapSingle(void)
Single thread version of the Pcap file processing.
Definition: runmode-pcap-file.c:52
RunModeFilePcapRegister
void RunModeFilePcapRegister(void)
Definition: runmode-pcap-file.c:39
FatalError
#define FatalError(...)
Definition: util-debug.h:517
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
SCFree
#define SCFree(p)
Definition: util-mem.h:61
PcapFileGlobalInit
void PcapFileGlobalInit(void)
Definition: source-pcap-file.c:147
UtilCpuGetNumProcessorsOnline
uint16_t UtilCpuGetNumProcessorsOnline(void)
Get the number of cpus online in the system.
Definition: util-cpu.c:108
RUNMODE_PCAP_FILE
@ RUNMODE_PCAP_FILE
Definition: runmodes.h:30
threading_detect_ratio
float threading_detect_ratio
Definition: runmodes.c:953
output.h
RunModeFilePcapAutoFp
int RunModeFilePcapAutoFp(void)
RunModeFilePcapAutoFp set up the following thread packet handlers:
Definition: runmode-pcap-file.c:117