Go to the documentation of this file.
68 static bool AFPRunModeIsIPS(
void)
75 if (af_packet_node == NULL) {
76 SCLogConfig(
"no 'af-packet' section in the yaml, default to IDS");
82 for (
int ldev = 0; ldev < nlive; ldev++) {
84 if (live_dev == NULL) {
85 SCLogConfig(
"invalid livedev at index %d, default to IDS", ldev);
89 if (if_root == NULL) {
90 if (if_default == NULL) {
92 "no 'af-packet' section for '%s' or 'default' in the yaml, default to IDS",
99 const char *copymodestr = NULL;
100 const char *copyifacestr = NULL;
103 if (strcmp(copymodestr,
"ips") == 0) {
113 if (has_ids && has_ips) {
114 SCLogError(
"using both IPS and TAP/IDS mode is not allowed due to undefined behavior. See "
122 static int AFPRunModeEnableIPS(
void)
124 bool r = AFPRunModeIsIPS();
137 "Workers af-packet mode, each thread does all"
138 " tasks from acquisition to logging",
141 "Multi socket AF_PACKET mode. Packets from "
142 "each flow are assigned to a single detect "
148 #ifdef HAVE_AF_PACKET
150 static void AFPDerefConfig(
void *conf)
161 static int cluster_id_auto = 1;
173 static void *ParseAFPConfig(
const char *iface)
175 const char *threadsstr = NULL;
179 const char *tmpclusterid;
180 const char *tmpctype;
181 const char *copymodestr;
184 const char *out_iface = NULL;
186 const char *ebpf_file = NULL;
219 #ifdef HAVE_PACKET_EBPF
225 if (af_packet_node == NULL) {
226 SCLogInfo(
"%s: unable to find af-packet config using default values", iface);
233 if (if_root == NULL && if_default == NULL) {
234 SCLogInfo(
"%s: unable to find af-packet config for "
235 "interface \"%s\" or \"default\", using default values",
241 if (if_root == NULL) {
242 if_root = if_default;
246 if (active_runmode && !strcmp(
"single", active_runmode)) {
251 if (threadsstr != NULL) {
252 if (strcmp(threadsstr,
"auto") == 0) {
257 "threads, resetting to default",
266 if (out_iface != NULL) {
267 if (strlen(out_iface) > 0) {
269 if (strcmp(iface, out_iface) == 0) {
271 "Invalid config: interface (%s) and copy-iface (%s) can't be the same",
276 SCLogWarning(
"copy-iface corresponding to %s interface cannot be NULL", iface);
294 SCLogWarning(
"%s: copy mode activated but no destination"
295 " iface. Disabling feature",
297 }
else if (strlen(copymodestr) <= 0) {
299 }
else if (strcmp(copymodestr,
"ips") == 0) {
302 }
else if (strcmp(copymodestr,
"tap") == 0) {
316 SCLogWarning(
"%s: tpacket v3 is only implemented for 'workers' runmode."
317 " Switching to tpacket v2.",
332 SCLogWarning(
"%s: using tpacket-v3 in IPS or TAP mode will result in high latency", iface);
336 aconf->
cluster_id = (uint16_t)(cluster_id_auto++);
339 SCLogWarning(
"%s: invalid cluster_id, resetting to 0", iface);
346 SCLogConfig(
"%s: using default cluster-type of \"cluster_flow\"", aconf->
iface);
347 tmpctype =
"cluster_flow";
350 if (strcmp(tmpctype,
"cluster_rollover") == 0) {
352 "%s: cluster_rollover deprecated; using \"cluster_flow\" instead. See ticket #6128",
354 tmpctype =
"cluster_flow";
357 if (strcmp(tmpctype,
"cluster_round_robin") == 0) {
358 SCLogConfig(
"%s: using round-robin cluster mode for AF_PACKET", aconf->
iface);
361 }
else if (strcmp(tmpctype,
"cluster_flow") == 0) {
369 SCLogConfig(
"%s: using defrag kernel functionality for AF_PACKET", aconf->
iface);
375 SCLogConfig(
"%s: enabling defrag for AF_PACKET cluster_flow", aconf->
iface);
381 }
else if (strcmp(tmpctype,
"cluster_cpu") == 0) {
385 }
else if (strcmp(tmpctype,
"cluster_qm") == 0) {
386 SCLogConfig(
"%s: using queue based cluster mode for AF_PACKET", aconf->
iface);
389 }
else if (strcmp(tmpctype,
"cluster_random") == 0) {
390 SCLogConfig(
"%s: using random based cluster mode for AF_PACKET", aconf->
iface);
393 #ifdef HAVE_PACKET_EBPF
394 }
else if (strcmp(tmpctype,
"cluster_ebpf") == 0) {
395 SCLogInfo(
"%s: using ebpf based cluster mode for AF_PACKET", aconf->
iface);
397 cluster_type = PACKET_FANOUT_EBPF;
406 SCLogConfig(
"%s: Rollover requested for AF_PACKET but ignored -- see ticket #6128.",
408 SCLogWarning(
"%s: rollover option has been deprecated and will be ignored as it can cause "
410 "tracking issues; see ticket #6128.",
419 #ifdef HAVE_PACKET_EBPF
420 SCLogConfig(
"%s: af-packet will use '%s' as eBPF load balancing file", iface, ebpf_file);
422 aconf->ebpf_t_config.
flags |= EBPF_SOCKET_FILTER;
426 #ifdef HAVE_PACKET_EBPF
431 aconf->ebpf_t_config.
flags |= EBPF_PINNED_MAPS;
433 const char *pinned_maps_name = NULL;
435 if_root, if_default,
"pinned-maps-name", &pinned_maps_name) != 1) {
436 aconf->ebpf_t_config.pinned_maps_name = pinned_maps_name;
438 aconf->ebpf_t_config.pinned_maps_name = NULL;
441 aconf->ebpf_t_config.pinned_maps_name = NULL;
445 #ifdef HAVE_PACKET_EBPF
447 if (aconf->
ebpf_lb_file && cluster_type == PACKET_FANOUT_EBPF) {
450 &aconf->ebpf_t_config);
457 SCLogError(
"%s: eBPF support is not built-in", iface);
464 #ifdef HAVE_PACKET_EBPF
465 SCLogConfig(
"%s: af-packet will use '%s' as eBPF filter file", iface, ebpf_file);
467 aconf->ebpf_t_config.mode = AFP_MODE_EBPF_BYPASS;
468 aconf->ebpf_t_config.
flags |= EBPF_SOCKET_FILTER;
472 #ifdef HAVE_PACKET_EBPF
473 SCLogConfig(
"%s: using bypass kernel functionality for AF_PACKET", aconf->
iface);
477 SCLogError(
"%s: bypass set but eBPF support is not built-in", iface);
484 #ifdef HAVE_PACKET_EBPF
487 &aconf->ebpf_t_config);
489 SCLogWarning(
"%s: failed to load eBPF filter file", iface);
492 SCLogError(
"%s: eBPF support is not built-in", iface);
499 #ifdef HAVE_PACKET_XDP
500 aconf->ebpf_t_config.mode = AFP_MODE_XDP_BYPASS;
501 aconf->ebpf_t_config.
flags |= EBPF_XDP_CODE;
505 SCLogConfig(
"%s: using bypass kernel functionality for AF_PACKET", aconf->
iface);
508 if (aconf->ebpf_t_config.
flags & EBPF_PINNED_MAPS) {
510 struct ebpf_timeout_config *ebt =
SCCalloc(1,
sizeof(
struct ebpf_timeout_config));
512 SCLogError(
"%s: flow bypass alloc error", iface);
514 memcpy(ebt, &(aconf->ebpf_t_config),
sizeof(
struct ebpf_timeout_config));
516 EBPFCheckBypassedFlowCreate,
523 SCLogWarning(
"%s: XDP filter set but XDP support is not built-in", iface);
525 #ifdef HAVE_PACKET_XDP
526 const char *xdp_mode;
528 aconf->
xdp_mode = XDP_FLAGS_SKB_MODE;
530 if (!strcmp(xdp_mode,
"soft")) {
531 aconf->
xdp_mode = XDP_FLAGS_SKB_MODE;
532 }
else if (!strcmp(xdp_mode,
"driver")) {
533 aconf->
xdp_mode = XDP_FLAGS_DRV_MODE;
534 }
else if (!strcmp(xdp_mode,
"hw")) {
535 aconf->
xdp_mode = XDP_FLAGS_HW_MODE;
536 aconf->ebpf_t_config.
flags |= EBPF_XDP_HW_MODE;
547 aconf->ebpf_t_config.cpus_count = 1;
555 #ifdef HAVE_PACKET_XDP
558 &aconf->ebpf_t_config);
561 SCLogInfo(
"%s: loaded pinned maps from sysfs", iface);
564 SCLogWarning(
"%s: failed to load XDP filter file", iface);
574 if_root, if_default,
"xdp-cpu-redirect", &cpuset) == 1) {
579 SCLogError(
"Previously found node has disappeared");
581 EBPFBuildCPUSet(node, aconf->
iface);
585 EBPFBuildCPUSet(NULL, aconf->
iface);
594 SCLogError(
"%s: XDP support is not built-in", iface);
608 if (value % getpagesize()) {
609 SCLogWarning(
"%s: block-size %" PRIuMAX
" must be a multiple of pagesize (%u).", iface,
610 value, getpagesize());
623 if (value % getpagesize()) {
624 SCLogWarning(
"%s: v2-block-size %" PRIuMAX
" must be a multiple of pagesize (%u).",
625 iface, value, getpagesize());
639 #ifdef HAVE_HW_TIMESTAMPING
646 if (strcmp(tmpctype,
"auto") == 0) {
652 }
else if (strcmp(tmpctype,
"kernel") == 0) {
666 SCLogNotice(
"%s: fanout not supported on this system, falling "
667 "back to 1 capture thread",
679 SCLogPerf(
"%s: cluster_flow: %u cores, using %u threads", iface, aconf->
threads,
685 if (rss_queues > 0 && rss_queues <= UINT16_MAX) {
686 aconf->
threads = (uint16_t)rss_queues;
687 SCLogPerf(
"%s: cluster_qm: %d RSS queues, using %u threads", iface, rss_queues,
705 SCLogWarning(
"%s: inefficient setup: ring-size < max_pending_packets. "
706 "Resetting to decent value %d.",
725 "%s: using AF_PACKET with offloads enabled leads to capture problems",
737 if (active_runmode == NULL || strcmp(
"workers", active_runmode) != 0) {
746 "%s: AF_PACKET defrag is not recommended for inline use, please disable", iface);
752 SCLogWarning(
"%s: AF_PACKET defrag is recommended for IDS cluster_flow", iface);
759 SCLogWarning(
"%s: AF_PACKET v2-block-size is not large enough for max fragmented IP packet "
768 SCLogWarning(
"%s: AF_PACKET block-size is not large enough for max fragmented IP packet "
775 SCLogWarning(
"%s: AF_PACKET tpacket-v3 is recommended for non-inline operation", iface);
781 static uint16_t AFPConfigGeThreadsCount(
void *conf)
794 #ifdef HAVE_AF_PACKET
796 const char *live_dev = NULL;
800 (void)
SCConfGet(
"af-packet.live-interface", &live_dev);
816 FatalError(
"Some IPS capture threads did not peer.");
819 SCLogDebug(
"RunModeIdsAFPAutoFp initialised");
831 #ifdef HAVE_AF_PACKET
833 const char *live_dev = NULL;
837 (void)
SCConfGet(
"af-packet.live-interface", &live_dev);
844 AFPConfigGeThreadsCount,
854 FatalError(
"Some IPS capture threads did not peer.");
857 SCLogDebug(
"RunModeIdsAFPSingle initialised");
872 #ifdef HAVE_AF_PACKET
874 const char *live_dev = NULL;
878 (void)
SCConfGet(
"af-packet.live-interface", &live_dev);
892 FatalError(
"Some IPS capture threads did not peer.");
895 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 SCConfValIsTrue(const char *val)
Check if a value is true.
void EngineModeSetIPS(const enum EngineHostMode mode)
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)
#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)
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
const char * thread_name_autofp
int SCConfValIsFalse(const char *val)
Check if a value is false.
@ CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_KERNEL
char * RunmodeGetActive(void)
const char * thread_name_single
int AFPGetLinkType(const char *ifname)
TmEcode AFPPeersListCheck(void)
Check that all AFPPeer got a peer.
void ConfSetBPFFilter(SCConfNode *if_root, SCConfNode *if_default, const char *iface, const char **bpf_filter)
#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
@ CHECKSUM_VALIDATION_AUTO
int SCConfGetChildValueIntWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, intmax_t *val)
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)
#define PACKET_FANOUT_CPU
SCConfNode * SCConfGetChildWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name)
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
void RunModeRegisterNewRunMode(enum SCRunModes runmode, const char *name, const char *description, int(*RunModeFunc)(void), int(*RunModeIsIPSEnabled)(void))
Registers a new runmode.
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
#define AFP_ENABLE_HWTIMESTAMP
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
uint32_t max_pending_packets
void TimeModeSetLive(void)
SCConfNode * SCConfNodeLookupKeyValue(const SCConfNode *base, const char *key, const char *value)
Lookup for a key value under a specific node.
int SCConfGetChildValue(const SCConfNode *base, const char *name, const char **vptr)
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.
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
#define SCLogError(...)
Macro used to log ERROR messages.
#define AFP_COPY_MODE_IPS
int RunModeSetLiveCaptureSingle(ConfigIfaceParserFunc ConfigParser, ConfigIfaceThreadsCountFunc ModThreadsCount, const char *recv_mod_name, const char *decode_mod_name, const char *thread_name, const char *live_dev)
#define LINKTYPE_ETHERNET
char iface[AFP_IFACE_NAME_LENGTH]
SCConfNode * ConfFindDeviceConfig(SCConfNode *node, const char *iface)
Find the configuration node for a specific device.
int LiveGetDeviceCount(void)
Get the number of registered devices.
int SCConfGetChildValueWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, const char **vptr)
uint16_t UtilCpuGetNumProcessorsOnline(void)
Get the number of cpus online in the system.
const char * ebpf_lb_file
int SCConfGetChildValueBoolWithDefault(const SCConfNode *base, const SCConfNode *dflt, const char *name, int *val)
#define SCLogNotice(...)
Macro used to log NOTICE messages.
int BypassedFlowManagerRegisterCheckFunc(BypassedCheckFunc CheckFunc, BypassedCheckFuncInit CheckFuncInit, void *data)
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 AFP_EMERGENCY_MODE