Go to the documentation of this file.
68 static int AFPRunModeIsIPS(
void)
80 if (af_packet_node == NULL) {
86 for (ldev = 0; ldev < nlive; ldev++) {
88 if (live_dev == NULL) {
92 const char *copymodestr = NULL;
95 if (if_root == NULL) {
96 if (if_default == NULL) {
100 if_root = if_default;
104 if (strcmp(copymodestr,
"ips") == 0) {
114 if (has_ids && has_ips) {
115 SCLogWarning(
"AF_PACKET using both IPS and TAP/IDS mode, this will not "
116 "be allowed in Suricata 8 due to undefined behavior. See ticket #5588.");
117 for (ldev = 0; ldev < nlive; ldev++) {
119 if (live_dev == NULL) {
124 const char *copymodestr = NULL;
126 if (if_root == NULL) {
127 if (if_default == NULL) {
131 if_root = if_default;
136 (strcmp(copymodestr,
"ips") == 0))) {
137 SCLogError(
"AF_PACKET IPS mode used and interface '%s' is in IDS or TAP mode. "
138 "Sniffing '%s' but expect bad result as stream-inline is activated.",
147 static void AFPRunModeEnableIPS(
void)
149 if (AFPRunModeIsIPS()) {
160 "Workers af-packet mode, each thread does all"
161 " tasks from acquisition to logging",
164 "Multi socket AF_PACKET mode. Packets from "
165 "each flow are assigned to a single detect "
172 #ifdef HAVE_AF_PACKET
174 static void AFPDerefConfig(
void *conf)
185 static int cluster_id_auto = 1;
197 static void *ParseAFPConfig(
const char *iface)
199 const char *threadsstr = NULL;
203 const char *tmpclusterid;
204 const char *tmpctype;
205 const char *copymodestr;
208 const char *bpf_filter = NULL;
209 const char *out_iface = NULL;
211 const char *ebpf_file = NULL;
243 #ifdef HAVE_PACKET_EBPF
247 if (
ConfGet(
"bpf-filter", &bpf_filter) == 1) {
248 if (strlen(bpf_filter) > 0) {
251 "%s: using command-line provided bpf filter '%s'", iface, aconf->
bpf_filter);
257 if (af_packet_node == NULL) {
258 SCLogInfo(
"%s: unable to find af-packet config using default values", iface);
265 if (if_root == NULL && if_default == NULL) {
266 SCLogInfo(
"%s: unable to find af-packet config for "
267 "interface \"%s\" or \"default\", using default values",
273 if (if_root == NULL) {
274 if_root = if_default;
278 if (active_runmode && !strcmp(
"single", active_runmode)) {
283 if (threadsstr != NULL) {
284 if (strcmp(threadsstr,
"auto") == 0) {
289 "threads, resetting to default",
298 if (strlen(out_iface) > 0) {
306 "%s: \"use-mmap\" option is obsolete: mmap is always enabled", aconf->
iface);
319 #ifdef HAVE_TPACKET_V3
323 SCLogWarning(
"%s: system too old for tpacket v3 switching to v2", iface);
327 SCLogWarning(
"%s: tpacket v3 is only implemented for 'workers' runmode."
328 " Switching to tpacket v2.",
338 if_root, if_default,
"use-emergency-flush", (
int *)&boolval);
346 SCLogWarning(
"%s: copy mode activated but no destination"
347 " iface. Disabling feature",
349 }
else if (strlen(copymodestr) <= 0) {
351 }
else if (strcmp(copymodestr,
"ips") == 0) {
355 SCLogWarning(
"%s: using tpacket_v3 in IPS mode will result in high latency", iface);
357 }
else if (strcmp(copymodestr,
"tap") == 0) {
361 SCLogWarning(
"%s: using tpacket_v3 in TAP mode will result in high latency", iface);
369 aconf->
cluster_id = (uint16_t)(cluster_id_auto++);
372 SCLogWarning(
"%s: invalid cluster_id, resetting to 0", iface);
382 }
else if (strcmp(tmpctype,
"cluster_round_robin") == 0) {
383 SCLogConfig(
"%s: using round-robin cluster mode for AF_PACKET", aconf->
iface);
386 }
else if (strcmp(tmpctype,
"cluster_flow") == 0) {
394 SCLogConfig(
"%s: using defrag kernel functionality for AF_PACKET", aconf->
iface);
399 }
else if (strcmp(tmpctype,
"cluster_cpu") == 0) {
403 }
else if (strcmp(tmpctype,
"cluster_qm") == 0) {
404 SCLogConfig(
"%s: using queue based cluster mode for AF_PACKET", aconf->
iface);
407 }
else if (strcmp(tmpctype,
"cluster_random") == 0) {
408 SCLogConfig(
"%s: using random based cluster mode for AF_PACKET", aconf->
iface);
411 }
else if (strcmp(tmpctype,
"cluster_rollover") == 0) {
412 SCLogConfig(
"%s: using rollover based cluster mode for AF_PACKET", aconf->
iface);
413 SCLogWarning(
"%s: rollover mode is causing severe flow "
414 "tracking issues, use it at your own risk.",
418 #ifdef HAVE_PACKET_EBPF
419 }
else if (strcmp(tmpctype,
"cluster_ebpf") == 0) {
420 SCLogInfo(
"%s: using ebpf based cluster mode for AF_PACKET", aconf->
iface);
422 cluster_type = PACKET_FANOUT_EBPF;
431 SCLogConfig(
"%s: Using rollover kernel functionality for AF_PACKET", aconf->
iface);
433 SCLogWarning(
"%s: rollover option is causing severe flow "
434 "tracking issues, use it at your own risk.",
440 if (
ConfGet(
"bpf-filter", &bpf_filter) != 1) {
442 if (strlen(bpf_filter) > 0) {
452 #ifdef HAVE_PACKET_EBPF
453 SCLogConfig(
"%s: af-packet will use '%s' as eBPF load balancing file", iface, ebpf_file);
455 aconf->ebpf_t_config.
flags |= EBPF_SOCKET_FILTER;
459 #ifdef HAVE_PACKET_EBPF
464 aconf->ebpf_t_config.
flags |= EBPF_PINNED_MAPS;
466 const char *pinned_maps_name = NULL;
469 &pinned_maps_name) != 1) {
470 aconf->ebpf_t_config.pinned_maps_name = pinned_maps_name;
472 aconf->ebpf_t_config.pinned_maps_name = NULL;
475 aconf->ebpf_t_config.pinned_maps_name = NULL;
479 #ifdef HAVE_PACKET_EBPF
481 if (aconf->
ebpf_lb_file && cluster_type == PACKET_FANOUT_EBPF) {
484 &aconf->ebpf_t_config);
491 SCLogError(
"%s: eBPF support is not built-in", iface);
498 #ifdef HAVE_PACKET_EBPF
499 SCLogConfig(
"%s: af-packet will use '%s' as eBPF filter file", iface, ebpf_file);
501 aconf->ebpf_t_config.mode = AFP_MODE_EBPF_BYPASS;
502 aconf->ebpf_t_config.
flags |= EBPF_SOCKET_FILTER;
506 #ifdef HAVE_PACKET_EBPF
507 SCLogConfig(
"%s: using bypass kernel functionality for AF_PACKET", aconf->
iface);
511 SCLogError(
"%s: bypass set but eBPF support is not built-in", iface);
518 #ifdef HAVE_PACKET_EBPF
521 &aconf->ebpf_t_config);
523 SCLogWarning(
"%s: failed to load eBPF filter file", iface);
526 SCLogError(
"%s: eBPF support is not built-in", iface);
533 #ifdef HAVE_PACKET_XDP
534 aconf->ebpf_t_config.mode = AFP_MODE_XDP_BYPASS;
535 aconf->ebpf_t_config.
flags |= EBPF_XDP_CODE;
539 SCLogConfig(
"%s: using bypass kernel functionality for AF_PACKET", aconf->
iface);
542 if (aconf->ebpf_t_config.
flags & EBPF_PINNED_MAPS) {
544 struct ebpf_timeout_config *ebt =
SCCalloc(1,
sizeof(
struct ebpf_timeout_config));
546 SCLogError(
"%s: flow bypass alloc error", iface);
548 memcpy(ebt, &(aconf->ebpf_t_config),
sizeof(
struct ebpf_timeout_config));
550 EBPFCheckBypassedFlowCreate,
557 SCLogWarning(
"%s: XDP filter set but XDP support is not built-in", iface);
559 #ifdef HAVE_PACKET_XDP
560 const char *xdp_mode;
562 aconf->
xdp_mode = XDP_FLAGS_SKB_MODE;
564 if (!strcmp(xdp_mode,
"soft")) {
565 aconf->
xdp_mode = XDP_FLAGS_SKB_MODE;
566 }
else if (!strcmp(xdp_mode,
"driver")) {
567 aconf->
xdp_mode = XDP_FLAGS_DRV_MODE;
568 }
else if (!strcmp(xdp_mode,
"hw")) {
569 aconf->
xdp_mode = XDP_FLAGS_HW_MODE;
570 aconf->ebpf_t_config.
flags |= EBPF_XDP_HW_MODE;
578 if (boolval ==
false) {
580 aconf->ebpf_t_config.cpus_count = 1;
588 #ifdef HAVE_PACKET_XDP
591 &aconf->ebpf_t_config);
594 SCLogInfo(
"%s: loaded pinned maps from sysfs", iface);
597 SCLogWarning(
"%s: failed to load XDP filter file", iface);
607 "xdp-cpu-redirect", &cpuset) == 1) {
611 SCLogError(
"Previously found node has disappeared");
613 EBPFBuildCPUSet(node, aconf->
iface);
617 EBPFBuildCPUSet(NULL, aconf->
iface);
626 SCLogError(
"%s: XDP support is not built-in", iface);
640 if (value % getpagesize()) {
641 SCLogWarning(
"%s: block-size %" PRIuMAX
" must be a multiple of pagesize (%u).", iface,
642 value, getpagesize());
661 if (strcmp(tmpctype,
"auto") == 0) {
667 }
else if (strcmp(tmpctype,
"kernel") == 0) {
681 SCLogNotice(
"%s: fanout not supported on this system, falling "
682 "back to 1 capture thread",
694 SCLogPerf(
"%s: cluster_flow: %u cores, using %u threads", iface, aconf->
threads,
700 if (rss_queues > 0) {
702 SCLogPerf(
"%s: cluster_qm: %d RSS queues, using %u threads", iface, rss_queues,
720 SCLogWarning(
"%s: inefficient setup: ring-size < max_pending_packets. "
721 "Resetting to decent value %d.",
740 "%s: using AF_PACKET with offloads enabled leads to capture problems",
752 if (active_runmode == NULL || strcmp(
"workers", active_runmode) != 0) {
760 static int AFPConfigGeThreadsCount(
void *conf)
773 #ifdef HAVE_AF_PACKET
775 const char *live_dev = NULL;
781 (void)
ConfGet(
"af-packet.live-interface", &live_dev);
797 FatalError(
"Some IPS capture threads did not peer.");
800 SCLogDebug(
"RunModeIdsAFPAutoFp initialised");
812 #ifdef HAVE_AF_PACKET
814 const char *live_dev = NULL;
819 (void)
ConfGet(
"af-packet.live-interface", &live_dev);
826 AFPConfigGeThreadsCount,
836 FatalError(
"Some IPS capture threads did not peer.");
839 SCLogDebug(
"RunModeIdsAFPSingle initialised");
854 #ifdef HAVE_AF_PACKET
856 const char *live_dev = NULL;
861 (void)
ConfGet(
"af-packet.live-interface", &live_dev);
875 FatalError(
"Some IPS capture threads did not peer.");
878 SCLogDebug(
"RunModeIdsAFPWorkers initialised");
const char * thread_name_workers
ChecksumValidationMode checksum_mode
#define PACKET_FANOUT_FLAG_DEFRAG
int RunModeIdsAFPWorkers(void)
Workers version of the AF_PACKET processing.
int RunModeSetLiveCaptureWorkers(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define AFP_COPY_MODE_NONE
int RunModeIdsAFPSingle(void)
Single thread version of the AF_PACKET processing.
void RunModeIdsAFPRegister(void)
int ConfGetChildValueBoolWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, int *val)
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
#define PACKET_FANOUT_RND
uint16_t UtilCpuGetNumProcessorsConfigured(void)
Get the number of cpus configured in the system.
#define PACKET_FANOUT_HASH
TmEcode AFPPeersListInit(void)
Init the global list of AFPPeer.
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
const char * RunModeAFPGetDefaultMode(void)
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
void RunModeInitialize(void)
const char * thread_name_autofp
void RunModeRegisterNewRunMode(enum RunModes runmode, const char *name, const char *description, int(*RunModeFunc)(void), void(*RunModeIsIPSEnabled)(void))
Registers a new runmode.
#define PACKET_FANOUT_ROLLOVER
ConfNode * ConfNodeLookupKeyValue(const ConfNode *base, const char *key, const char *value)
Lookup for a key value under a specific node.
@ CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_KERNEL
char * RunmodeGetActive(void)
int StringParseInt32(int32_t *res, int base, size_t len, const char *str)
int ConfGetChildValueIntWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, intmax_t *val)
const char * thread_name_single
ConfNode * ConfGetChildWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name)
int AFPGetLinkType(const char *ifname)
TmEcode AFPPeersListCheck(void)
Check that all AFPPeer got a peer.
int ConfValIsTrue(const char *val)
Check if a value is true.
#define AFP_BLOCK_SIZE_DEFAULT_ORDER
size_t strlcpy(char *dst, const char *src, size_t siz)
int RunModeSetLiveCaptureAutoFp(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
@ CHECKSUM_VALIDATION_ENABLE
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
@ CHECKSUM_VALIDATION_AUTO
const char * ebpf_filter_file
void RunModeEnablesBypassManager(void)
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
int GetIfaceRSSQueuesNum(const char *dev)
ConfNode * ConfFindDeviceConfig(ConfNode *node, const char *iface)
Find the configuration node for a specific device.
#define PACKET_FANOUT_CPU
void EngineModeSetIPS(void)
int ConfGetChildValueWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, const char **vptr)
void(* DerefFunc)(void *)
#define SCLogWarning(...)
Macro used to log WARNING messages.
#define AFP_COPY_MODE_TAP
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
void TimeModeSetLive(void)
const char * LiveGetDeviceName(int number)
Get a pointer to the device name at idx.
const char * xdp_filter_file
int RunModeIdsAFPAutoFp(void)
#define SC_ATOMIC_RESET(name)
wrapper for reinitializing an atomic variable.
int BypassedFlowManagerRegisterUpdateFunc(BypassedUpdateFunc UpdateFunc, void *data)
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
#define SCLogError(...)
Macro used to log ERROR messages.
#define AFP_COPY_MODE_IPS
int ConfValIsFalse(const char *val)
Check if a value is false.
int RunModeSetLiveCaptureSingle(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
char iface[AFP_IFACE_NAME_LENGTH]
int LiveGetDeviceCount(void)
Get the number of registered devices.
uint16_t UtilCpuGetNumProcessorsOnline(void)
Get the number of cpus online in the system.
const char * ebpf_lb_file
#define SCLogNotice(...)
Macro used to log NOTICE messages.
int BypassedFlowManagerRegisterCheckFunc(BypassedCheckFunc CheckFunc, BypassedCheckFuncInit CheckFuncInit, void *data)
#define PACKET_FANOUT_FLAG_ROLLOVER
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...
#define LINKTYPE_ETHERNET
#define AFP_EMERGENCY_MODE