Go to the documentation of this file.
70 "Single threaded af-packet mode",
73 "Workers af-packet mode, each thread does all"
74 " tasks from acquisition to logging",
77 "Multi socket AF_PACKET mode. Packets from "
78 "each flow are assigned to a single detect "
87 static void AFPDerefConfig(
void *conf)
98 static int cluster_id_auto = 1;
110 static void *ParseAFPConfig(
const char *iface)
112 const char *threadsstr = NULL;
116 const char *tmpclusterid;
117 const char *tmpctype;
118 const char *copymodestr;
121 const char *bpf_filter = NULL;
122 const char *out_iface = NULL;
124 const char *ebpf_file = NULL;
156 #ifdef HAVE_PACKET_EBPF
160 if (
ConfGet(
"bpf-filter", &bpf_filter) == 1) {
161 if (strlen(bpf_filter) > 0) {
163 SCLogConfig(
"Going to use command-line provided bpf filter '%s'",
170 if (af_packet_node == NULL) {
171 SCLogInfo(
"unable to find af-packet config using default values");
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",
186 if (if_root == NULL) {
187 if_root = if_default;
191 if (active_runmode && !strcmp(
"single", active_runmode)) {
196 if (threadsstr != NULL) {
197 if (strcmp(threadsstr,
"auto") == 0) {
202 "threads, resetting to default");
210 if (strlen(out_iface) > 0) {
217 SCLogConfig(
"Disabling mmaped capture on iface %s",
225 "mmap-locked", (
int *)&boolval);
227 SCLogConfig(
"Enabling locked memory for mmap on iface %s",
233 "tpacket-v3", (
int *)&boolval) == 1)
237 #ifdef HAVE_TPACKET_V3
238 SCLogConfig(
"Enabling tpacket v3 capture on iface %s",
242 SCLogNotice(
"System too old for tpacket v3 switching to v2");
247 "tpacket v3 is only implemented for 'workers' runmode."
248 " Switching to tpacket v2.");
257 "use-emergency-flush", (
int *)&boolval);
259 SCLogConfig(
"Enabling ring emergency flush on iface %s",
268 SCLogInfo(
"Copy mode activated but no destination"
269 " iface. Disabling feature");
271 SCLogInfo(
"Copy mode activated but use-mmap "
272 "set to no. Disabling feature");
273 }
else if (strlen(copymodestr) <= 0) {
275 }
else if (strcmp(copymodestr,
"ips") == 0) {
276 SCLogInfo(
"AF_PACKET IPS mode activated %s->%s",
283 }
else if (strcmp(copymodestr,
"tap") == 0) {
284 SCLogInfo(
"AF_PACKET TAP mode activated %s->%s",
292 SCLogInfo(
"Invalid mode (not in tap, ips)");
297 aconf->
cluster_id = (uint16_t)(cluster_id_auto++);
310 }
else if (strcmp(tmpctype,
"cluster_round_robin") == 0) {
311 SCLogConfig(
"Using round-robin cluster mode for AF_PACKET (iface %s)",
315 }
else if (strcmp(tmpctype,
"cluster_flow") == 0) {
320 SCLogConfig(
"Using flow cluster mode for AF_PACKET (iface %s)",
324 SCLogConfig(
"Using defrag kernel functionality for AF_PACKET (iface %s)",
330 }
else if (strcmp(tmpctype,
"cluster_cpu") == 0) {
331 SCLogConfig(
"Using cpu cluster mode for AF_PACKET (iface %s)",
335 }
else if (strcmp(tmpctype,
"cluster_qm") == 0) {
336 SCLogConfig(
"Using queue based cluster mode for AF_PACKET (iface %s)",
340 }
else if (strcmp(tmpctype,
"cluster_random") == 0) {
341 SCLogConfig(
"Using random based cluster mode for AF_PACKET (iface %s)",
345 }
else if (strcmp(tmpctype,
"cluster_rollover") == 0) {
346 SCLogConfig(
"Using rollover based cluster mode for AF_PACKET (iface %s)",
349 "tracking issues, use it at your own risk.");
352 #ifdef HAVE_PACKET_EBPF
353 }
else if (strcmp(tmpctype,
"cluster_ebpf") == 0) {
354 SCLogInfo(
"Using ebpf based cluster mode for AF_PACKET (iface %s)",
357 cluster_type = PACKET_FANOUT_EBPF;
366 SCLogConfig(
"Using rollover kernel functionality for AF_PACKET (iface %s)",
370 "tracking issues, use it at your own risk.");
375 if (
ConfGet(
"bpf-filter", &bpf_filter) != 1) {
377 if (strlen(bpf_filter) > 0) {
387 #ifdef HAVE_PACKET_EBPF
388 SCLogConfig(
"af-packet will use '%s' as eBPF load balancing file",
391 aconf->ebpf_t_config.
flags |= EBPF_SOCKET_FILTER;
395 #ifdef HAVE_PACKET_EBPF
401 aconf->ebpf_t_config.
flags |= EBPF_PINNED_MAPS;
403 const char *pinned_maps_name = NULL;
406 &pinned_maps_name) != 1) {
407 aconf->ebpf_t_config.pinned_maps_name = pinned_maps_name;
409 aconf->ebpf_t_config.pinned_maps_name = NULL;
412 aconf->ebpf_t_config.pinned_maps_name = NULL;
416 #ifdef HAVE_PACKET_EBPF
418 if (aconf->
ebpf_lb_file && cluster_type == PACKET_FANOUT_EBPF) {
421 &aconf->ebpf_t_config);
435 #ifdef HAVE_PACKET_EBPF
436 SCLogConfig(
"af-packet will use '%s' as eBPF filter file",
439 aconf->ebpf_t_config.mode = AFP_MODE_EBPF_BYPASS;
440 aconf->ebpf_t_config.
flags |= EBPF_SOCKET_FILTER;
444 #ifdef HAVE_PACKET_EBPF
445 SCLogConfig(
"Using bypass kernel functionality for AF_PACKET (iface %s)",
457 #ifdef HAVE_PACKET_EBPF
460 &aconf->ebpf_t_config);
463 "Error when loading eBPF filter file");
473 #ifdef HAVE_PACKET_XDP
474 aconf->ebpf_t_config.mode = AFP_MODE_XDP_BYPASS;
475 aconf->ebpf_t_config.
flags |= EBPF_XDP_CODE;
479 SCLogConfig(
"Using bypass kernel functionality for AF_PACKET (iface %s)",
483 if (aconf->ebpf_t_config.
flags & EBPF_PINNED_MAPS) {
485 struct ebpf_timeout_config *ebt =
SCCalloc(1,
sizeof(
struct ebpf_timeout_config));
489 memcpy(ebt, &(aconf->ebpf_t_config),
sizeof(
struct ebpf_timeout_config));
491 EBPFCheckBypassedFlowCreate,
500 #ifdef HAVE_PACKET_XDP
501 const char *xdp_mode;
503 aconf->
xdp_mode = XDP_FLAGS_SKB_MODE;
505 if (!strcmp(xdp_mode,
"soft")) {
506 aconf->
xdp_mode = XDP_FLAGS_SKB_MODE;
507 }
else if (!strcmp(xdp_mode,
"driver")) {
508 aconf->
xdp_mode = XDP_FLAGS_DRV_MODE;
509 }
else if (!strcmp(xdp_mode,
"hw")) {
510 aconf->
xdp_mode = XDP_FLAGS_HW_MODE;
511 aconf->ebpf_t_config.
flags |= EBPF_XDP_HW_MODE;
514 "Invalid xdp-mode value: '%s'", xdp_mode);
520 if (boolval ==
false) {
523 aconf->ebpf_t_config.cpus_count = 1;
531 #ifdef HAVE_PACKET_XDP
534 &aconf->ebpf_t_config);
537 SCLogInfo(
"Loaded pinned maps from sysfs");
541 "Error when loading XDP filter file");
547 "Error when setting up XDP");
552 "xdp-cpu-redirect", &cpuset) == 1) {
557 "Previously found node has disappeared");
559 EBPFBuildCPUSet(node, aconf->
iface);
563 EBPFBuildCPUSet(NULL, aconf->
iface);
586 if (value % getpagesize()) {
601 SCLogConfig(
"Disabling promiscuous mode on iface %s",
607 if (strcmp(tmpctype,
"auto") == 0) {
613 }
else if (strcmp(tmpctype,
"kernel") == 0) {
627 SCLogNotice(
"fanout not supported on this system, falling "
628 "back to 1 capture thread");
644 if (rss_queues > 0) {
646 SCLogPerf(
"%d RSS queues, so using %u threads", rss_queues, aconf->
threads);
651 SCLogPerf(
"Using %d AF_PACKET threads for interface %s",
665 "Resetting to decent value %d.", aconf->
ring_size);
683 "Using AF_PACKET with offloading activated leads to capture problems");
694 if (active_runmode && !strcmp(
"workers", active_runmode)) {
708 SCLogConfig(
"%s: enabling zero copy mode by using data release call", iface);
714 static int AFPConfigGeThreadsCount(
void *conf)
732 if (af_packet_node == NULL) {
738 for (ldev = 0; ldev < nlive; ldev++) {
740 if (live_dev == NULL) {
744 const char *copymodestr = NULL;
747 if (if_root == NULL) {
748 if (if_default == NULL) {
752 if_root = if_default;
756 if (strcmp(copymodestr,
"ips") == 0) {
766 if (has_ids && has_ips) {
767 SCLogInfo(
"AF_PACKET mode using IPS and IDS mode");
768 for (ldev = 0; ldev < nlive; ldev++) {
770 if (live_dev == NULL) {
775 const char *copymodestr = NULL;
777 if (if_root == NULL) {
778 if (if_default == NULL) {
782 if_root = if_default;
786 (strcmp(copymodestr,
"ips") == 0))) {
788 "AF_PACKET IPS mode used and interface '%s' is in IDS or TAP mode. "
789 "Sniffing '%s' but expect bad result as stream-inline is activated.",
806 #ifdef HAVE_AF_PACKET
808 const char *live_dev = NULL;
814 (void)
ConfGet(
"af-packet.live-interface", &live_dev);
823 AFPConfigGeThreadsCount,
836 SCLogDebug(
"RunModeIdsAFPAutoFp initialised");
848 #ifdef HAVE_AF_PACKET
850 const char *live_dev = NULL;
855 (void)
ConfGet(
"af-packet.live-interface", &live_dev);
862 AFPConfigGeThreadsCount,
875 SCLogDebug(
"RunModeIdsAFPSingle initialised");
890 #ifdef HAVE_AF_PACKET
892 const char *live_dev = NULL;
897 (void)
ConfGet(
"af-packet.live-interface", &live_dev);
904 AFPConfigGeThreadsCount,
917 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 StringParseUint16(uint16_t *res, int base, uint16_t len, const char *str)
int RunModeSetLiveCaptureWorkers(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
TmEcode AFPPeersListCheck()
Check that all AFPPeer got a peer.
int GetIfaceRSSQueuesNum(const char *pcap_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.
@ SC_ERR_INVALID_CLUSTER_TYPE
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
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
const char * RunModeAFPGetDefaultMode(void)
void RunModeInitialize(void)
int StringParseInt32(int32_t *res, int base, uint16_t len, const char *str)
const char * thread_name_autofp
#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 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)
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.
ConfNode * ConfFindDeviceConfig(ConfNode *node, const char *iface)
Find the configuration node for a specific device.
#define PACKET_FANOUT_CPU
int ConfGetChildValueWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, const char **vptr)
void(* DerefFunc)(void *)
@ SC_ERR_INVALID_ARGUMENT
#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)
int AFPIsFanoutSupported(int cluster_id)
test if we can use FANOUT. Older kernels like those in CentOS6 have HAVE_PACKET_FANOUT defined but fa...
void RunModeRegisterNewRunMode(enum RunModes runmode, const char *name, const char *description, int(*RunModeFunc)(void))
Registers a new runmode.
const char * LiveGetDeviceName(int number)
Get a pointer to the device name at idx.
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
const char * xdp_filter_file
#define FatalError(x,...)
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 SCLogWarning(err_code,...)
Macro used to log WARNING 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
TmEcode AFPPeersListInit()
Init the global list of AFPPeer.
#define LINKTYPE_ETHERNET
#define AFP_EMERGENCY_MODE