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