suricata
runmode-tile.c
Go to the documentation of this file.
1 /* Copyright (C) 2011-2013 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 /**
19  * \file
20  *
21  * \author Tom DeCanio <decanio.tom@gmail.com>
22  * \author Ken Steele, Tilera Corporation <suricata@tilera.com>
23  *
24  * Tilera TILE-Gx runmode support
25  */
26 
27 #include "suricata-common.h"
28 #include "tm-threads.h"
29 #include "conf.h"
30 #include "runmodes.h"
31 #include "runmode-tile.h"
32 #include "output.h"
33 #include "source-mpipe.h"
34 
35 #include "detect-engine.h"
36 
37 #include "util-debug.h"
38 #include "util-time.h"
39 #include "util-cpu.h"
40 #include "util-affinity.h"
41 #include "util-device.h"
42 
43 #ifdef HAVE_MPIPE
44 /* Number of configured parallel pipelines. */
46 #endif
47 
48 /*
49  * runmode support for tilegx
50  */
51 
52 static const char *mpipe_default_mode = "workers";
53 
55 {
56  return mpipe_default_mode;
57 }
58 
60 {
61 #ifdef HAVE_MPIPE
63  "Workers tilegx mpipe mode, each thread does all"
64  " tasks from acquisition to logging",
66  mpipe_default_mode = "workers";
67 #endif
68 }
69 
70 #ifdef HAVE_MPIPE
71 
72 void *ParseMpipeConfig(const char *iface)
73 {
74  ConfNode *if_root;
75  ConfNode *mpipe_node;
76  MpipeIfaceConfig *aconf = SCMalloc(sizeof(*aconf));
77  char *copymodestr;
78  char *out_iface = NULL;
79 
80  if (unlikely(aconf == NULL)) {
81  return NULL;
82  }
83 
84  if (iface == NULL) {
85  SCFree(aconf);
86  return NULL;
87  }
88 
89  strlcpy(aconf->iface, iface, sizeof(aconf->iface));
90 
91  /* Find initial node */
92  mpipe_node = ConfGetNode("mpipe.inputs");
93  if (mpipe_node == NULL) {
94  SCLogInfo("Unable to find mpipe config using default value");
95  return aconf;
96  }
97 
98  if_root = ConfNodeLookupKeyValue(mpipe_node, "interface", iface);
99  if (if_root == NULL) {
100  SCLogInfo("Unable to find mpipe config for "
101  "interface %s, using default value",
102  iface);
103  return aconf;
104  }
105 
106  if (ConfGetChildValue(if_root, "copy-iface", &out_iface) == 1) {
107  if (strlen(out_iface) > 0) {
108  aconf->out_iface = out_iface;
109  }
110  }
111  aconf->copy_mode = MPIPE_COPY_MODE_NONE;
112  if (ConfGetChildValue(if_root, "copy-mode", &copymodestr) == 1) {
113  if (aconf->out_iface == NULL) {
114  SCLogInfo("Copy mode activated but no destination"
115  " iface. Disabling feature");
116  } else if (strlen(copymodestr) <= 0) {
117  aconf->out_iface = NULL;
118  } else if (strcmp(copymodestr, "ips") == 0) {
119  SCLogInfo("MPIPE IPS mode activated %s->%s",
120  iface,
121  aconf->out_iface);
122  aconf->copy_mode = MPIPE_COPY_MODE_IPS;
123  } else if (strcmp(copymodestr, "tap") == 0) {
124  SCLogInfo("MPIPE TAP mode activated %s->%s",
125  iface,
126  aconf->out_iface);
127  aconf->copy_mode = MPIPE_COPY_MODE_TAP;
128  } else {
129  SCLogError(SC_ERR_RUNMODE, "Invalid mode (expected tap or ips)");
130  exit(EXIT_FAILURE);
131  }
132  }
133  return aconf;
134 }
135 
136 /**
137  * \brief RunModeTileMpipeWorkers set up to process all modules in each thread.
138  *
139  * \param iface pointer to the name of the interface from which we will
140  * fetch the packets
141  * \retval 0 if all goes well. (If any problem is detected the engine will
142  * exit())
143  */
144 int RunModeTileMpipeWorkers(void)
145 {
146  SCEnter();
147  char tname[TM_THREAD_NAME_MAX];
148  char *thread_name;
149  TmModule *tm_module;
150  int pipe;
151 
153 
154  /* Available cpus */
155  uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
156 
157  TimeModeSetLive();
158 
159  unsigned int pipe_max = 1;
160  if (ncpus > 1)
161  pipe_max = ncpus - 1;
162 
163  intmax_t threads;
164 
165  if (ConfGetInt("mpipe.threads", &threads) == 1) {
166  tile_num_pipelines = threads;
167  } else {
168  tile_num_pipelines = pipe_max;
169  }
170  SCLogInfo("%d Tilera worker threads", tile_num_pipelines);
171 
172  ReceiveMpipeInit();
173 
174  char *mpipe_dev = NULL;
175  int nlive = LiveGetDeviceCount();
176  if (nlive > 0) {
177  SCLogInfo("Using %d live device(s).", nlive);
178  /*mpipe_dev = LiveGetDevice(0);*/
179  } else {
180  /*
181  * Attempt to get interface from config file
182  * overrides -i from command line.
183  */
184  if (ConfGet("mpipe.interface", &mpipe_dev) == 0) {
185  if (ConfGet("mpipe.single_mpipe_dev", &mpipe_dev) == 0) {
186  SCLogError(SC_ERR_RUNMODE, "Failed retrieving "
187  "mpipe.single_mpipe_dev from Conf");
188  exit(EXIT_FAILURE);
189  }
190  }
191  }
192 
193  /* Get affinity for worker */
194  cpu_set_t cpus;
195  //int result = tmc_cpus_get_my_affinity(&cpus);
196  int result = tmc_cpus_get_dataplane_cpus(&cpus);
197  if (result < 0) {
199  "tmc_cpus_get_my_affinity() returned=%d", result);
201  }
202 
203  for (pipe = 0; pipe < tile_num_pipelines; pipe++) {
204  char *mpipe_devc;
205 
206  if (nlive > 0) {
207  mpipe_devc = SCStrdup("multi");
208  } else {
209  mpipe_devc = SCStrdup(mpipe_dev);
210  }
211  if (unlikely(mpipe_devc == NULL)) {
212  printf("ERROR: SCStrdup failed for ReceiveMpipe\n");
213  exit(EXIT_FAILURE);
214  }
215 
216  snprintf(tname, sizeof(tname), "%s#%02d", thread_name_workers, pipe+1);
217 
218  /* create the threads */
219  ThreadVars *tv_worker =
221  "packetpool", "packetpool",
222  "packetpool", "packetpool",
223  "pktacqloop");
224  if (tv_worker == NULL) {
225  printf("ERROR: TmThreadsCreate failed\n");
226  exit(EXIT_FAILURE);
227  }
228  tm_module = TmModuleGetByName("ReceiveMpipe");
229  if (tm_module == NULL) {
230  printf("ERROR: TmModuleGetByName failed for ReceiveMpipe\n");
231  exit(EXIT_FAILURE);
232  }
233  TmSlotSetFuncAppend(tv_worker, tm_module, (void *)mpipe_devc);
234 
235  /* Bind to a single cpu. */
236  int pipe_cpu = tmc_cpus_find_nth_cpu(&cpus, pipe);
237  tv_worker->rank = pipe;
238 
239  TmThreadSetCPUAffinity(tv_worker, pipe_cpu);
240 
241  tm_module = TmModuleGetByName("DecodeMpipe");
242  if (tm_module == NULL) {
243  printf("ERROR: TmModuleGetByName DecodeMpipe failed\n");
244  exit(EXIT_FAILURE);
245  }
246  TmSlotSetFuncAppend(tv_worker, tm_module, NULL);
247 
248  tm_module = TmModuleGetByName("FlowWorker");
249  if (tm_module == NULL) {
250  SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for FlowWorker failed");
251  exit(EXIT_FAILURE);
252  }
253  TmSlotSetFuncAppend(tv_worker, tm_module, NULL);
254 
255  tm_module = TmModuleGetByName("RespondReject");
256  if (tm_module == NULL) {
257  printf("ERROR: TmModuleGetByName for RespondReject failed\n");
258  exit(EXIT_FAILURE);
259  }
260  TmSlotSetFuncAppend(tv_worker, tm_module, NULL);
261 
262  SetupOutputs(tv_worker);
263 
264  if (TmThreadSpawn(tv_worker) != TM_ECODE_OK) {
265  printf("ERROR: TmThreadSpawn failed\n");
266  exit(EXIT_FAILURE);
267  }
268  }
269 
270  return 0;
271 }
272 
273 #endif
void TmSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, const void *data)
Appends a new entry to the slots.
Definition: tm-threads.c:836
ConfNode * ConfNodeLookupKeyValue(const ConfNode *base, const char *key, const char *value)
Lookup for a key value under a specific node.
Definition: conf.c:860
void RunModeInitialize(void)
Definition: runmodes.c:912
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
void RunModeRegisterNewRunMode(int runmode, const char *name, const char *description, int(*RunModeFunc)(void))
Registers a new runmode.
Definition: runmodes.c:426
#define unlikely(expr)
Definition: util-optimize.h:35
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&#39;t support custo...
Definition: tm-threads.c:1252
void TimeModeSetLive(void)
Definition: util-time.c:82
void RunModeTileMpipeRegister(void)
Definition: runmode-tile.c:59
int LiveGetDeviceCount(void)
Get the number of registered devices.
Definition: util-device.c:148
uint16_t rank
Definition: threadvars.h:95
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:331
int ConfGetChildValue(const ConfNode *base, const char *name, const char **vptr)
Definition: conf.c:388
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
#define SCEnter(...)
Definition: util-debug.h:337
int tile_num_pipelines
#define SCReturnInt(x)
Definition: util-debug.h:341
Definition: conf.h:32
int RunModeTileMpipeWorkers(void)
#define SCMalloc(a)
Definition: util-mem.h:174
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
#define SCFree(a)
Definition: util-mem.h:236
int ConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:437
#define TM_THREAD_NAME_MAX
Definition: tm-threads.h:33
TmEcode TmThreadSetCPUAffinity(ThreadVars *tv, uint16_t cpu)
Set the thread options (cpu affinity).
Definition: tm-threads.c:1031
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:176
#define SCStrdup(a)
Definition: util-mem.h:220
TmModule * TmModuleGetByName(const char *name)
get a tm module ptr by name
Definition: tm-modules.c:51
void * ParseMpipeConfig(const char *iface)
Per thread variable structure.
Definition: threadvars.h:57
uint16_t UtilCpuGetNumProcessorsOnline(void)
Get the number of cpus online in the system.
Definition: util-cpu.c:99
const char * RunModeTileMpipeGetDefaultMode(void)
Definition: runmode-tile.c:54
TmEcode TmThreadSpawn(ThreadVars *tv)
Spawns a thread associated with the ThreadVars instance tv.
Definition: tm-threads.c:1882
const char * thread_name_workers
Definition: runmodes.c:63