From d5e254d50478da4893b77bcb05694c37af961beb Mon Sep 17 00:00:00 2001 From: deltay Date: Fri, 28 Oct 2011 15:22:24 +0800 Subject: [PATCH] Add pfring bpf filter, require pfring >= 5.1 --- configure.in | 18 ++++++++++++++++++ src/runmode-pfring.c | 25 +++++++++++++++++++++++++ src/source-pfring.c | 19 +++++++++++++++++++ src/source-pfring.h | 3 +++ suricata.yaml | 2 ++ 5 files changed, 67 insertions(+) diff --git a/configure.in b/configure.in index 4d21e0e23e..8ef560daee 100644 --- a/configure.in +++ b/configure.in @@ -692,6 +692,24 @@ esac AC_MSG_RESULT(no) fi + AC_MSG_CHECKING([if pfring_set_bpf_filter is available]) + AC_TRY_COMPILE([ + #include + ], + [ + pfring *pd; + pd = pfring_open("eth1", 1, 1515, 1); + pfring_set_bpf_filter(pd, "tcp"); + ], + [ pfring_set_bpf_filter_available=yes ], [:]) + + if test "$pfring_set_bpf_filter_available" = "yes"; then + AC_DEFINE([HAVE_PFRING_SET_BPF_FILTER],[1],[PF_RING pfring_set_bpf_filter is available]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + STORE_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} -Werror" AC_MSG_CHECKING([if pfring_recv expects u_char**]) diff --git a/src/runmode-pfring.c b/src/runmode-pfring.c index 02cad36b33..5022a56799 100644 --- a/src/runmode-pfring.c +++ b/src/runmode-pfring.c @@ -82,6 +82,9 @@ void PfringDerefConfig(void *conf) { PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf; if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) { + if (pfp->bpf_filter) { + SCFree(pfp->bpf_filter); + } SCFree(pfp); } } @@ -193,6 +196,9 @@ void *ParsePfringConfig(const char *iface) cluster_type default_ctype = CLUSTER_ROUND_ROBIN; int getctype = 0; #endif +#ifdef HAVE_PFRING_SET_BPF_FILTER + char *bpf_filter = NULL; +#endif /* HAVE_PFRING_SET_BPF_FILTER */ if (iface == NULL) { return NULL; @@ -201,6 +207,7 @@ void *ParsePfringConfig(const char *iface) if (pfconf == NULL) { return NULL; } + memset(pfconf, 0, sizeof(PfringIfaceConfig)); strlcpy(pfconf->iface, iface, sizeof(pfconf->iface)); pfconf->threads = 1; pfconf->cluster_id = 1; @@ -257,6 +264,24 @@ void *ParsePfringConfig(const char *iface) SCLogDebug("Going to use cluster-id %" PRId32, pfconf->cluster_id); } } +#ifdef HAVE_PFRING_SET_BPF_FILTER + /*load pfring bpf filter*/ + /* command line value has precedence */ + if (ConfGet("bpf-filter", &bpf_filter) == 1) { + if (strlen(bpf_filter) > 0) { + pfconf->bpf_filter = SCStrdup(bpf_filter); + SCLogDebug("Going to use command-line provided bpf filter %s", + pfconf->bpf_filter); + } + } else { + if (ConfGetChildValue(if_root, "bpf-filter", &bpf_filter) == 1) { + if (strlen(bpf_filter) > 0) { + pfconf->bpf_filter = SCStrdup(bpf_filter); + SCLogDebug("Going to use bpf filter %s", pfconf->bpf_filter); + } + } + } +#endif /* HAVE_PFRING_SET_BPF_FILTER */ #ifdef HAVE_PFRING_CLUSTER_TYPE if (ConfGet("pfring.cluster-type", &tmpctype) == 1) { diff --git a/src/source-pfring.c b/src/source-pfring.c index 5f1b5c5019..44999da138 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -126,6 +126,9 @@ typedef struct PfringThreadVars_ #endif /* HAVE_PFRING_CLUSTER_TYPE */ uint8_t cluster_id; char *interface; +#ifdef HAVE_PFRING_SET_BPF_FILTER + char *bpf_filter; +#endif /* HAVE_PFRING_SET_BPF_FILTER */ } PfringThreadVars; /** @@ -334,6 +337,16 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) { version & 0x000000FF, ptv->interface); } +#ifdef HAVE_PFRING_SET_BPF_FILTER + if (pfconf->bpf_filter) { + ptv->bpf_filter = SCStrdup(pfconf->bpf_filter); + rc= pfring_set_bpf_filter(ptv->pd, ptv->bpf_filter); + if (rc < 0) { + SCLogInfo("Set PF_RING bpf filter \"%s\" failed.", ptv->bpf_filter); + } + } +#endif /* HAVE_PFRING_SET_BPF_FILTER */ + /* It seems that as of 4.7.1 this is required */ #ifdef HAVE_PFRING_ENABLE rc = pfring_enable_ring(ptv->pd); @@ -383,6 +396,12 @@ TmEcode ReceivePfringThreadDeinit(ThreadVars *tv, void *data) { if (ptv->interface) SCFree(ptv->interface); pfring_remove_from_cluster(ptv->pd); +#ifdef HAVE_PFRING_SET_BPF_FILTER + if (ptv->bpf_filter) { + pfring_remove_bpf_filter(ptv->pd); + SCFree(ptv->bpf_filter); + } +#endif /* HAVE_PFRING_SET_BPF_FILTER */ pfring_close(ptv->pd); return TM_ECODE_OK; } diff --git a/src/source-pfring.h b/src/source-pfring.h index 14ce12254d..ae7550f779 100644 --- a/src/source-pfring.h +++ b/src/source-pfring.h @@ -41,6 +41,9 @@ typedef struct PfringIfaceConfig_ char iface[PFRING_IFACE_NAME_LENGTH]; /* number of threads */ int threads; +#ifdef HAVE_PFRING_SET_BPF_FILTER + char *bpf_filter; +#endif /* HAVE_PFRING_SET_BPF_FILTER */ SC_ATOMIC_DECLARE(unsigned int, ref); void (*DerefFunc)(void *); } PfringIfaceConfig; diff --git a/suricata.yaml b/suricata.yaml index e73b630058..5b91b903a2 100644 --- a/suricata.yaml +++ b/suricata.yaml @@ -538,6 +538,8 @@ pfring: # Default PF_RING cluster type. PF_RING can load balance per flow or per hash. # This is only supported in versions of PF_RING > 4.1.1. cluster-type: cluster_round_robin + # bpf filter for this interface + #bpf-filter: tcp # Second interface #- interface: eth1 # threads: 3