suricata
runmode-af-packet.c
Go to the documentation of this file.
1 /* Copyright (C) 2011-2025 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  * \ingroup afppacket
20  *
21  * @{
22  */
23 
24 /**
25  * \file
26  *
27  * \author Eric Leblond <eric@regit.org>
28  *
29  * AF_PACKET socket runmode
30  *
31  */
32 
33 #include "suricata-common.h"
34 #include "suricata.h"
35 #include "tm-threads.h"
36 #include "conf.h"
37 #include "runmodes.h"
38 #include "runmode-af-packet.h"
39 #include "output.h"
40 #include "detect-engine-mpm.h"
41 
42 #include "alert-fastlog.h"
43 #include "alert-debuglog.h"
44 
45 #include "flow-bypass.h"
46 
47 #include "util-conf.h"
48 #include "util-debug.h"
49 #include "util-cpu.h"
50 #include "util-affinity.h"
51 #include "util-device-private.h"
52 #include "util-runmodes.h"
53 #include "util-ioctl.h"
54 #include "util-ebpf.h"
55 #include "util-byte.h"
56 
57 #include "source-af-packet.h"
58 #include "util-bpf.h"
59 
60 extern uint32_t max_pending_packets;
61 
62 const char *RunModeAFPGetDefaultMode(void)
63 {
64  return "workers";
65 }
66 
67 static bool AFPRunModeIsIPS(void)
68 {
69  int nlive = LiveGetDeviceCount();
70  bool has_ips = false;
71  bool has_ids = false;
72 
73  SCConfNode *af_packet_node = SCConfGetNode("af-packet");
74  if (af_packet_node == NULL) {
75  SCLogConfig("no 'af-packet' section in the yaml, default to IDS");
76  return false;
77  }
78 
79  SCConfNode *if_default = SCConfNodeLookupKeyValue(af_packet_node, "interface", "default");
80 
81  for (int ldev = 0; ldev < nlive; ldev++) {
82  const char *live_dev = LiveGetDeviceName(ldev);
83  if (live_dev == NULL) {
84  SCLogConfig("invalid livedev at index %d, default to IDS", ldev);
85  return false;
86  }
87  SCConfNode *if_root = ConfFindDeviceConfig(af_packet_node, live_dev);
88  if (if_root == NULL) {
89  if (if_default == NULL) {
91  "no 'af-packet' section for '%s' or 'default' in the yaml, default to IDS",
92  live_dev);
93  return false;
94  }
95  if_root = if_default;
96  }
97 
98  const char *copymodestr = NULL;
99  const char *copyifacestr = NULL;
100  if (SCConfGetChildValueWithDefault(if_root, if_default, "copy-mode", &copymodestr) == 1 &&
101  SCConfGetChildValue(if_root, "copy-iface", &copyifacestr) == 1) {
102  if (strcmp(copymodestr, "ips") == 0) {
103  has_ips = true;
104  } else {
105  has_ids = true;
106  }
107  } else {
108  has_ids = true;
109  }
110  }
111 
112  if (has_ids && has_ips) {
113  SCLogError("using both IPS and TAP/IDS mode is not allowed due to undefined behavior. See "
114  "ticket #5588.");
115  return false;
116  }
117 
118  return has_ips;
119 }
120 
121 static int AFPRunModeEnableIPS(void)
122 {
123  bool r = AFPRunModeIsIPS();
124  if (r) {
125  SCLogInfo("Setting IPS mode");
127  }
128  return r;
129 }
130 
132 {
133  RunModeRegisterNewRunMode(RUNMODE_AFP_DEV, "single", "Single threaded af-packet mode",
134  RunModeIdsAFPSingle, AFPRunModeEnableIPS);
136  "Workers af-packet mode, each thread does all"
137  " tasks from acquisition to logging",
138  RunModeIdsAFPWorkers, AFPRunModeEnableIPS);
140  "Multi socket AF_PACKET mode. Packets from "
141  "each flow are assigned to a single detect "
142  "thread.",
143  RunModeIdsAFPAutoFp, AFPRunModeEnableIPS);
144 }
145 
146 
147 #ifdef HAVE_AF_PACKET
148 
149 static void AFPDerefConfig(void *conf)
150 {
151  AFPIfaceConfig *pfp = (AFPIfaceConfig *)conf;
152  /* Pcap config is used only once but cost of this low. */
153  if (SC_ATOMIC_SUB(pfp->ref, 1) == 1) {
154  SCFree(pfp);
155  }
156 }
157 
158 /* if cluster id is not set, assign it automagically, uniq value per
159  * interface. */
160 static int cluster_id_auto = 1;
161 
162 /**
163  * \brief extract information from config file
164  *
165  * The returned structure will be freed by the thread init function.
166  * This is thus necessary to or copy the structure before giving it
167  * to thread or to reparse the file for each thread (and thus have
168  * new structure.
169  *
170  * \return a AFPIfaceConfig corresponding to the interface name
171  */
172 static void *ParseAFPConfig(const char *iface)
173 {
174  const char *threadsstr = NULL;
175  SCConfNode *if_root;
176  SCConfNode *if_default = NULL;
177  SCConfNode *af_packet_node;
178  const char *tmpclusterid;
179  const char *tmpctype;
180  const char *copymodestr;
181  intmax_t value;
182  int boolval;
183  const char *out_iface = NULL;
184  int cluster_type = PACKET_FANOUT_HASH;
185  const char *ebpf_file = NULL;
186  const char *active_runmode = RunmodeGetActive();
187 
188  if (iface == NULL) {
189  return NULL;
190  }
191 
192  AFPIfaceConfig *aconf = SCCalloc(1, sizeof(*aconf));
193  if (unlikely(aconf == NULL)) {
194  return NULL;
195  }
196 
197  strlcpy(aconf->iface, iface, sizeof(aconf->iface));
198  aconf->threads = 0;
199  SC_ATOMIC_INIT(aconf->ref);
200  (void) SC_ATOMIC_ADD(aconf->ref, 1);
201  aconf->buffer_size = 0;
202  aconf->cluster_id = 1;
203  aconf->cluster_type = cluster_type | PACKET_FANOUT_FLAG_DEFRAG;
204  aconf->promisc = 1;
206  aconf->DerefFunc = AFPDerefConfig;
207  aconf->flags = 0;
208  aconf->bpf_filter = NULL;
209  aconf->ebpf_lb_file = NULL;
210  aconf->ebpf_lb_fd = -1;
211  aconf->ebpf_filter_file = NULL;
212  aconf->ebpf_filter_fd = -1;
213  aconf->out_iface = NULL;
214  aconf->copy_mode = AFP_COPY_MODE_NONE;
215  aconf->block_timeout = 10;
216  aconf->block_size = getpagesize() << AFP_BLOCK_SIZE_DEFAULT_ORDER;
217  aconf->v2_block_size = 0;
218 #ifdef HAVE_PACKET_EBPF
219  aconf->ebpf_t_config.cpus_count = UtilCpuGetNumProcessorsConfigured();
220 #endif
221 
222  /* Find initial node */
223  af_packet_node = SCConfGetNode("af-packet");
224  if (af_packet_node == NULL) {
225  SCLogInfo("%s: unable to find af-packet config using default values", iface);
226  goto finalize;
227  }
228 
229  if_root = ConfFindDeviceConfig(af_packet_node, iface);
230  if_default = ConfFindDeviceConfig(af_packet_node, "default");
231 
232  if (if_root == NULL && if_default == NULL) {
233  SCLogInfo("%s: unable to find af-packet config for "
234  "interface \"%s\" or \"default\", using default values",
235  iface, iface);
236  goto finalize;
237  }
238 
239  /* If there is no setting for current interface use default one as main iface */
240  if (if_root == NULL) {
241  if_root = if_default;
242  if_default = NULL;
243  }
244 
245  if (active_runmode && !strcmp("single", active_runmode)) {
246  aconf->threads = 1;
247  } else if (SCConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) {
248  aconf->threads = 0;
249  } else {
250  if (threadsstr != NULL) {
251  if (strcmp(threadsstr, "auto") == 0) {
252  aconf->threads = 0;
253  } else {
254  if (StringParseUint16(&aconf->threads, 10, 0, (const char *)threadsstr) < 0) {
255  SCLogWarning("%s: invalid number of "
256  "threads, resetting to default",
257  iface);
258  aconf->threads = 0;
259  }
260  }
261  }
262  }
263 
264  if (SCConfGetChildValueWithDefault(if_root, if_default, "copy-iface", &out_iface) == 1) {
265  if (out_iface != NULL) {
266  if (strlen(out_iface) > 0) {
267  aconf->out_iface = out_iface;
268  if (strcmp(iface, out_iface) == 0) {
269  FatalError(
270  "Invalid config: interface (%s) and copy-iface (%s) can't be the same",
271  iface, out_iface);
272  }
273  }
274  } else {
275  SCLogWarning("copy-iface corresponding to %s interface cannot be NULL", iface);
276  }
277  }
278 
279  (void)SCConfGetChildValueBoolWithDefault(if_root, if_default, "mmap-locked", &boolval);
280  if (boolval) {
281  SCLogConfig("%s: enabling locked memory for mmap", aconf->iface);
282  aconf->flags |= AFP_MMAP_LOCKED;
283  }
284 
285  (void)SCConfGetChildValueBoolWithDefault(if_root, if_default, "use-emergency-flush", &boolval);
286  if (boolval) {
287  SCLogConfig("%s: using emergency ring flush", aconf->iface);
288  aconf->flags |= AFP_EMERGENCY_MODE;
289  }
290 
291  if (SCConfGetChildValueWithDefault(if_root, if_default, "copy-mode", &copymodestr) == 1) {
292  if (aconf->out_iface == NULL) {
293  SCLogWarning("%s: copy mode activated but no destination"
294  " iface. Disabling feature",
295  iface);
296  } else if (strlen(copymodestr) <= 0) {
297  aconf->out_iface = NULL;
298  } else if (strcmp(copymodestr, "ips") == 0) {
299  SCLogInfo("%s: AF_PACKET IPS mode activated %s->%s", iface, iface, aconf->out_iface);
300  aconf->copy_mode = AFP_COPY_MODE_IPS;
301  } else if (strcmp(copymodestr, "tap") == 0) {
302  SCLogInfo("%s: AF_PACKET TAP mode activated %s->%s", iface, iface, aconf->out_iface);
303  aconf->copy_mode = AFP_COPY_MODE_TAP;
304  } else {
305  SCLogWarning("Invalid 'copy-mode' (not in tap, ips)");
306  }
307  }
308 
309  if (SCConfGetChildValueBoolWithDefault(if_root, if_default, "tpacket-v3", &boolval) == 1) {
310  if (boolval) {
311  if (strcasecmp(RunmodeGetActive(), "workers") == 0) {
312  SCLogConfig("%s: enabling tpacket v3", aconf->iface);
313  aconf->flags |= AFP_TPACKET_V3;
314  } else {
315  SCLogWarning("%s: tpacket v3 is only implemented for 'workers' runmode."
316  " Switching to tpacket v2.",
317  iface);
318  aconf->flags &= ~AFP_TPACKET_V3;
319  }
320  } else {
321  aconf->flags &= ~AFP_TPACKET_V3;
322  }
323  } else if (aconf->copy_mode == AFP_COPY_MODE_NONE) {
324  // If copy mode is none (passive IDS) and "tpacket-v3" is not
325  // present, default to TPACKET_V3.
326  SCLogConfig("%s: enabling tpacket v3", aconf->iface);
327  aconf->flags |= AFP_TPACKET_V3;
328  }
329 
330  if (aconf->flags & AFP_TPACKET_V3 && aconf->copy_mode) {
331  SCLogWarning("%s: using tpacket-v3 in IPS or TAP mode will result in high latency", iface);
332  }
333 
334  if (SCConfGetChildValueWithDefault(if_root, if_default, "cluster-id", &tmpclusterid) != 1) {
335  aconf->cluster_id = (uint16_t)(cluster_id_auto++);
336  } else {
337  if (StringParseUint16(&aconf->cluster_id, 10, 0, (const char *)tmpclusterid) < 0) {
338  SCLogWarning("%s: invalid cluster_id, resetting to 0", iface);
339  aconf->cluster_id = 0;
340  }
341  SCLogDebug("Going to use cluster-id %" PRIu16, aconf->cluster_id);
342  }
343 
344  if (SCConfGetChildValueWithDefault(if_root, if_default, "cluster-type", &tmpctype) != 1) {
345  SCLogConfig("%s: using default cluster-type of \"cluster_flow\"", aconf->iface);
346  tmpctype = "cluster_flow";
347  }
348 
349  if (strcmp(tmpctype, "cluster_rollover") == 0) {
350  SCLogWarning(
351  "%s: cluster_rollover deprecated; using \"cluster_flow\" instead. See ticket #6128",
352  aconf->iface);
353  tmpctype = "cluster_flow";
354  }
355 
356  if (strcmp(tmpctype, "cluster_round_robin") == 0) {
357  SCLogConfig("%s: using round-robin cluster mode for AF_PACKET", aconf->iface);
359  cluster_type = PACKET_FANOUT_LB;
360  } else if (strcmp(tmpctype, "cluster_flow") == 0) {
361  /* Check for defrag. If not set by the user enable it when not
362  * inline. */
363  uint16_t defrag = 0;
364  int conf_val = 0;
365  SCLogConfig("%s: using flow cluster mode for AF_PACKET", aconf->iface);
366  if (SCConfGetChildValueBoolWithDefault(if_root, if_default, "defrag", &conf_val)) {
367  if (conf_val) {
368  SCLogConfig("%s: using defrag kernel functionality for AF_PACKET", aconf->iface);
369  defrag = PACKET_FANOUT_FLAG_DEFRAG;
370  }
371  } else {
372  /* "defrag" not provided in config, default to true if not inline. */
373  if (aconf->copy_mode == 0) {
374  SCLogConfig("%s: enabling defrag for AF_PACKET cluster_flow", aconf->iface);
375  defrag = PACKET_FANOUT_FLAG_DEFRAG;
376  }
377  }
378  aconf->cluster_type = PACKET_FANOUT_HASH | defrag;
379  cluster_type = PACKET_FANOUT_HASH;
380  } else if (strcmp(tmpctype, "cluster_cpu") == 0) {
381  SCLogConfig("%s: using cpu cluster mode for AF_PACKET", aconf->iface);
383  cluster_type = PACKET_FANOUT_CPU;
384  } else if (strcmp(tmpctype, "cluster_qm") == 0) {
385  SCLogConfig("%s: using queue based cluster mode for AF_PACKET", aconf->iface);
387  cluster_type = PACKET_FANOUT_QM;
388  } else if (strcmp(tmpctype, "cluster_random") == 0) {
389  SCLogConfig("%s: using random based cluster mode for AF_PACKET", aconf->iface);
391  cluster_type = PACKET_FANOUT_RND;
392 #ifdef HAVE_PACKET_EBPF
393  } else if (strcmp(tmpctype, "cluster_ebpf") == 0) {
394  SCLogInfo("%s: using ebpf based cluster mode for AF_PACKET", aconf->iface);
395  aconf->cluster_type = PACKET_FANOUT_EBPF;
396  cluster_type = PACKET_FANOUT_EBPF;
397 #endif
398  } else {
399  SCLogWarning("invalid cluster-type %s", tmpctype);
400  }
401 
402  int conf_val = 0;
403  SCConfGetChildValueBoolWithDefault(if_root, if_default, "rollover", &conf_val);
404  if (conf_val) {
405  SCLogConfig("%s: Rollover requested for AF_PACKET but ignored -- see ticket #6128.",
406  aconf->iface);
407  SCLogWarning("%s: rollover option has been deprecated and will be ignored as it can cause "
408  "severe flow "
409  "tracking issues; see ticket #6128.",
410  iface);
411  }
412 
413  ConfSetBPFFilter(if_root, if_default, iface, &aconf->bpf_filter);
414 
415  if (SCConfGetChildValueWithDefault(if_root, if_default, "ebpf-lb-file", &ebpf_file) != 1) {
416  aconf->ebpf_lb_file = NULL;
417  } else {
418 #ifdef HAVE_PACKET_EBPF
419  SCLogConfig("%s: af-packet will use '%s' as eBPF load balancing file", iface, ebpf_file);
420  aconf->ebpf_lb_file = ebpf_file;
421  aconf->ebpf_t_config.flags |= EBPF_SOCKET_FILTER;
422 #endif
423  }
424 
425 #ifdef HAVE_PACKET_EBPF
426  boolval = false;
427  if (SCConfGetChildValueBoolWithDefault(if_root, if_default, "pinned-maps", &boolval) == 1) {
428  if (boolval) {
429  SCLogConfig("%s: using pinned maps", aconf->iface);
430  aconf->ebpf_t_config.flags |= EBPF_PINNED_MAPS;
431  }
432  const char *pinned_maps_name = NULL;
434  if_root, if_default, "pinned-maps-name", &pinned_maps_name) != 1) {
435  aconf->ebpf_t_config.pinned_maps_name = pinned_maps_name;
436  } else {
437  aconf->ebpf_t_config.pinned_maps_name = NULL;
438  }
439  } else {
440  aconf->ebpf_t_config.pinned_maps_name = NULL;
441  }
442 #endif
443 
444 #ifdef HAVE_PACKET_EBPF
445  /* One shot loading of the eBPF file */
446  if (aconf->ebpf_lb_file && cluster_type == PACKET_FANOUT_EBPF) {
447  int ret = EBPFLoadFile(aconf->iface, aconf->ebpf_lb_file, "loadbalancer",
448  &aconf->ebpf_lb_fd,
449  &aconf->ebpf_t_config);
450  if (ret != 0) {
451  SCLogWarning("%s: failed to load eBPF lb file", iface);
452  }
453  }
454 #else
455  if (aconf->ebpf_lb_file) {
456  SCLogError("%s: eBPF support is not built-in", iface);
457  }
458 #endif
459 
460  if (SCConfGetChildValueWithDefault(if_root, if_default, "ebpf-filter-file", &ebpf_file) != 1) {
461  aconf->ebpf_filter_file = NULL;
462  } else {
463 #ifdef HAVE_PACKET_EBPF
464  SCLogConfig("%s: af-packet will use '%s' as eBPF filter file", iface, ebpf_file);
465  aconf->ebpf_filter_file = ebpf_file;
466  aconf->ebpf_t_config.mode = AFP_MODE_EBPF_BYPASS;
467  aconf->ebpf_t_config.flags |= EBPF_SOCKET_FILTER;
468 #endif
469  SCConfGetChildValueBoolWithDefault(if_root, if_default, "bypass", &conf_val);
470  if (conf_val) {
471 #ifdef HAVE_PACKET_EBPF
472  SCLogConfig("%s: using bypass kernel functionality for AF_PACKET", aconf->iface);
473  aconf->flags |= AFP_BYPASS;
474  BypassedFlowManagerRegisterUpdateFunc(EBPFUpdateFlow, NULL);
475 #else
476  SCLogError("%s: bypass set but eBPF support is not built-in", iface);
477 #endif
478  }
479  }
480 
481  /* One shot loading of the eBPF file */
482  if (aconf->ebpf_filter_file) {
483 #ifdef HAVE_PACKET_EBPF
484  int ret = EBPFLoadFile(aconf->iface, aconf->ebpf_filter_file, "filter",
485  &aconf->ebpf_filter_fd,
486  &aconf->ebpf_t_config);
487  if (ret != 0) {
488  SCLogWarning("%s: failed to load eBPF filter file", iface);
489  }
490 #else
491  SCLogError("%s: eBPF support is not built-in", iface);
492 #endif
493  }
494 
495  if (SCConfGetChildValueWithDefault(if_root, if_default, "xdp-filter-file", &ebpf_file) != 1) {
496  aconf->xdp_filter_file = NULL;
497  } else {
498 #ifdef HAVE_PACKET_XDP
499  aconf->ebpf_t_config.mode = AFP_MODE_XDP_BYPASS;
500  aconf->ebpf_t_config.flags |= EBPF_XDP_CODE;
501  aconf->xdp_filter_file = ebpf_file;
502  SCConfGetChildValueBoolWithDefault(if_root, if_default, "bypass", &conf_val);
503  if (conf_val) {
504  SCLogConfig("%s: using bypass kernel functionality for AF_PACKET", aconf->iface);
505  aconf->flags |= AFP_XDPBYPASS;
506  /* if maps are pinned we need to read them at start */
507  if (aconf->ebpf_t_config.flags & EBPF_PINNED_MAPS) {
509  struct ebpf_timeout_config *ebt = SCCalloc(1, sizeof(struct ebpf_timeout_config));
510  if (ebt == NULL) {
511  SCLogError("%s: flow bypass alloc error", iface);
512  } else {
513  memcpy(ebt, &(aconf->ebpf_t_config), sizeof(struct ebpf_timeout_config));
515  EBPFCheckBypassedFlowCreate,
516  (void *)ebt);
517  }
518  }
519  BypassedFlowManagerRegisterUpdateFunc(EBPFUpdateFlow, NULL);
520  }
521 #else
522  SCLogWarning("%s: XDP filter set but XDP support is not built-in", iface);
523 #endif
524 #ifdef HAVE_PACKET_XDP
525  const char *xdp_mode;
526  if (SCConfGetChildValueWithDefault(if_root, if_default, "xdp-mode", &xdp_mode) != 1) {
527  aconf->xdp_mode = XDP_FLAGS_SKB_MODE;
528  } else {
529  if (!strcmp(xdp_mode, "soft")) {
530  aconf->xdp_mode = XDP_FLAGS_SKB_MODE;
531  } else if (!strcmp(xdp_mode, "driver")) {
532  aconf->xdp_mode = XDP_FLAGS_DRV_MODE;
533  } else if (!strcmp(xdp_mode, "hw")) {
534  aconf->xdp_mode = XDP_FLAGS_HW_MODE;
535  aconf->ebpf_t_config.flags |= EBPF_XDP_HW_MODE;
536  } else {
537  SCLogWarning("Invalid xdp-mode value: '%s'", xdp_mode);
538  }
539  }
540 
541  boolval = true;
542  if (SCConfGetChildValueBoolWithDefault(if_root, if_default, "use-percpu-hash", &boolval) ==
543  1) {
544  if (!boolval) {
545  SCLogConfig("%s: not using percpu hash", aconf->iface);
546  aconf->ebpf_t_config.cpus_count = 1;
547  }
548  }
549 #endif
550  }
551 
552  /* One shot loading of the eBPF file */
553  if (aconf->xdp_filter_file) {
554 #ifdef HAVE_PACKET_XDP
555  int ret = EBPFLoadFile(aconf->iface, aconf->xdp_filter_file, "xdp",
556  &aconf->xdp_filter_fd,
557  &aconf->ebpf_t_config);
558  switch (ret) {
559  case 1:
560  SCLogInfo("%s: loaded pinned maps from sysfs", iface);
561  break;
562  case -1:
563  SCLogWarning("%s: failed to load XDP filter file", iface);
564  break;
565  case 0:
566  ret = EBPFSetupXDP(aconf->iface, aconf->xdp_filter_fd, aconf->xdp_mode);
567  if (ret != 0) {
568  SCLogWarning("%s: failed to set up XDP", iface);
569  } else {
570  /* Try to get the xdp-cpu-redirect key */
571  const char *cpuset;
573  if_root, if_default, "xdp-cpu-redirect", &cpuset) == 1) {
574  SCLogConfig("%s: Setting up CPU map XDP", iface);
575  SCConfNode *node =
576  SCConfGetChildWithDefault(if_root, if_default, "xdp-cpu-redirect");
577  if (node == NULL) {
578  SCLogError("Previously found node has disappeared");
579  } else {
580  EBPFBuildCPUSet(node, aconf->iface);
581  }
582  } else {
583  /* It will just set CPU count to 0 */
584  EBPFBuildCPUSet(NULL, aconf->iface);
585  }
586  }
587  /* we have a peer and we use bypass so we can set up XDP iface redirect */
588  if (aconf->out_iface) {
589  EBPFSetPeerIface(aconf->iface, aconf->out_iface);
590  }
591  }
592 #else
593  SCLogError("%s: XDP support is not built-in", iface);
594 #endif
595  }
596 
597  if ((SCConfGetChildValueIntWithDefault(if_root, if_default, "buffer-size", &value)) == 1) {
598  aconf->buffer_size = (int)value;
599  } else {
600  aconf->buffer_size = 0;
601  }
602  if ((SCConfGetChildValueIntWithDefault(if_root, if_default, "ring-size", &value)) == 1) {
603  aconf->ring_size = (int)value;
604  }
605 
606  if ((SCConfGetChildValueIntWithDefault(if_root, if_default, "block-size", &value)) == 1) {
607  if (value % getpagesize()) {
608  SCLogWarning("%s: block-size %" PRIuMAX " must be a multiple of pagesize (%u).", iface,
609  value, getpagesize());
610  } else {
611  aconf->block_size = (int)value;
612  }
613  }
614 
615  if ((SCConfGetChildValueIntWithDefault(if_root, if_default, "block-timeout", &value)) == 1) {
616  aconf->block_timeout = (int)value;
617  } else {
618  aconf->block_timeout = 10;
619  }
620 
621  if ((SCConfGetChildValueIntWithDefault(if_root, if_default, "v2-block-size", &value)) == 1) {
622  if (value % getpagesize()) {
623  SCLogWarning("%s: v2-block-size %" PRIuMAX " must be a multiple of pagesize (%u).",
624  iface, value, getpagesize());
625  } else {
626  aconf->v2_block_size = (int)value;
627  }
628  }
629 
630  (void)SCConfGetChildValueBoolWithDefault(if_root, if_default, "disable-promisc", &boolval);
631  if (boolval) {
632  SCLogConfig("%s: disabling promiscuous mode", aconf->iface);
633  aconf->promisc = 0;
634  }
635 
636  (void)SCConfGetChildValueBoolWithDefault(if_root, if_default, "enable-hwtimestamp", &boolval);
637  if (boolval) {
638 #ifdef HAVE_HW_TIMESTAMPING
639  SCLogConfig("%s: enabling hardware timestamping", aconf->iface);
640 #endif
641  aconf->flags |= AFP_ENABLE_HWTIMESTAMP;
642  }
643 
644  if (SCConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) {
645  if (strcmp(tmpctype, "auto") == 0) {
647  } else if (SCConfValIsTrue(tmpctype)) {
649  } else if (SCConfValIsFalse(tmpctype)) {
651  } else if (strcmp(tmpctype, "kernel") == 0) {
653  } else {
654  SCLogWarning("%s: invalid value for checksum-checks", aconf->iface);
655  }
656  }
657 
658 finalize:
659 
660  /* if the number of threads is not 1, we need to first check if fanout
661  * functions on this system. */
662  if (aconf->threads != 1) {
663  if (AFPIsFanoutSupported(aconf->cluster_id) == 0) {
664  if (aconf->threads != 0) {
665  SCLogNotice("%s: fanout not supported on this system, falling "
666  "back to 1 capture thread",
667  iface);
668  }
669  aconf->threads = 1;
670  }
671  }
672 
673  /* try to automagically set the proper number of threads */
674  if (aconf->threads == 0) {
675  /* for cluster_flow use core count */
676  if (cluster_type == PACKET_FANOUT_HASH) {
678  SCLogPerf("%s: cluster_flow: %u cores, using %u threads", iface, aconf->threads,
679  aconf->threads);
680 
681  /* for cluster_qm use RSS queue count */
682  } else if (cluster_type == PACKET_FANOUT_QM) {
683  int rss_queues = GetIfaceRSSQueuesNum(iface);
684  if (rss_queues > 0 && rss_queues <= UINT16_MAX) {
685  aconf->threads = (uint16_t)rss_queues;
686  SCLogPerf("%s: cluster_qm: %d RSS queues, using %u threads", iface, rss_queues,
687  aconf->threads);
688  }
689  }
690 
691  if (aconf->threads) {
692  SCLogDebug("using %d threads for interface %s", aconf->threads, iface);
693  }
694  }
695  if (aconf->threads <= 0) {
696  aconf->threads = 1;
697  }
698  SC_ATOMIC_RESET(aconf->ref);
699  (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads);
700 
701  if (aconf->ring_size != 0) {
702  if (aconf->ring_size * aconf->threads < (int)max_pending_packets) {
703  aconf->ring_size = max_pending_packets / aconf->threads + 1;
704  SCLogWarning("%s: inefficient setup: ring-size < max_pending_packets. "
705  "Resetting to decent value %d.",
706  iface, aconf->ring_size);
707  /* We want at least that max_pending_packets packets can be handled by the
708  * interface. This is generous if we have multiple interfaces listening. */
709  }
710  } else {
711  /* We want that max_pending_packets packets can be handled by suricata
712  * for this interface. To take burst into account we multiply the obtained
713  * size by 2. */
714  aconf->ring_size = max_pending_packets * 2 / aconf->threads;
715  }
716 
717  int ltype = AFPGetLinkType(iface);
718  switch (ltype) {
719  case LINKTYPE_ETHERNET:
720  /* af-packet can handle csum offloading */
721  if (LiveGetOffload() == 0) {
722  if (GetIfaceOffloading(iface, 0, 1) == 1) {
723  SCLogWarning(
724  "%s: using AF_PACKET with offloads enabled leads to capture problems",
725  iface);
726  }
727  } else {
729  }
730  break;
731  case -1:
732  default:
733  break;
734  }
735 
736  if (active_runmode == NULL || strcmp("workers", active_runmode) != 0) {
737  /* If we are using copy mode we need a lock */
738  aconf->flags |= AFP_SOCK_PROTECT;
739  aconf->flags |= AFP_NEED_PEER;
740  }
741 
742  /* Warn if inline and defrag is enabled. */
744  SCLogWarning(
745  "%s: AF_PACKET defrag is not recommended for inline use, please disable", iface);
746  }
747 
748  /* Warn if not inline and defrag is disabled. */
749  if (aconf->copy_mode == AFP_COPY_MODE_NONE && cluster_type == PACKET_FANOUT_HASH &&
750  ((aconf->cluster_type & PACKET_FANOUT_FLAG_DEFRAG) == 0)) {
751  SCLogWarning("%s: AF_PACKET defrag is recommended for IDS cluster_flow", iface);
752  }
753 
754  /* For tpacket-v2, warn if defrag is enabled and block-size is
755  * less than max defragmented packet size. */
756  if ((aconf->flags & AFP_TPACKET_V3) == 0 && (aconf->cluster_type & PACKET_FANOUT_FLAG_DEFRAG) &&
757  aconf->v2_block_size > 0 && aconf->v2_block_size < MAX_PACKET_SIZE) {
758  SCLogWarning("%s: AF_PACKET v2-block-size is not large enough for max fragmented IP packet "
759  "size (%u)",
760  iface, MAX_PACKET_SIZE);
761  }
762 
763  /* For tpacket-v3, warn if defrag is enabled and block-block-size
764  * is less than max defragmented packet size. */
765  if ((aconf->flags & AFP_TPACKET_V3) && (aconf->cluster_type & PACKET_FANOUT_FLAG_DEFRAG) &&
766  (aconf->block_size < MAX_PACKET_SIZE)) {
767  SCLogWarning("%s: AF_PACKET block-size is not large enough for max fragmented IP packet "
768  "size (%u)",
769  iface, MAX_PACKET_SIZE);
770  }
771 
772  /* Warn that if not-inline, tpacket-v3 is the better choice. */
773  if (aconf->copy_mode == AFP_COPY_MODE_NONE && (aconf->flags & AFP_TPACKET_V3) == 0) {
774  SCLogWarning("%s: AF_PACKET tpacket-v3 is recommended for non-inline operation", iface);
775  }
776 
777  return aconf;
778 }
779 
780 static uint16_t AFPConfigGeThreadsCount(void *conf)
781 {
782  AFPIfaceConfig *afp = (AFPIfaceConfig *)conf;
783  return afp->threads;
784 }
785 
786 #endif /* HAVE_AF_PACKET */
787 
789 {
790  SCEnter();
791 
792 /* We include only if AF_PACKET is enabled */
793 #ifdef HAVE_AF_PACKET
794  int ret;
795  const char *live_dev = NULL;
796 
797  TimeModeSetLive();
798 
799  (void)SCConfGet("af-packet.live-interface", &live_dev);
800 
801  SCLogDebug("live_dev %s", live_dev);
802 
803  if (AFPPeersListInit() != TM_ECODE_OK) {
804  FatalError("Unable to init peers list.");
805  }
806 
807  ret = RunModeSetLiveCaptureAutoFp(ParseAFPConfig, AFPConfigGeThreadsCount, "ReceiveAFP",
808  "DecodeAFP", thread_name_autofp, live_dev);
809  if (ret != 0) {
810  FatalError("Unable to start runmode");
811  }
812 
813  /* In IPS mode each threads must have a peer */
814  if (AFPPeersListCheck() != TM_ECODE_OK) {
815  FatalError("Some IPS capture threads did not peer.");
816  }
817 
818  SCLogDebug("RunModeIdsAFPAutoFp initialised");
819 #endif /* HAVE_AF_PACKET */
820 
821  SCReturnInt(0);
822 }
823 
824 /**
825  * \brief Single thread version of the AF_PACKET processing.
826  */
828 {
829  SCEnter();
830 #ifdef HAVE_AF_PACKET
831  int ret;
832  const char *live_dev = NULL;
833 
834  TimeModeSetLive();
835 
836  (void)SCConfGet("af-packet.live-interface", &live_dev);
837 
838  if (AFPPeersListInit() != TM_ECODE_OK) {
839  FatalError("Unable to init peers list.");
840  }
841 
842  ret = RunModeSetLiveCaptureSingle(ParseAFPConfig,
843  AFPConfigGeThreadsCount,
844  "ReceiveAFP",
845  "DecodeAFP", thread_name_single,
846  live_dev);
847  if (ret != 0) {
848  FatalError("Unable to start runmode");
849  }
850 
851  /* In IPS mode each threads must have a peer */
852  if (AFPPeersListCheck() != TM_ECODE_OK) {
853  FatalError("Some IPS capture threads did not peer.");
854  }
855 
856  SCLogDebug("RunModeIdsAFPSingle initialised");
857 
858 #endif /* HAVE_AF_PACKET */
859  SCReturnInt(0);
860 }
861 
862 /**
863  * \brief Workers version of the AF_PACKET processing.
864  *
865  * Start N threads with each thread doing all the work.
866  *
867  */
869 {
870  SCEnter();
871 #ifdef HAVE_AF_PACKET
872  int ret;
873  const char *live_dev = NULL;
874 
875  TimeModeSetLive();
876 
877  (void)SCConfGet("af-packet.live-interface", &live_dev);
878 
879  if (AFPPeersListInit() != TM_ECODE_OK) {
880  FatalError("Unable to init peers list.");
881  }
882 
883  ret = RunModeSetLiveCaptureWorkers(ParseAFPConfig, AFPConfigGeThreadsCount, "ReceiveAFP",
884  "DecodeAFP", thread_name_workers, live_dev);
885  if (ret != 0) {
886  FatalError("Unable to start runmode");
887  }
888 
889  /* In IPS mode each threads must have a peer */
890  if (AFPPeersListCheck() != TM_ECODE_OK) {
891  FatalError("Some IPS capture threads did not peer.");
892  }
893 
894  SCLogDebug("RunModeIdsAFPWorkers initialised");
895 
896 #endif /* HAVE_AF_PACKET */
897  SCReturnInt(0);
898 }
899 
900 /**
901  * @}
902  */
thread_name_workers
const char * thread_name_workers
Definition: runmodes.c:67
util-device-private.h
AFPIfaceConfig_::promisc
int promisc
Definition: source-af-packet.h:107
util-byte.h
tm-threads.h
AFPIfaceConfig_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-af-packet.h:111
PACKET_FANOUT_FLAG_DEFRAG
#define PACKET_FANOUT_FLAG_DEFRAG
Definition: source-af-packet.h:40
RunModeIdsAFPWorkers
int RunModeIdsAFPWorkers(void)
Workers version of the AF_PACKET processing.
Definition: runmode-af-packet.c:868
flow-bypass.h
AFPIfaceConfig_::xdp_mode
uint8_t xdp_mode
Definition: source-af-packet.h:119
SCConfValIsTrue
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:577
AFP_BYPASS
#define AFP_BYPASS
Definition: source-af-packet.h:65
EngineModeSetIPS
void EngineModeSetIPS(const enum EngineHostMode mode)
Definition: suricata.c:265
RunModeSetLiveCaptureWorkers
int RunModeSetLiveCaptureWorkers(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
Definition: util-runmodes.c:329
alert-debuglog.h
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
AFP_COPY_MODE_NONE
#define AFP_COPY_MODE_NONE
Definition: source-af-packet.h:68
RunModeIdsAFPSingle
int RunModeIdsAFPSingle(void)
Single thread version of the AF_PACKET processing.
Definition: runmode-af-packet.c:827
runmode-af-packet.h
util-bpf.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
RunModeIdsAFPRegister
void RunModeIdsAFPRegister(void)
Definition: runmode-af-packet.c:131
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
LiveGetOffload
int LiveGetOffload(void)
Definition: util-device.c:87
AFPIfaceConfig_::ebpf_filter_fd
int ebpf_filter_fd
Definition: source-af-packet.h:116
PACKET_FANOUT_RND
#define PACKET_FANOUT_RND
Definition: source-af-packet.h:36
UtilCpuGetNumProcessorsConfigured
uint16_t UtilCpuGetNumProcessorsConfigured(void)
Get the number of cpus configured in the system.
Definition: util-cpu.c:59
AFP_SOCK_PROTECT
#define AFP_SOCK_PROTECT
Definition: source-af-packet.h:60
PACKET_FANOUT_HASH
#define PACKET_FANOUT_HASH
Definition: source-af-packet.h:32
AFPPeersListInit
TmEcode AFPPeersListInit(void)
Init the global list of AFPPeer.
Definition: source-af-packet.c:447
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
RunModeAFPGetDefaultMode
const char * RunModeAFPGetDefaultMode(void)
Definition: runmode-af-packet.c:62
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:295
SCConfGet
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:352
PACKET_FANOUT_QM
#define PACKET_FANOUT_QM
Definition: source-af-packet.h:37
util-runmodes.h
AFPIfaceConfig_::ring_size
int ring_size
Definition: source-af-packet.h:96
thread_name_autofp
const char * thread_name_autofp
Definition: runmodes.c:65
AFPIfaceConfig_::block_timeout
int block_timeout
Definition: source-af-packet.h:100
SCConfValIsFalse
int SCConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:602
CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_DISABLE
Definition: decode.h:43
AFPIfaceConfig_::out_iface
const char * out_iface
Definition: source-af-packet.h:120
CHECKSUM_VALIDATION_KERNEL
@ CHECKSUM_VALIDATION_KERNEL
Definition: decode.h:47
AFP_XDPBYPASS
#define AFP_XDPBYPASS
Definition: source-af-packet.h:66
RunmodeGetActive
char * RunmodeGetActive(void)
Definition: runmodes.c:198
AFPIfaceConfig_::flags
unsigned int flags
Definition: source-af-packet.h:109
AFPIfaceConfig_::xdp_filter_fd
int xdp_filter_fd
Definition: source-af-packet.h:118
thread_name_single
const char * thread_name_single
Definition: runmodes.c:66
AFPGetLinkType
int AFPGetLinkType(const char *ifname)
Definition: source-af-packet.c:1532
AFPPeersListCheck
TmEcode AFPPeersListCheck(void)
Check that all AFPPeer got a peer.
Definition: source-af-packet.c:464
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
ConfSetBPFFilter
void ConfSetBPFFilter(SCConfNode *if_root, SCConfNode *if_default, const char *iface, const char **bpf_filter)
Definition: util-bpf.c:30
AFP_BLOCK_SIZE_DEFAULT_ORDER
#define AFP_BLOCK_SIZE_DEFAULT_ORDER
Definition: source-af-packet.h:78
AFPIfaceConfig_::cluster_type
int cluster_type
Definition: source-af-packet.h:105
AFPIfaceConfig_::cluster_id
uint16_t cluster_id
Definition: source-af-packet.h:104
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
RunModeSetLiveCaptureAutoFp
int RunModeSetLiveCaptureAutoFp(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
Definition: util-runmodes.c:85
AFPIfaceConfig_::block_size
int block_size
Definition: source-af-packet.h:98
CHECKSUM_VALIDATION_ENABLE
@ CHECKSUM_VALIDATION_ENABLE
Definition: decode.h:44
CHECKSUM_VALIDATION_AUTO
@ CHECKSUM_VALIDATION_AUTO
Definition: decode.h:45
util-debug.h
AFPIfaceConfig_::ebpf_lb_fd
int ebpf_lb_fd
Definition: source-af-packet.h:114
SCConfGetChildValueIntWithDefault
int SCConfGetChildValueIntWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, intmax_t *val)
Definition: conf.c:502
AFP_MMAP_LOCKED
#define AFP_MMAP_LOCKED
Definition: source-af-packet.h:64
util-cpu.h
AFPIfaceConfig_::ebpf_filter_file
const char * ebpf_filter_file
Definition: source-af-packet.h:115
PACKET_FANOUT_LB
#define PACKET_FANOUT_LB
Definition: source-af-packet.h:33
RunModeEnablesBypassManager
void RunModeEnablesBypassManager(void)
Definition: runmodes.c:460
LiveGetDevice
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
Definition: util-device.c:269
GetIfaceRSSQueuesNum
int GetIfaceRSSQueuesNum(const char *dev)
Definition: util-ioctl.c:720
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect-engine-mpm.h
util-ebpf.h
util-affinity.h
PACKET_FANOUT_CPU
#define PACKET_FANOUT_CPU
Definition: source-af-packet.h:34
SCConfGetChildWithDefault
SCConfNode * SCConfGetChildWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name)
Definition: conf.c:405
AFPIfaceConfig_::DerefFunc
void(* DerefFunc)(void *)
Definition: source-af-packet.h:125
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
AFP_COPY_MODE_TAP
#define AFP_COPY_MODE_TAP
Definition: source-af-packet.h:69
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:341
AFPIfaceConfig_::threads
uint16_t threads
Definition: source-af-packet.h:92
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
GetIfaceOffloading
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
Definition: util-ioctl.c:677
RUNMODE_AFP_DEV
@ RUNMODE_AFP_DEV
Definition: runmodes.h:36
DisableIfaceOffloading
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
Definition: util-ioctl.c:690
AFP_ENABLE_HWTIMESTAMP
#define AFP_ENABLE_HWTIMESTAMP
Definition: source-af-packet.h:59
runmodes.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:232
AFP_NEED_PEER
#define AFP_NEED_PEER
Definition: source-af-packet.h:58
max_pending_packets
uint32_t max_pending_packets
Definition: suricata.c:188
TimeModeSetLive
void TimeModeSetLive(void)
Definition: util-time.c:99
alert-fastlog.h
util-conf.h
SCConfNodeLookupKeyValue
SCConfNode * SCConfNodeLookupKeyValue(const SCConfNode *base, const char *key, const char *value)
Lookup for a key value under a specific node.
Definition: conf.c:894
SCConfGetChildValue
int SCConfGetChildValue(const SCConfNode *base, const char *name, const char **vptr)
Definition: conf.c:389
suricata-common.h
LiveGetDeviceName
const char * LiveGetDeviceName(int number)
Get a pointer to the device name at idx.
Definition: util-device.c:205
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:241
AFPIfaceConfig_::xdp_filter_file
const char * xdp_filter_file
Definition: source-af-packet.h:117
AFP_TPACKET_V3
#define AFP_TPACKET_V3
Definition: source-af-packet.h:62
FatalError
#define FatalError(...)
Definition: util-debug.h:517
AFPIfaceConfig_::v2_block_size
int v2_block_size
Definition: source-af-packet.h:102
RunModeIdsAFPAutoFp
int RunModeIdsAFPAutoFp(void)
Definition: runmode-af-packet.c:788
SC_ATOMIC_RESET
#define SC_ATOMIC_RESET(name)
wrapper for reinitializing an atomic variable.
Definition: util-atomic.h:323
BypassedFlowManagerRegisterUpdateFunc
int BypassedFlowManagerRegisterUpdateFunc(BypassedUpdateFunc UpdateFunc, void *data)
source-af-packet.h
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
MAX_PACKET_SIZE
#define MAX_PACKET_SIZE
Definition: source-af-packet.h:81
SCConfGetNode
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
Definition: conf.c:183
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SCFree
#define SCFree(p)
Definition: util-mem.h:61
AFP_COPY_MODE_IPS
#define AFP_COPY_MODE_IPS
Definition: source-af-packet.h:70
AFPIfaceConfig_::buffer_size
int buffer_size
Definition: source-af-packet.h:94
util-ioctl.h
RunModeSetLiveCaptureSingle
int RunModeSetLiveCaptureSingle(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
Definition: util-runmodes.c:353
AFPIfaceConfig_::iface
char iface[AFP_IFACE_NAME_LENGTH]
Definition: source-af-packet.h:90
suricata.h
AFPIfaceConfig_::copy_mode
uint8_t copy_mode
Definition: source-af-packet.h:110
AFPIfaceConfig_
Definition: source-af-packet.h:89
AFPIfaceConfig_::bpf_filter
const char * bpf_filter
Definition: source-af-packet.h:112
ConfFindDeviceConfig
SCConfNode * ConfFindDeviceConfig(SCConfNode *node, const char *iface)
Find the configuration node for a specific device.
Definition: util-conf.c:126
LiveGetDeviceCount
int LiveGetDeviceCount(void)
Get the number of registered devices.
Definition: util-device.c:171
SCConfGetChildValueWithDefault
int SCConfGetChildValueWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, const char **vptr)
Definition: conf.c:419
ENGINE_HOST_IS_BRIDGE
@ ENGINE_HOST_IS_BRIDGE
Definition: suricata.h:118
UtilCpuGetNumProcessorsOnline
uint16_t UtilCpuGetNumProcessorsOnline(void)
Get the number of cpus online in the system.
Definition: util-cpu.c:108
AFPIfaceConfig_::ebpf_lb_file
const char * ebpf_lb_file
Definition: source-af-packet.h:113
SCConfGetChildValueBoolWithDefault
int SCConfGetChildValueBoolWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, int *val)
Definition: conf.c:554
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:250
BypassedFlowManagerRegisterCheckFunc
int BypassedFlowManagerRegisterCheckFunc(BypassedCheckFunc CheckFunc, BypassedCheckFuncInit CheckFuncInit, void *data)
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
SCConfNode_
Definition: conf.h:37
AFPIsFanoutSupported
int AFPIsFanoutSupported(uint16_t cluster_id)
test if we can use FANOUT. Older kernels like those in CentOS6 have HAVE_PACKET_FANOUT defined but fa...
Definition: source-af-packet.c:1891
output.h
AFP_EMERGENCY_MODE
#define AFP_EMERGENCY_MODE
Definition: source-af-packet.h:61