bpf: refactor the BPF code and postpone querying of the engine mode

BPF codebase queried engine mode earlier than it was determined from
the configuration file/command line. As a result it used the default (IDS)
mode where it could've been configured later on to the IPS mode.
This could lead into an undefined behavior as some Suricata modules behave
according to the engine mode.

PF-Ring, Netmap and AF-Packet all shared almost identical code for
determining the engine mode. It was put into one common function.
Omitted the usage of SCStrdup function in PF-Ring module as it is
uppercased during thread initialization phase.

Ticket: #5957
pull/8791/head
Lukas Sismis 3 years ago committed by Victor Julien
parent 22485b368e
commit 5a6d5702a4

@ -57,6 +57,7 @@
#include "util-byte.h" #include "util-byte.h"
#include "source-af-packet.h" #include "source-af-packet.h"
#include "util-bpf.h"
extern intmax_t max_pending_packets; extern intmax_t max_pending_packets;
@ -205,7 +206,6 @@ static void *ParseAFPConfig(const char *iface)
const char *copymodestr; const char *copymodestr;
intmax_t value; intmax_t value;
int boolval; int boolval;
const char *bpf_filter = NULL;
const char *out_iface = NULL; const char *out_iface = NULL;
int cluster_type = PACKET_FANOUT_HASH; int cluster_type = PACKET_FANOUT_HASH;
const char *ebpf_file = NULL; const char *ebpf_file = NULL;
@ -244,14 +244,6 @@ static void *ParseAFPConfig(const char *iface)
aconf->ebpf_t_config.cpus_count = UtilCpuGetNumProcessorsConfigured(); aconf->ebpf_t_config.cpus_count = UtilCpuGetNumProcessorsConfigured();
#endif #endif
if (ConfGet("bpf-filter", &bpf_filter) == 1) {
if (strlen(bpf_filter) > 0) {
aconf->bpf_filter = bpf_filter;
SCLogConfig(
"%s: using command-line provided bpf filter '%s'", iface, aconf->bpf_filter);
}
}
/* Find initial node */ /* Find initial node */
af_packet_node = ConfGetNode("af-packet"); af_packet_node = ConfGetNode("af-packet");
if (af_packet_node == NULL) { if (af_packet_node == NULL) {
@ -435,16 +427,7 @@ static void *ParseAFPConfig(const char *iface)
iface); iface);
} }
/*load af_packet bpf filter*/ ConfSetBPFFilter(if_root, if_default, iface, &aconf->bpf_filter);
/* command line value has precedence */
if (ConfGet("bpf-filter", &bpf_filter) != 1) {
if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) {
if (strlen(bpf_filter) > 0) {
aconf->bpf_filter = bpf_filter;
SCLogConfig("%s: bpf filter %s", iface, aconf->bpf_filter);
}
}
}
if (ConfGetChildValueWithDefault(if_root, if_default, "ebpf-lb-file", &ebpf_file) != 1) { if (ConfGetChildValueWithDefault(if_root, if_default, "ebpf-lb-file", &ebpf_file) != 1) {
aconf->ebpf_lb_file = NULL; aconf->ebpf_lb_file = NULL;

@ -48,6 +48,7 @@
#include "source-netmap.h" #include "source-netmap.h"
#include "util-conf.h" #include "util-conf.h"
#include "suricata.h" #include "suricata.h"
#include "util-bpf.h"
extern intmax_t max_pending_packets; extern intmax_t max_pending_packets;
@ -205,14 +206,6 @@ static int ParseNetmapSettings(NetmapIfaceSettings *ns, const char *iface,
ns->real = true; ns->real = true;
} }
const char *bpf_filter = NULL;
if (ConfGet("bpf-filter", &bpf_filter) == 1) {
if (strlen(bpf_filter) > 0) {
ns->bpf_filter = bpf_filter;
SCLogInfo("%s: using command-line provided bpf filter '%s'", iface, ns->bpf_filter);
}
}
if (if_root == NULL && if_default == NULL) { if (if_root == NULL && if_default == NULL) {
SCLogInfo("%s: unable to find netmap config for interface \"%s\" or \"default\", using " SCLogInfo("%s: unable to find netmap config for interface \"%s\" or \"default\", using "
"default values", "default values",
@ -242,16 +235,7 @@ static int ParseNetmapSettings(NetmapIfaceSettings *ns, const char *iface,
} }
} }
/* load netmap bpf filter */ ConfSetBPFFilter(if_root, if_default, iface, &ns->bpf_filter);
/* command line value has precedence */
if (ns->bpf_filter == NULL) {
if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) {
if (strlen(bpf_filter) > 0) {
ns->bpf_filter = bpf_filter;
SCLogInfo("%s: using bpf filter %s", iface, ns->bpf_filter);
}
}
}
int boolval = 0; int boolval = 0;
(void)ConfGetChildValueBoolWithDefault(if_root, if_default, "disable-promisc", (int *)&boolval); (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "disable-promisc", (int *)&boolval);

@ -21,7 +21,8 @@
#include "conf.h" #include "conf.h"
#include "runmodes.h" #include "runmodes.h"
#include "source-pfring.h" #include "source-pfring.h"
#include "suricata.h"
#include "util-bpf.h"
#include "util-debug.h" #include "util-debug.h"
#include "util-time.h" #include "util-time.h"
#include "util-cpu.h" #include "util-cpu.h"
@ -70,9 +71,6 @@ static void PfringDerefConfig(void *conf)
{ {
PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf; PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf;
if (SC_ATOMIC_SUB(pfp->ref, 1) == 1) { if (SC_ATOMIC_SUB(pfp->ref, 1) == 1) {
if (pfp->bpf_filter) {
SCFree(pfp->bpf_filter);
}
SCFree(pfp); SCFree(pfp);
} }
} }
@ -201,7 +199,6 @@ static void *ParsePfringConfig(const char *iface)
const char *tmpctype = NULL; const char *tmpctype = NULL;
cluster_type default_ctype = CLUSTER_FLOW; cluster_type default_ctype = CLUSTER_FLOW;
int getctype = 0; int getctype = 0;
const char *bpf_filter = NULL;
int bool_val; int bool_val;
if (unlikely(pfconf == NULL)) { if (unlikely(pfconf == NULL)) {
@ -312,30 +309,10 @@ static void *ParsePfringConfig(const char *iface)
} }
} }
/*load pfring bpf filter*/ ConfSetBPFFilter(if_root, if_default, pfconf->iface, &pfconf->bpf_filter);
/* command line value has precedence */
if (ConfGet("bpf-filter", &bpf_filter) == 1) { if (EngineModeIsIPS()) {
if (strlen(bpf_filter) > 0) { FatalError("IPS mode not supported in PF_RING.");
pfconf->bpf_filter = SCStrdup(bpf_filter);
if (unlikely(pfconf->bpf_filter == NULL)) {
SCLogError("Can't allocate BPF filter string");
} else {
SCLogDebug("Going to use command-line provided bpf filter %s",
pfconf->bpf_filter);
}
}
} else {
if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) {
if (strlen(bpf_filter) > 0) {
pfconf->bpf_filter = SCStrdup(bpf_filter);
if (unlikely(pfconf->bpf_filter == NULL)) {
SCLogError("Can't allocate BPF filter string");
} else {
SCLogDebug("Going to use bpf filter %s",
pfconf->bpf_filter);
}
}
}
} }
if (ConfGet("pfring.cluster-type", &tmpctype) == 1) { if (ConfGet("pfring.cluster-type", &tmpctype) == 1) {

@ -44,7 +44,7 @@ typedef struct PfringIfaceConfig_
/* number of threads */ /* number of threads */
int threads; int threads;
char *bpf_filter; const char *bpf_filter;
ChecksumValidationMode checksum_mode; ChecksumValidationMode checksum_mode;
SC_ATOMIC_DECLARE(unsigned int, ref); SC_ATOMIC_DECLARE(unsigned int, ref);

@ -141,6 +141,7 @@
#include "util-running-modes.h" #include "util-running-modes.h"
#include "util-signal.h" #include "util-signal.h"
#include "util-time.h" #include "util-time.h"
#include "util-validate.h"
/* /*
* we put this here, because we only use it here in main. * we put this here, because we only use it here in main.
@ -456,15 +457,9 @@ static int SetBpfString(int argc, char *argv[])
if (bpf_len == 0) if (bpf_len == 0)
return TM_ECODE_OK; return TM_ECODE_OK;
if (EngineModeIsIPS()) {
SCLogError("BPF filter not available in IPS mode."
" Use firewall filtering if possible.");
return TM_ECODE_FAILED;
}
bpf_filter = SCMalloc(bpf_len); bpf_filter = SCMalloc(bpf_len);
if (unlikely(bpf_filter == NULL)) if (unlikely(bpf_filter == NULL))
return TM_ECODE_OK; return TM_ECODE_FAILED;
memset(bpf_filter, 0x00, bpf_len); memset(bpf_filter, 0x00, bpf_len);
tmpindex = optind; tmpindex = optind;
@ -502,11 +497,6 @@ static void SetBpfStringFromFile(char *filename)
FILE *fp = NULL; FILE *fp = NULL;
size_t nm = 0; size_t nm = 0;
if (EngineModeIsIPS()) {
FatalError("BPF filter not available in IPS mode."
" Use firewall filtering if possible.");
}
fp = fopen(filename, "r"); fp = fopen(filename, "r");
if (fp == NULL) { if (fp == NULL) {
SCLogError("Failed to open file %s", filename); SCLogError("Failed to open file %s", filename);

@ -24,6 +24,31 @@
#include "suricata-common.h" #include "suricata-common.h"
#include "util-bpf.h" #include "util-bpf.h"
#include "threads.h" #include "threads.h"
#include "conf.h"
#include "util-debug.h"
void ConfSetBPFFilter(
ConfNode *if_root, ConfNode *if_default, const char *iface, const char **bpf_filter)
{
if (*bpf_filter != NULL) {
SCLogInfo("BPF filter already configured");
return;
}
/* command line value has precedence */
if (ConfGet("bpf-filter", bpf_filter) == 1) {
if (strlen(*bpf_filter) > 0) {
SCLogConfig("%s: using command-line provided bpf filter '%s'", iface, *bpf_filter);
}
} else if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", bpf_filter) ==
1) { // reading from a file
if (strlen(*bpf_filter) > 0) {
SCLogConfig("%s: using file provided bpf filter %s", iface, *bpf_filter);
}
} else {
SCLogDebug("No BPF filter found, skipping");
}
}
#if !defined __OpenBSD__ #if !defined __OpenBSD__

@ -24,6 +24,11 @@
#ifndef __UTIL_BPF_H__ #ifndef __UTIL_BPF_H__
#define __UTIL_BPF_H__ #define __UTIL_BPF_H__
#include "conf.h"
void ConfSetBPFFilter(
ConfNode *if_root, ConfNode *if_default, const char *iface, const char **bpf_filter);
#if !defined __OpenBSD__ #if !defined __OpenBSD__
int SCBPFCompile(int snaplen_arg, int linktype_arg, struct bpf_program *program, int SCBPFCompile(int snaplen_arg, int linktype_arg, struct bpf_program *program,

Loading…
Cancel
Save