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