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