From c3092b6e5a441453a7ef4ce05aa68d03d54aeab0 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Tue, 9 Jul 2024 15:10:50 -0600 Subject: [PATCH] pf-ring: remove, to make room for plugin Ticket: #7162 --- src/Makefile.am | 4 - src/decode.h | 8 - src/runmode-pfring.c | 533 --------------------------- src/runmode-pfring.h | 34 -- src/runmodes.c | 15 - src/runmodes.h | 1 - src/source-pfring.c | 777 ---------------------------------------- src/source-pfring.h | 84 ----- src/suricata.c | 90 +---- src/tm-modules.c | 4 +- src/tm-threads-common.h | 2 - src/tm-threads.c | 2 - src/util-privs.c | 5 - 13 files changed, 5 insertions(+), 1554 deletions(-) delete mode 100644 src/runmode-pfring.c delete mode 100644 src/runmode-pfring.h delete mode 100644 src/source-pfring.c delete mode 100644 src/source-pfring.h diff --git a/src/Makefile.am b/src/Makefile.am index 8b0d6294ad..0ff6bd7304 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -441,7 +441,6 @@ noinst_HEADERS = \ runmode-nfq.h \ runmode-pcap-file.h \ runmode-pcap.h \ - runmode-pfring.h \ runmodes.h \ runmode-unittests.h \ runmode-unix-socket.h \ @@ -463,7 +462,6 @@ noinst_HEADERS = \ source-pcap-file.h \ source-pcap-file-helper.h \ source-pcap.h \ - source-pfring.h \ source-windivert.h \ source-windivert-prototypes.h \ stream.h \ @@ -1041,7 +1039,6 @@ libsuricata_c_a_SOURCES = \ runmode-nfq.c \ runmode-pcap.c \ runmode-pcap-file.c \ - runmode-pfring.c \ runmodes.c \ runmode-unittests.c \ runmode-unix-socket.c \ @@ -1061,7 +1058,6 @@ libsuricata_c_a_SOURCES = \ source-pcap-file.c \ source-pcap-file-directory-helper.c \ source-pcap-file-helper.c \ - source-pfring.c \ source-windivert.c \ stream.c \ stream-tcp.c \ diff --git a/src/decode.h b/src/decode.h index 0f7c9fa746..b7398bc2a0 100644 --- a/src/decode.h +++ b/src/decode.h @@ -77,9 +77,6 @@ enum PktSrcEnum { #ifdef HAVE_DPDK #include "source-dpdk.h" #endif -#ifdef HAVE_PF_RING_FLOW_OFFLOAD -#include "source-pfring.h" -#endif #ifdef HAVE_AF_XDP #include "source-af-xdp.h" #endif @@ -546,11 +543,6 @@ typedef struct Packet_ #ifdef HAVE_NETMAP NetmapPacketVars netmap_v; #endif -#ifdef HAVE_PFRING -#ifdef HAVE_PF_RING_FLOW_OFFLOAD - PfringPacketVars pfring_v; -#endif -#endif #ifdef WINDIVERT WinDivertPacketVars windivert_v; #endif /* WINDIVERT */ diff --git a/src/runmode-pfring.c b/src/runmode-pfring.c deleted file mode 100644 index 7b0fe7b3d2..0000000000 --- a/src/runmode-pfring.c +++ /dev/null @@ -1,533 +0,0 @@ -/* Copyright (C) 2007-2018 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "runmode-pfring.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "source-pfring.h" -#include "suricata.h" -#include "util-bpf.h" -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-runmodes.h" -#include "util-device.h" -#include "util-ioctl.h" -#include "util-byte.h" -#include "util-conf.h" - -#ifdef HAVE_PFRING -#include - -#define PFRING_CONF_V1 1 -#define PFRING_CONF_V2 2 -#endif - -const char *RunModeIdsPfringGetDefaultMode(void) -{ -#ifdef HAVE_PFRING - return "workers"; -#else - return NULL; -#endif -} - -void RunModeIdsPfringRegister(void) -{ - RunModeRegisterNewRunMode(RUNMODE_PFRING, "autofp", - "Multi threaded pfring mode. Packets from " - "each flow are assigned to a single detect " - "thread, unlike \"pfring_auto\" where packets " - "from the same flow can be processed by any " - "detect thread", - RunModeIdsPfringAutoFp, NULL); - RunModeRegisterNewRunMode( - RUNMODE_PFRING, "single", "Single threaded pfring mode", RunModeIdsPfringSingle, NULL); - RunModeRegisterNewRunMode(RUNMODE_PFRING, "workers", - "Workers pfring mode, each thread does all" - " tasks from acquisition to logging", - RunModeIdsPfringWorkers, NULL); -} - -#ifdef HAVE_PFRING -static void PfringDerefConfig(void *conf) -{ - PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf; - if (SC_ATOMIC_SUB(pfp->ref, 1) == 1) { - SCFree(pfp); - } -} - -/** - * \brief extract information from config file - * - * The returned structure will be freed by the thread init function. - * This is thus necessary to or copy the structure before giving it - * to thread or to reparse the file for each thread (and thus have - * new structure. - * - * If old config system is used, then return the same parameters - * value for each interface. - * - * \return a PfringIfaceConfig corresponding to the interface name - */ -static void *OldParsePfringConfig(const char *iface) -{ - const char *threadsstr = NULL; - PfringIfaceConfig *pfconf = SCMalloc(sizeof(*pfconf)); - const char *tmpclusterid; - const char *tmpctype = NULL; - cluster_type default_ctype = CLUSTER_FLOW; - - if (unlikely(pfconf == NULL)) { - return NULL; - } - - if (iface == NULL) { - SCFree(pfconf); - return NULL; - } - - strlcpy(pfconf->iface, iface, sizeof(pfconf->iface)); - pfconf->flags = 0; - pfconf->threads = 1; - pfconf->cluster_id = 1; - pfconf->ctype = default_ctype; - pfconf->DerefFunc = PfringDerefConfig; - pfconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - SC_ATOMIC_INIT(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, 1); - - /* Find initial node */ - if (ConfGet("pfring.threads", &threadsstr) != 1) { - pfconf->threads = 1; - } else { - if (threadsstr != NULL) { - if (StringParseInt32(&pfconf->threads, 10, 0, threadsstr) < 0) { - SCLogWarning("Invalid value for " - "pfring.threads: '%s'. Resetting to 1.", - threadsstr); - pfconf->threads = 1; - } - } - } - if (pfconf->threads == 0) { - pfconf->threads = 1; - } - - SC_ATOMIC_RESET(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, pfconf->threads); - - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo("%s: ZC interface detected, not setting cluster-id", pfconf->iface); - } - else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo("DNA interface detected, not setting cluster-id"); - } else if (ConfGet("pfring.cluster-id", &tmpclusterid) != 1) { - SCLogError("Could not get cluster-id from config"); - } else { - if (StringParseInt32(&pfconf->cluster_id, 10, 0, (const char *)tmpclusterid) < 0) { - SCLogWarning("Invalid value for " - "pfring.cluster_id: '%s'. Resetting to 1.", - tmpclusterid); - pfconf->cluster_id = 1; - } - pfconf->flags |= PFRING_CONF_FLAGS_CLUSTER; - SCLogDebug("Going to use cluster-id %" PRId32, pfconf->cluster_id); - } - - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo("%s: ZC interface detected, not setting cluster type for PF_RING", pfconf->iface); - } else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo( - "%s: DNA interface detected, not setting cluster type for PF_RING", pfconf->iface); - } else if (ConfGet("pfring.cluster-type", &tmpctype) != 1) { - SCLogError("Could not get cluster-type from config"); - } else if (strcmp(tmpctype, "cluster_round_robin") == 0) { - SCLogInfo("%s: Using round-robin cluster mode for PF_RING", pfconf->iface); - pfconf->ctype = (cluster_type)tmpctype; - } else if (strcmp(tmpctype, "cluster_flow") == 0) { - SCLogInfo("%s: Using flow cluster mode for PF_RING", pfconf->iface); - pfconf->ctype = (cluster_type)tmpctype; - } else { - SCLogError("invalid cluster-type %s", tmpctype); - SCFree(pfconf); - return NULL; - } - - return pfconf; -} - -/** - * \brief extract information from config file - * - * The returned structure will be freed by the thread init function. - * This is thus necessary to or copy the structure before giving it - * to thread or to reparse the file for each thread (and thus have - * new structure. - * - * If old config system is used, then return the same parameters - * value for each interface. - * - * \return a PfringIfaceConfig corresponding to the interface name - */ -static void *ParsePfringConfig(const char *iface) -{ - const char *threadsstr = NULL; - ConfNode *if_root; - ConfNode *if_default = NULL; - ConfNode *pf_ring_node; - PfringIfaceConfig *pfconf = SCMalloc(sizeof(*pfconf)); - const char *tmpclusterid; - const char *tmpctype = NULL; - cluster_type default_ctype = CLUSTER_FLOW; - int getctype = 0; - int bool_val; - const char *active_runmode = RunmodeGetActive(); - - if (unlikely(pfconf == NULL)) { - return NULL; - } - - if (iface == NULL) { - SCFree(pfconf); - return NULL; - } - - memset(pfconf, 0, sizeof(PfringIfaceConfig)); - strlcpy(pfconf->iface, iface, sizeof(pfconf->iface)); - pfconf->threads = 1; - pfconf->cluster_id = 1; - pfconf->ctype = (cluster_type)default_ctype; - pfconf->DerefFunc = PfringDerefConfig; - SC_ATOMIC_INIT(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, 1); - - /* Find initial node */ - pf_ring_node = ConfGetNode("pfring"); - if (pf_ring_node == NULL) { - SCLogInfo("Unable to find pfring config using default value"); - return pfconf; - } - - if_root = ConfFindDeviceConfig(pf_ring_node, iface); - - if_default = ConfFindDeviceConfig(pf_ring_node, "default"); - - if (if_root == NULL && if_default == NULL) { - SCLogInfo("Unable to find pfring config for " - "interface %s, using default value or 1.0 " - "configuration system. ", - iface); - return pfconf; - } - - /* If there is no setting for current interface use default one as main iface */ - if (if_root == NULL) { - if_root = if_default; - if_default = NULL; - } - - if (active_runmode && !strcmp("single", active_runmode)) { - pfconf->threads = 1; - } else if (ConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) { - pfconf->threads = 1; - } else if (threadsstr != NULL) { - if (strcmp(threadsstr, "auto") == 0) { - pfconf->threads = (int)UtilCpuGetNumProcessorsOnline(); - if (pfconf->threads > 0) { - SCLogPerf("%u cores, so using %u threads", pfconf->threads, pfconf->threads); - } else { - pfconf->threads = GetIfaceRSSQueuesNum(iface); - if (pfconf->threads > 0) { - SCLogPerf("%d RSS queues, so using %u threads", pfconf->threads, pfconf->threads); - } - } - } else { - uint16_t threads = 0; - if (StringParseUint16(&threads, 10, 0, (const char *)threadsstr) < 0) { - SCLogWarning("Invalid value for " - "pfring.threads: '%s'. Resetting to 1.", - threadsstr); - pfconf->threads = 1; - } else { - pfconf->threads = threads; - } - } - } - if (pfconf->threads <= 0) { - pfconf->threads = 1; - } - - SC_ATOMIC_RESET(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, pfconf->threads); - - /* command line value has precedence */ - if (ConfGet("pfring.cluster-id", &tmpclusterid) == 1) { - if (StringParseInt32(&pfconf->cluster_id, 10, 0, (const char *)tmpclusterid) < 0) { - SCLogWarning("Invalid value for " - "pfring.cluster-id: '%s'. Resetting to 1.", - tmpclusterid); - pfconf->cluster_id = 1; - } - pfconf->flags |= PFRING_CONF_FLAGS_CLUSTER; - SCLogDebug("Going to use command-line provided cluster-id %" PRId32, - pfconf->cluster_id); - } else { - - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo( - "%s: ZC interface detected, not setting cluster-id for PF_RING", pfconf->iface); - } else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo("%s: DNA interface detected, not setting cluster-id for PF_RING", - pfconf->iface); - } else if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-id", &tmpclusterid) != 1) { - SCLogError("Could not get cluster-id from config"); - } else { - if (StringParseInt32(&pfconf->cluster_id, 10, 0, (const char *)tmpclusterid) < 0) { - SCLogWarning("Invalid value for " - "pfring.cluster-id: '%s'. Resetting to 1.", - tmpclusterid); - pfconf->cluster_id = 1; - } - pfconf->flags |= PFRING_CONF_FLAGS_CLUSTER; - SCLogDebug("Going to use cluster-id %" PRId32, pfconf->cluster_id); - } - } - - ConfSetBPFFilter(if_root, if_default, pfconf->iface, &pfconf->bpf_filter); - - if (EngineModeIsIPS()) { - FatalError("IPS mode not supported in PF_RING."); - } - - if (ConfGet("pfring.cluster-type", &tmpctype) == 1) { - SCLogDebug("Going to use command-line provided cluster-type"); - getctype = 1; - } else { - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo("%s: ZC interface detected, not setting cluster type for PF_RING", - pfconf->iface); - } else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo("%s: DNA interface detected, not setting cluster type for PF_RING", - pfconf->iface); - } else if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-type", &tmpctype) != 1) { - SCLogError("Could not get cluster-type from config"); - } else { - getctype = 1; - } - } - - if (getctype) { - if (strcmp(tmpctype, "cluster_round_robin") == 0) { - SCLogInfo("%s: Using round-robin cluster mode for PF_RING." - " This mode is not recommended.", - pfconf->iface); - pfconf->ctype = CLUSTER_ROUND_ROBIN; - } else if (strcmp(tmpctype, "cluster_flow") == 0) { - SCLogInfo("%s: Using flow cluster mode for PF_RING", pfconf->iface); - pfconf->ctype = CLUSTER_FLOW; - } else if (strcmp(tmpctype, "cluster_inner_flow") == 0) { - SCLogInfo("%s: Using flow cluster mode inner mode for PF_RING", pfconf->iface); - pfconf->ctype = CLUSTER_INNER_FLOW; - } else if (strcmp(tmpctype, "cluster_inner_flow_2_tuple") == 0) { - SCLogInfo("%s: Using flow cluster inner 2 tuple mode for PF_RING", pfconf->iface); - pfconf->ctype = CLUSTER_INNER_FLOW_2_TUPLE; - } else if (strcmp(tmpctype, "cluster_inner_flow_4_tuple") == 0) { - SCLogInfo("%s: Using flow cluster inner 4 tuple mode for PF_RING", pfconf->iface); - pfconf->ctype = CLUSTER_INNER_FLOW_4_TUPLE; - } else if (strcmp(tmpctype, "cluster_inner_flow_5_tuple") == 0) { - SCLogInfo("%s: Using flow cluster inner 5 tuple mode for PF_RING", pfconf->iface); - pfconf->ctype = CLUSTER_INNER_FLOW_5_TUPLE; - } else { - SCLogError("invalid cluster-type %s", tmpctype); - SCFree(pfconf); - return NULL; - } - } - if (ConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) { - if (strcmp(tmpctype, "auto") == 0) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else if (ConfValIsTrue(tmpctype)) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } else if (ConfValIsFalse(tmpctype)) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - } else if (strcmp(tmpctype, "rx-only") == 0) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_RXONLY; - } else { - SCLogError("%s: Invalid value for checksum-checks", pfconf->iface); - } - } - - if (ConfGetChildValueBoolWithDefault(if_root, if_default, "bypass", &bool_val) == 1) { - if (bool_val) { -#ifdef HAVE_PF_RING_FLOW_OFFLOAD - SCLogConfig("%s: Enabling bypass support in PF_RING (if supported by underlying hw)", - pfconf->iface); - pfconf->flags |= PFRING_CONF_FLAGS_BYPASS; -#else - SCLogError("Bypass is not supported by this Pfring version, please upgrade"); - SCFree(pfconf); - return NULL; -#endif - } - } - - if (LiveGetOffload() == 0) { - if (GetIfaceOffloading(iface, 0, 1) == 1) { - SCLogWarning("Using PF_RING with offloading activated leads to capture problems"); - } - } else { - DisableIfaceOffloading(LiveGetDevice(iface), 0, 1); - } - return pfconf; -} - -static int PfringConfigGetThreadsCount(void *conf) -{ - PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf; - return pfp->threads; -} - -static int PfringConfLevel(void) -{ - const char *def_dev = NULL; - /* 1.0 config should return a string */ - if (ConfGet("pfring.interface", &def_dev) != 1) { - return PFRING_CONF_V2; - } else { - return PFRING_CONF_V1; - } -} - -static int GetDevAndParser(const char **live_dev, ConfigIfaceParserFunc *parser) -{ - ConfGet("pfring.live-interface", live_dev); - - /* determine which config type we have */ - if (PfringConfLevel() > PFRING_CONF_V1) { - *parser = ParsePfringConfig; - } else { - SCLogInfo("Using 1.0 style configuration for pfring"); - *parser = OldParsePfringConfig; - /* In v1: try to get interface name from config */ - if (*live_dev == NULL) { - if (ConfGet("pfring.interface", live_dev) == 1) { - SCLogInfo("Using interface %s", *live_dev); - LiveRegisterDevice(*live_dev); - } else { - SCLogInfo("No interface found, problem incoming"); - *live_dev = NULL; - } - } - } - - return 0; -} -#endif - -int RunModeIdsPfringAutoFp(void) -{ - SCEnter(); - -/* We include only if pfring is enabled */ -#ifdef HAVE_PFRING - int ret; - const char *live_dev = NULL; - ConfigIfaceParserFunc tparser; - - TimeModeSetLive(); - - ret = GetDevAndParser(&live_dev, &tparser); - if (ret != 0) { - FatalError("Unable to get parser and interface params"); - } - - ret = RunModeSetLiveCaptureAutoFp(tparser, PfringConfigGetThreadsCount, "ReceivePfring", - "DecodePfring", thread_name_autofp, live_dev); - if (ret != 0) { - FatalError("Runmode start failed"); - } - - SCLogInfo("RunModeIdsPfringAutoFp initialised"); -#endif /* HAVE_PFRING */ - - return 0; -} - -int RunModeIdsPfringSingle(void) -{ - SCEnter(); - -/* We include only if pfring is enabled */ -#ifdef HAVE_PFRING - int ret; - const char *live_dev = NULL; - ConfigIfaceParserFunc tparser; - - TimeModeSetLive(); - - ret = GetDevAndParser(&live_dev, &tparser); - if (ret != 0) { - FatalError("Unable to get parser and interface params"); - } - - ret = RunModeSetLiveCaptureSingle(tparser, - PfringConfigGetThreadsCount, - "ReceivePfring", - "DecodePfring", thread_name_single, - live_dev); - if (ret != 0) { - FatalError("Runmode start failed"); - } - - SCLogInfo("RunModeIdsPfringSingle initialised"); -#endif /* HAVE_PFRING */ - - return 0; -} - -int RunModeIdsPfringWorkers(void) -{ - SCEnter(); - -/* We include only if pfring is enabled */ -#ifdef HAVE_PFRING - int ret; - const char *live_dev = NULL; - ConfigIfaceParserFunc tparser; - - TimeModeSetLive(); - - ret = GetDevAndParser(&live_dev, &tparser); - if (ret != 0) { - FatalError("Unable to get parser and interface params"); - } - - ret = RunModeSetLiveCaptureWorkers(tparser, PfringConfigGetThreadsCount, "ReceivePfring", - "DecodePfring", thread_name_workers, live_dev); - if (ret != 0) { - FatalError("Runmode start failed"); - } - - SCLogInfo("RunModeIdsPfringWorkers initialised"); -#endif /* HAVE_PFRING */ - - return 0; -} diff --git a/src/runmode-pfring.h b/src/runmode-pfring.h deleted file mode 100644 index dbdc60091f..0000000000 --- a/src/runmode-pfring.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef SURICATA_RUNMODE_PFRING_H -#define SURICATA_RUNMODE_PFRING_H - -#include "suricata-common.h" - -int RunModeIdsPfringAutoFp(void); -int RunModeIdsPfringSingle(void); -int RunModeIdsPfringWorkers(void); -void RunModeIdsPfringRegister(void); -const char *RunModeIdsPfringGetDefaultMode(void); - -#endif /* SURICATA_RUNMODE_PFRING_H */ diff --git a/src/runmodes.c b/src/runmodes.c index 287567570c..4f84149001 100644 --- a/src/runmodes.c +++ b/src/runmodes.c @@ -41,7 +41,6 @@ #include "runmode-nfq.h" #include "runmode-pcap.h" #include "runmode-pcap-file.h" -#include "runmode-pfring.h" #include "runmode-unix-socket.h" #include "runmode-windivert.h" #include "util-unittest.h" @@ -50,8 +49,6 @@ #include "output.h" -#include "source-pfring.h" - #include "tmqh-flow.h" #include "flow-manager.h" #include "flow-bypass.h" @@ -124,12 +121,6 @@ static const char *RunModeTranslateModeToName(int runmode) return "PCAP_DEV"; case RUNMODE_PCAP_FILE: return "PCAP_FILE"; - case RUNMODE_PFRING: -#ifdef HAVE_PFRING - return "PFRING"; -#else - return "PFRING(DISABLED)"; -#endif case RUNMODE_PLUGIN: return "PLUGIN"; case RUNMODE_NFQ: @@ -231,7 +222,6 @@ void RunModeRegisterRunModes(void) RunModeIdsPcapRegister(); RunModeFilePcapRegister(); - RunModeIdsPfringRegister(); RunModeIpsNFQRegister(); RunModeIpsIPFWRegister(); RunModeErfFileRegister(); @@ -309,11 +299,6 @@ static const char *RunModeGetConfOrDefault(int capture_mode, const char *capture case RUNMODE_PCAP_FILE: custom_mode = RunModeFilePcapGetDefaultMode(); break; -#ifdef HAVE_PFRING - case RUNMODE_PFRING: - custom_mode = RunModeIdsPfringGetDefaultMode(); - break; -#endif case RUNMODE_PLUGIN: { #ifdef HAVE_PLUGINS SCCapturePlugin *plugin = SCPluginFindCaptureByName(capture_plugin_name); diff --git a/src/runmodes.h b/src/runmodes.h index 7d486121e7..86966b61d3 100644 --- a/src/runmodes.h +++ b/src/runmodes.h @@ -28,7 +28,6 @@ enum RunModes { RUNMODE_UNKNOWN = 0, RUNMODE_PCAP_DEV, RUNMODE_PCAP_FILE, - RUNMODE_PFRING, RUNMODE_NFQ, RUNMODE_NFLOG, RUNMODE_IPFW, diff --git a/src/source-pfring.c b/src/source-pfring.c deleted file mode 100644 index bb22981a6e..0000000000 --- a/src/source-pfring.c +++ /dev/null @@ -1,777 +0,0 @@ -/* Copyright (C) 2007-2019 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author William Metcalf - * \author Eric Leblond - * - * PF_RING packet acquisition support - * - * \todo remove requirement for setting cluster so old 3.x versions are supported - * \todo implement DNA support - * \todo Allow ring options such as snaplen etc, to be user configurable. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "conf.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "source-pfring.h" -#include "util-debug.h" -#include "util-checksum.h" -#include "util-privs.h" -#include "util-datalink.h" -#include "util-device.h" -#include "util-host-info.h" -#include "runmodes.h" -#include "util-profiling.h" - -TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot); -TmEcode PfringBreakLoop(ThreadVars *tv, void *data); -TmEcode ReceivePfringThreadInit(ThreadVars *, const void *, void **); -void ReceivePfringThreadExitStats(ThreadVars *, void *); -TmEcode ReceivePfringThreadDeinit(ThreadVars *, void *); - -TmEcode DecodePfringThreadInit(ThreadVars *, const void *, void **); -TmEcode DecodePfring(ThreadVars *, Packet *, void *); -TmEcode DecodePfringThreadDeinit(ThreadVars *tv, void *data); - -extern uint16_t max_pending_packets; - -#ifndef HAVE_PFRING - -/*Handle cases where we don't have PF_RING support built-in*/ -TmEcode NoPfringSupportExit(ThreadVars *, const void *, void **); - -void TmModuleReceivePfringRegister (void) -{ - tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring"; - tmm_modules[TMM_RECEIVEPFRING].ThreadInit = NoPfringSupportExit; - tmm_modules[TMM_RECEIVEPFRING].Func = NULL; - tmm_modules[TMM_RECEIVEPFRING].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVEPFRING].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEPFRING].cap_flags = SC_CAP_NET_ADMIN | SC_CAP_NET_RAW | - SC_CAP_NET_BIND_SERVICE | SC_CAP_NET_BROADCAST; - tmm_modules[TMM_RECEIVEPFRING].flags = TM_FLAG_RECEIVE_TM; -} - -void TmModuleDecodePfringRegister (void) -{ - tmm_modules[TMM_DECODEPFRING].name = "DecodePfring"; - tmm_modules[TMM_DECODEPFRING].ThreadInit = NoPfringSupportExit; - tmm_modules[TMM_DECODEPFRING].Func = NULL; - tmm_modules[TMM_DECODEPFRING].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEPFRING].ThreadDeinit = NULL; - tmm_modules[TMM_DECODEPFRING].cap_flags = 0; - tmm_modules[TMM_DECODEPFRING].flags = TM_FLAG_DECODE_TM; -} - -/** - * \brief this function prints an error message and exits. - * \param tv pointer to ThreadVars - * \param initdata pointer to the interface passed from the user - * \param data pointer gets populated with PfringThreadVars - */ -TmEcode NoPfringSupportExit(ThreadVars *tv, const void *initdata, void **data) -{ - SCLogError("Error creating thread %s: you do not have support for pfring " - "enabled please recompile with --enable-pfring", - tv->name); - exit(EXIT_FAILURE); -} - -#else /* implied we do have PF_RING support */ - -#include - -/** protect pfring_set_bpf_filter, as it is not thread safe */ -static SCMutex pfring_bpf_set_filter_lock = SCMUTEX_INITIALIZER; - -/* XXX replace with user configurable options */ -#define LIBPFRING_PROMISC 1 -#define LIBPFRING_REENTRANT 0 -#define LIBPFRING_WAIT_FOR_INCOMING 1 - -/* PfringThreadVars flags */ -#define PFRING_FLAGS_ZERO_COPY (1 << 0) -#define PFRING_FLAGS_BYPASS (1 << 1) - -/** - * \brief Structure to hold thread specific variables. - */ -struct PfringThreadVars_ -{ - /* thread specific handle */ - pfring *pd; - - /* counters */ - uint64_t bytes; - uint64_t pkts; - - uint16_t capture_kernel_packets; - uint16_t capture_kernel_drops; - uint16_t capture_bypassed; - - uint32_t flags; - - ThreadVars *tv; - TmSlot *slot; - - int vlan_in_ext_header; - - /* threads count */ - int threads; - - cluster_type ctype; - - uint8_t cluster_id; - char *interface; - LiveDevice *livedev; - - char *bpf_filter; - - ChecksumValidationMode checksum_mode; - - bool vlan_hdr_warned; -}; - -/** - * \brief Registration Function for ReceivePfring. - * \todo Unit tests are needed for this module. - */ -void TmModuleReceivePfringRegister (void) -{ - tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring"; - tmm_modules[TMM_RECEIVEPFRING].ThreadInit = ReceivePfringThreadInit; - tmm_modules[TMM_RECEIVEPFRING].Func = NULL; - tmm_modules[TMM_RECEIVEPFRING].PktAcqLoop = ReceivePfringLoop; - tmm_modules[TMM_RECEIVEPFRING].PktAcqBreakLoop = PfringBreakLoop; - tmm_modules[TMM_RECEIVEPFRING].ThreadExitPrintStats = ReceivePfringThreadExitStats; - tmm_modules[TMM_RECEIVEPFRING].ThreadDeinit = ReceivePfringThreadDeinit; - tmm_modules[TMM_RECEIVEPFRING].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registration Function for DecodePfring. - * \todo Unit tests are needed for this module. - */ -void TmModuleDecodePfringRegister (void) -{ - tmm_modules[TMM_DECODEPFRING].name = "DecodePfring"; - tmm_modules[TMM_DECODEPFRING].ThreadInit = DecodePfringThreadInit; - tmm_modules[TMM_DECODEPFRING].Func = DecodePfring; - tmm_modules[TMM_DECODEPFRING].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEPFRING].ThreadDeinit = DecodePfringThreadDeinit; - tmm_modules[TMM_DECODEPFRING].flags = TM_FLAG_DECODE_TM; -} - -static inline void PfringDumpCounters(PfringThreadVars *ptv) -{ - pfring_stat pfring_s; - if (likely((pfring_stats(ptv->pd, &pfring_s) >= 0))) { - /* pfring counter is per socket and is not cleared after read. - * So to get the number of packet on the interface we can add - * the newly seen packets and drops for this thread and add it - * to the interface counter */ - uint64_t th_pkts = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_packets); - uint64_t th_drops = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_drops); - SC_ATOMIC_ADD(ptv->livedev->pkts, pfring_s.recv - th_pkts); - SC_ATOMIC_ADD(ptv->livedev->drop, pfring_s.drop - th_drops); - StatsSetUI64(ptv->tv, ptv->capture_kernel_packets, pfring_s.recv); - StatsSetUI64(ptv->tv, ptv->capture_kernel_drops, pfring_s.drop); - -#ifdef HAVE_PF_RING_FLOW_OFFLOAD - if (ptv->flags & PFRING_FLAGS_BYPASS) { - uint64_t th_bypassed = StatsGetLocalCounterValue(ptv->tv, ptv->capture_bypassed); - SC_ATOMIC_ADD(ptv->livedev->bypassed, pfring_s.shunt - th_bypassed); - StatsSetUI64(ptv->tv, ptv->capture_bypassed, pfring_s.shunt); - } -#endif - } -} - -/** - * \brief Pfring Packet Process function. - * - * This function fills in our packet structure from libpfring. - * From here the packets are picked up by the DecodePfring thread. - * - * \param user pointer to PfringThreadVars - * \param h pointer to pfring packet header - * \param p pointer to the current packet - */ -static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p) -{ - PfringThreadVars *ptv = (PfringThreadVars *)user; - - ptv->bytes += h->caplen; - ptv->pkts++; - p->livedev = ptv->livedev; - - /* PF_RING may fail to set timestamp */ - if (h->ts.tv_sec == 0) { - struct timeval tmp_ts; - gettimeofday(&tmp_ts, NULL); - h->ts = tmp_ts; - } - - p->ts = SCTIME_FROM_TIMEVAL(&h->ts); - - /* PF_RING all packets are marked as a link type of ethernet - * so that is what we do here. */ - p->datalink = LINKTYPE_ETHERNET; - - /* In the past, we needed this vlan handling in cases - * where the vlan header was stripped from the raw packet. - * With modern (at least >= 6) versions of PF_RING, the - * 'copy_data_to_ring' function (kernel/pf_ring.c) makes - * sure that if the hardware stripped the vlan header, - * it is put back by PF_RING. - * - * PF_RING should put it back in all cases, but as a extra - * precaution keep the check here. If the vlan header is - * part of the raw packet, the vlan_offset will be set. - * So if it is not set, use the parsed info from PF_RING's - * extended header. - */ - if (ptv->vlan_in_ext_header && - h->extended_hdr.parsed_pkt.offset.vlan_offset == 0 && - h->extended_hdr.parsed_pkt.vlan_id) - { - p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id & 0x0fff; - p->vlan_idx = 1; - - if (!ptv->vlan_hdr_warned) { - SCLogWarning("no VLAN header in the raw " - "packet. See ticket #2355."); - ptv->vlan_hdr_warned = true; - } - } - - switch (ptv->checksum_mode) { - case CHECKSUM_VALIDATION_RXONLY: - if (h->extended_hdr.rx_direction == 0) { - p->flags |= PKT_IGNORE_CHECKSUM; - } - break; - case CHECKSUM_VALIDATION_DISABLE: - p->flags |= PKT_IGNORE_CHECKSUM; - break; - case CHECKSUM_VALIDATION_AUTO: - if (ChecksumAutoModeCheck(ptv->pkts, - SC_ATOMIC_GET(ptv->livedev->pkts), - SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { - ptv->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - p->flags |= PKT_IGNORE_CHECKSUM; - } - break; - default: - break; - } - - SET_PKT_LEN(p, h->caplen); -} - -#ifdef HAVE_PF_RING_FLOW_OFFLOAD -/** - * \brief Pfring bypass callback function - * - * \param p a Packet to use information from to trigger bypass - * \return 1 if bypass is successful, 0 if not - */ -static int PfringBypassCallback(Packet *p) -{ - hw_filtering_rule r; - - /* Only bypass TCP and UDP */ - if (!(PacketIsTCP(p) || PacketIsUDP(p))) { - return 0; - } - - /* Bypassing tunneled packets is currently not supported */ - if (PacketIsTunnel(p)) { - return 0; - } - - r.rule_family_type = generic_flow_id_rule; - r.rule_family.flow_id_rule.action = flow_drop_rule; - r.rule_family.flow_id_rule.thread = 0; - r.rule_family.flow_id_rule.flow_id = p->pfring_v.flow_id; - - SCLogDebug("Bypass set for flow ID = %u", p->pfring_v.flow_id); - - if (pfring_add_hw_rule(p->pfring_v.ptv->pd, &r) < 0) { - return 0; - } - - return 1; -} -#endif - -/** - * \brief Receives packets from an interface via libpfring. - * - * This function receives packets from an interface and passes - * the packet on to the pfring callback function. - * - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PfringThreadVars for ptv - * \param slot slot containing task information - * \retval TM_ECODE_OK on success - * \retval TM_ECODE_FAILED on failure - */ -TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - PfringThreadVars *ptv = (PfringThreadVars *)data; - Packet *p = NULL; - struct pfring_pkthdr hdr; - TmSlot *s = (TmSlot *)slot; - SCTime_t last_dump = SCTIME_INITIALIZER; - u_int buffer_size; - u_char *pkt_buffer; - - ptv->slot = s->slot_next; - - /* we have to enable the ring here as we need to do it after all - * the threads have called pfring_set_cluster(). */ - int rc = pfring_enable_ring(ptv->pd); - if (rc != 0) { - SCLogError("pfring_enable_ring failed returned %d ", rc); - SCReturnInt(TM_ECODE_FAILED); - } - - // Indicate that the thread is actually running its application level code (i.e., it can poll - // packets) - TmThreadsSetFlag(tv, THV_RUNNING); - - while(1) { - if (suricata_ctl_flags & SURICATA_STOP) { - SCReturnInt(TM_ECODE_OK); - } - - /* make sure we have at least one packet in the packet pool, to prevent - * us from alloc'ing packets at line rate */ - PacketPoolWait(); - - p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - SCReturnInt(TM_ECODE_FAILED); - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - /* Some flavours of PF_RING may fail to set timestamp - see PF-RING-enabled libpcap code*/ - hdr.ts.tv_sec = hdr.ts.tv_usec = 0; - - /* Check for Zero-copy mode */ - if (ptv->flags & PFRING_FLAGS_ZERO_COPY) { - buffer_size = 0; - pkt_buffer = NULL; - } else { - buffer_size = GET_PKT_DIRECT_MAX_SIZE(p); - pkt_buffer = GET_PKT_DIRECT_DATA(p); - } - - int r = pfring_recv(ptv->pd, &pkt_buffer, - buffer_size, - &hdr, - LIBPFRING_WAIT_FOR_INCOMING); - if (likely(r == 1)) { - /* profiling started before blocking pfring_recv call, so - * reset it here */ - PACKET_PROFILING_RESTART(p); - -#ifdef HAVE_PF_RING_FLOW_OFFLOAD - if (ptv->flags & PFRING_FLAGS_BYPASS) { - /* pkt hash contains the flow id in this configuration */ - p->pfring_v.flow_id = hdr.extended_hdr.pkt_hash; - p->pfring_v.ptv = ptv; - p->BypassPacketsFlow = PfringBypassCallback; - } -#endif - - /* Check for Zero-copy mode */ - if (ptv->flags & PFRING_FLAGS_ZERO_COPY) { - PacketSetData(p, pkt_buffer, hdr.caplen); - } - - PfringProcessPacket(ptv, &hdr, p); - - if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { - SCReturnInt(TM_ECODE_FAILED); - } - - /* Trigger one dump of stats every second */ - if (SCTIME_CMP_NEQ(p->ts, last_dump)) { - PfringDumpCounters(ptv); - last_dump = p->ts; - } - } else if (unlikely(r == 0)) { - if (suricata_ctl_flags & SURICATA_STOP) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(TM_ECODE_OK); - } - - /* pfring didn't use the packet yet */ - TmThreadsCaptureHandleTimeout(tv, p); - - } else { - SCLogError("pfring_recv error %" PRId32 "", r); - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(TM_ECODE_FAILED); - } - StatsSyncCountersIfSignalled(tv); - } - - return TM_ECODE_OK; -} - -/** - * \brief Stop function for ReceivePfringLoop. - * - * This function forces ReceivePfringLoop to stop the - * execution, exiting the packet capture loop. - * - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PfringThreadVars for ptv - * \retval TM_ECODE_OK on success - * \retval TM_ECODE_FAILED on failure - */ -TmEcode PfringBreakLoop(ThreadVars *tv, void *data) -{ - PfringThreadVars *ptv = (PfringThreadVars *)data; - - /* Safety check */ - if (ptv->pd == NULL) { - return TM_ECODE_FAILED; - } - - pfring_breakloop(ptv->pd); - - return TM_ECODE_OK; -} - -/** - * \brief Init function for ReceivePfring. - * - * This is a setup function for receiving packets - * via libpfring. - * - * \param tv pointer to ThreadVars - * \param initdata pointer to the interface passed from the user - * \param data pointer gets populated with PfringThreadVars - * \todo add a config option for setting cluster id - * \todo Create a general pfring setup function. - * \retval TM_ECODE_OK on success - * \retval TM_ECODE_FAILED on error - */ -TmEcode ReceivePfringThreadInit(ThreadVars *tv, const void *initdata, void **data) -{ - int rc; - u_int32_t version = 0; - PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata; - unsigned int opflag; - char const *active_runmode = RunmodeGetActive(); - - if (pfconf == NULL) - return TM_ECODE_FAILED; - - PfringThreadVars *ptv = SCCalloc(1, sizeof(PfringThreadVars)); - if (unlikely(ptv == NULL)) { - pfconf->DerefFunc(pfconf); - return TM_ECODE_FAILED; - } - - ptv->tv = tv; - ptv->threads = 1; - - ptv->interface = SCStrdup(pfconf->iface); - if (unlikely(ptv->interface == NULL)) { - SCLogError("Unable to allocate device string"); - SCFree(ptv); - SCReturnInt(TM_ECODE_FAILED); - } - - ptv->livedev = LiveGetDevice(pfconf->iface); - if (ptv->livedev == NULL) { - SCLogError("Unable to find Live device"); - SCFree(ptv); - SCReturnInt(TM_ECODE_FAILED); - } - - /* enable zero-copy mode for workers runmode */ - if (active_runmode && strcmp("workers", active_runmode) == 0) { - ptv->flags |= PFRING_FLAGS_ZERO_COPY; - SCLogPerf("Enabling zero-copy for %s", ptv->interface); - } - - ptv->checksum_mode = pfconf->checksum_mode; - - opflag = PF_RING_PROMISC; - - /* if we have a recent kernel, we need to use parsed_pkt to get VLAN info */ - if (ptv->vlan_in_ext_header) { - opflag |= PF_RING_LONG_HEADER; - } - - if (ptv->checksum_mode == CHECKSUM_VALIDATION_RXONLY) { - if (strncmp(ptv->interface, "dna", 3) == 0) { - SCLogWarning("Can't use rxonly checksum-checks on DNA interface," - " resetting to auto"); - ptv->checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else { - opflag |= PF_RING_LONG_HEADER; - } - } - -#ifdef HAVE_PF_RING_FLOW_OFFLOAD - if (pfconf->flags & PFRING_CONF_FLAGS_BYPASS) { - opflag |= PF_RING_FLOW_OFFLOAD | PF_RING_FLOW_OFFLOAD_NOUPDATES; - ptv->flags |= PFRING_FLAGS_BYPASS; - } -#endif - - ptv->pd = pfring_open(ptv->interface, (uint32_t)default_packet_size, opflag); - if (ptv->pd == NULL) { - SCLogError("Failed to open %s: pfring_open error." - " Check if %s exists and pf_ring module is loaded.", - ptv->interface, ptv->interface); - pfconf->DerefFunc(pfconf); - SCFree(ptv); - return TM_ECODE_FAILED; - } - - pfring_set_application_name(ptv->pd, (char *)PROG_NAME); - pfring_version(ptv->pd, &version); - - /* We only set cluster info if the number of pfring threads is greater than 1 */ - ptv->threads = pfconf->threads; - - ptv->cluster_id = pfconf->cluster_id; - - if ((ptv->threads == 1) && (strncmp(ptv->interface, "dna", 3) == 0)) { - SCLogInfo("DNA interface detected, not adding thread to cluster"); - } else if (strncmp(ptv->interface, "zc", 2) == 0) { - SCLogInfo("ZC interface detected, not adding thread to cluster"); - } else { - ptv->ctype = (cluster_type)pfconf->ctype; - rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, ptv->ctype); - - if (rc != 0) { - SCLogError("pfring_set_cluster " - "returned %d for cluster-id: %d", - rc, ptv->cluster_id); - if (rc != PF_RING_ERROR_NOT_SUPPORTED || (pfconf->flags & PFRING_CONF_FLAGS_CLUSTER)) { - /* cluster is mandatory as explicitly specified in the configuration */ - pfconf->DerefFunc(pfconf); - return TM_ECODE_FAILED; - } - } - } - - if (ptv->threads > 1) { - SCLogPerf("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d", - tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8, - version & 0x000000FF, ptv->interface, ptv->cluster_id); - } else { - SCLogPerf("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d, single-pfring-thread", - tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8, - version & 0x000000FF, ptv->interface, ptv->cluster_id); - } - - if (pfconf->bpf_filter) { - ptv->bpf_filter = SCStrdup(pfconf->bpf_filter); - if (unlikely(ptv->bpf_filter == NULL)) { - SCLogError("Set PF_RING bpf filter failed."); - } else { - SCMutexLock(&pfring_bpf_set_filter_lock); - rc = pfring_set_bpf_filter(ptv->pd, ptv->bpf_filter); - SCMutexUnlock(&pfring_bpf_set_filter_lock); - - if (rc < 0) { - SCLogError("Failed to compile BPF \"%s\"", ptv->bpf_filter); - return TM_ECODE_FAILED; - } - } - } - - ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", - ptv->tv); - ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", - ptv->tv); -#ifdef HAVE_PF_RING_FLOW_OFFLOAD - ptv->capture_bypassed = StatsRegisterCounter("capture.bypassed", - ptv->tv); -#endif - - /* If kernel is older than 3.0, VLAN is not stripped so we don't - * get the info from packet extended header but we will use a standard - * parsing */ - ptv->vlan_in_ext_header = 1; - if (! SCKernelVersionIsAtLeast(3, 0)) { - ptv->vlan_in_ext_header = 0; - } - - /* If VLAN tags are not in the extended header, set cluster type to 5-tuple - * or in case of a ZC interface, do nothing */ - if ((! ptv->vlan_in_ext_header) && ptv->ctype == CLUSTER_FLOW && - strncmp(ptv->interface, "zc", 2) != 0) { - SCLogPerf("VLAN not in extended header, setting cluster type to CLUSTER_FLOW_5_TUPLE"); - rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, CLUSTER_FLOW_5_TUPLE); - - if (rc != 0) { - SCLogError("pfring_set_cluster " - "returned %d for cluster-id: %d", - rc, ptv->cluster_id); - pfconf->DerefFunc(pfconf); - return TM_ECODE_FAILED; - } - } - - DatalinkSetGlobalType(LINKTYPE_ETHERNET); - - *data = (void *)ptv; - pfconf->DerefFunc(pfconf); - - return TM_ECODE_OK; -} - -/** - * \brief This function prints stats to the screen at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PfringThreadVars for ptv - */ -void ReceivePfringThreadExitStats(ThreadVars *tv, void *data) -{ - PfringThreadVars *ptv = (PfringThreadVars *)data; - - PfringDumpCounters(ptv); - SCLogPerf("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 "", - tv->name, - StatsGetLocalCounterValue(tv, ptv->capture_kernel_packets), - StatsGetLocalCounterValue(tv, ptv->capture_kernel_drops)); - SCLogPerf("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes); -#ifdef HAVE_PF_RING_FLOW_OFFLOAD - if (ptv->flags & PFRING_FLAGS_BYPASS) { - SCLogPerf("(%s) Bypass: Packets %" PRIu64 "", - tv->name, - StatsGetLocalCounterValue(tv, ptv->capture_bypassed)); - } -#endif -} - -/** - * \brief DeInit function closes pd at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PfringThreadVars for ptvi - * \retval TM_ECODE_OK is always returned - */ -TmEcode ReceivePfringThreadDeinit(ThreadVars *tv, void *data) -{ - PfringThreadVars *ptv = (PfringThreadVars *)data; - if (ptv->interface) - SCFree(ptv->interface); - pfring_remove_from_cluster(ptv->pd); - - if (ptv->bpf_filter) { - pfring_remove_bpf_filter(ptv->pd); - SCFree(ptv->bpf_filter); - } - - pfring_close(ptv->pd); - SCFree(ptv); - return TM_ECODE_OK; -} - -/** - * \brief This function passes off to link type decoders. - * - * DecodePfring decodes raw packets from PF_RING. Inside of libpcap version of - * PF_RING all packets are marked as a link type of ethernet so that is what we do here. - * - * \param tv pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into PfringThreadVars for ptv - * - * \todo Verify that PF_RING only deals with ethernet traffic - * - * \warning This function bypasses the pkt buf and len macro's - * - * \retval TM_ECODE_OK is always returned - */ -TmEcode DecodePfring(ThreadVars *tv, Packet *p, void *data) -{ - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - BUG_ON(PKT_IS_PSEUDOPKT(p)); - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - /* If suri has set vlan during reading, we increase vlan counter */ - if (p->vlan_idx) { - StatsIncr(tv, dtv->counter_vlan); - } - - DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p)); - - PacketDecodeFinalize(tv, dtv, p); - - return TM_ECODE_OK; -} - -/** - * \brief This an Init function for DecodePfring - * - * \param tv pointer to ThreadVars - * \param initdata pointer to initialization data. - * \param data pointer that gets cast into PfringThreadVars for ptv - * \retval TM_ECODE_OK is returned on success - * \retval TM_ECODE_FAILED is returned on error - */ -TmEcode DecodePfringThreadInit(ThreadVars *tv, const void *initdata, void **data) -{ - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - return TM_ECODE_OK; -} - -TmEcode DecodePfringThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -#endif /* HAVE_PFRING */ -/* eof */ diff --git a/src/source-pfring.h b/src/source-pfring.h deleted file mode 100644 index 742e0ac6cb..0000000000 --- a/src/source-pfring.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author William Metcalf - */ - -#ifndef SURICATA_SOURCE_PFRING_H -#define SURICATA_SOURCE_PFRING_H - -#define PFRING_IFACE_NAME_LENGTH 48 - -typedef struct PfringThreadVars_ PfringThreadVars; - -/* PfringIfaceConfig flags */ -#define PFRING_CONF_FLAGS_CLUSTER (1 << 0) -#define PFRING_CONF_FLAGS_BYPASS (1 << 1) - -typedef struct PfringIfaceConfig_ -{ - uint32_t flags; - - /* cluster param */ - int cluster_id; - unsigned int ctype; - - char iface[PFRING_IFACE_NAME_LENGTH]; - /* number of threads */ - int threads; - - const char *bpf_filter; - - ChecksumValidationMode checksum_mode; - SC_ATOMIC_DECLARE(unsigned int, ref); - void (*DerefFunc)(void *); -} PfringIfaceConfig; - -/** - * \brief per packet Pfring vars - * - * This structure is used to pass packet metadata in callbacks. - */ -typedef struct PfringPacketVars_ -{ - PfringThreadVars *ptv; - uint32_t flow_id; -} PfringPacketVars; - - -void TmModuleReceivePfringRegister (void); -void TmModuleDecodePfringRegister (void); - -int PfringConfGetThreads(void); -void PfringLoadConfig(void); - -/* - * We don't have to use an enum that sucks in our code - * these values must match with cluster_type in the kernel - * include file pf_ring.h - */ -#define CLUSTER_FLOW 0 -#define CLUSTER_ROUND_ROBIN 1 -#define CLUSTER_FLOW_5_TUPLE 4 -#define CLUSTER_INNER_FLOW 6 -#define CLUSTER_INNER_FLOW_2_TUPLE 7 -#define CLUSTER_INNER_FLOW_4_TUPLE 8 -#define CLUSTER_INNER_FLOW_5_TUPLE 9 -#endif /* SURICATA_SOURCE_PFRING_H */ diff --git a/src/suricata.c b/src/suricata.c index de60255199..d8e981b9e3 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -93,7 +93,6 @@ #include "source-pcap.h" #include "source-pcap-file.h" #include "source-pcap-file-helper.h" -#include "source-pfring.h" #include "source-erf-file.h" #include "source-erf-dag.h" #include "source-napatech.h" @@ -648,12 +647,6 @@ static void PrintUsage(const char *progname) #ifdef HAVE_NETMAP printf("\t--netmap[=] : run in netmap mode, no value select interfaces from suricata.yaml\n"); #endif -#ifdef HAVE_PFRING - printf("\t--pfring[=] : run in pfring mode, use interfaces from suricata.yaml\n"); - printf("\t--pfring-int : run in pfring mode, use interface \n"); - printf("\t--pfring-cluster-id : pfring cluster id \n"); - printf("\t--pfring-cluster-type : pfring cluster type for PF_RING 4.1.2 and later cluster_round_robin|cluster_flow\n"); -#endif /* HAVE_PFRING */ printf("\t--simulate-ips : force engine into IPS mode. Useful for QA\n"); #ifdef HAVE_LIBCAP_NG printf("\t--user : run suricata as this user after init\n"); @@ -711,9 +704,6 @@ static void PrintBuildInfo(void) #ifdef HAVE_PCAP_SET_BUFF strlcat(features, "PCAP_SET_BUFF ", sizeof(features)); #endif -#ifdef HAVE_PFRING - strlcat(features, "PF_RING ", sizeof(features)); -#endif #ifdef HAVE_AF_PACKET strlcat(features, "AF_PACKET ", sizeof(features)); #endif @@ -920,9 +910,6 @@ void RegisterAllModules(void) /* netmap */ TmModuleReceiveNetmapRegister(); TmModuleDecodeNetmapRegister(); - /* pfring */ - TmModuleReceivePfringRegister(); - TmModuleDecodePfringRegister(); /* dag file */ TmModuleReceiveErfFileRegister(); TmModuleDecodeErfFileRegister(); @@ -994,18 +981,6 @@ static TmEcode ParseInterfacesList(const int runmode, char *pcap_dev) SCReturnInt(TM_ECODE_FAILED); } } - } else if (runmode == RUNMODE_PFRING) { - /* FIXME add backward compat support */ - /* iface has been set on command line */ - if (strlen(pcap_dev)) { - if (ConfSetFinal("pfring.live-interface", pcap_dev) != 1) { - SCLogError("Failed to set pfring.live-interface"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - /* not an error condition if we have a 1.0 config */ - LiveBuildDeviceList("pfring"); - } #ifdef HAVE_DPDK } else if (runmode == RUNMODE_DPDK) { char iface_selector[] = "dpdk.interfaces"; @@ -1342,10 +1317,6 @@ TmEcode SCParseCommandLine(int argc, char **argv) struct option long_opts[] = { {"dump-config", 0, &dump_config, 1}, {"dump-features", 0, &dump_features, 1}, - {"pfring", optional_argument, 0, 0}, - {"pfring-int", required_argument, 0, 0}, - {"pfring-cluster-id", required_argument, 0, 0}, - {"pfring-cluster-type", required_argument, 0, 0}, #ifdef HAVE_DPDK {"dpdk", 0, 0, 0}, #endif @@ -1428,52 +1399,10 @@ TmEcode SCParseCommandLine(int argc, char **argv) while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) { switch (opt) { case 0: - if (strcmp((long_opts[option_index]).name , "pfring") == 0 || - strcmp((long_opts[option_index]).name , "pfring-int") == 0) { -#ifdef HAVE_PFRING - suri->run_mode = RUNMODE_PFRING; - if (optarg != NULL) { - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - LiveRegisterDeviceName(optarg); - } -#else - SCLogError("PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if(strcmp((long_opts[option_index]).name , "pfring-cluster-id") == 0){ -#ifdef HAVE_PFRING - if (ConfSetFinal("pfring.cluster-id", optarg) != 1) { - SCLogError("failed to set pfring.cluster-id"); - return TM_ECODE_FAILED; - } -#else - SCLogError("PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if(strcmp((long_opts[option_index]).name , "pfring-cluster-type") == 0){ -#ifdef HAVE_PFRING - if (ConfSetFinal("pfring.cluster-type", optarg) != 1) { - SCLogError("failed to set pfring.cluster-type"); - return TM_ECODE_FAILED; - } -#else - SCLogError("PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if (strcmp((long_opts[option_index]).name , "capture-plugin") == 0){ + if (strcmp((long_opts[option_index]).name, "capture-plugin") == 0) { suri->run_mode = RUNMODE_PLUGIN; suri->capture_plugin_name = optarg; - } - else if (strcmp((long_opts[option_index]).name , "capture-plugin-args") == 0){ + } else if (strcmp((long_opts[option_index]).name, "capture-plugin-args") == 0) { suri->capture_plugin_args = optarg; } else if (strcmp((long_opts[option_index]).name, "dpdk") == 0) { if (ParseCommandLineDpdk(suri, optarg) != TM_ECODE_OK) { @@ -1848,29 +1777,19 @@ TmEcode SCParseCommandLine(int argc, char **argv) return TM_ECODE_FAILED; } #else /* not afpacket */ - /* warn user if netmap or pf-ring are available */ -#if defined HAVE_PFRING || HAVE_NETMAP + /* warn user if netmap is available */ +#if defined HAVE_NETMAP int i = 0; -#ifdef HAVE_PFRING - i++; -#endif #ifdef HAVE_NETMAP i++; #endif SCLogWarning("faster capture " "option%s %s available:" -#ifdef HAVE_PFRING - " PF_RING (--pfring-int=%s)" -#endif #ifdef HAVE_NETMAP " NETMAP (--netmap=%s)" #endif ". Use --pcap=%s to suppress this warning", i == 1 ? "" : "s", i == 1 ? "is" : "are" -#ifdef HAVE_PFRING - , - optarg -#endif #ifdef HAVE_NETMAP , optarg @@ -2475,7 +2394,6 @@ static int ConfigGetCaptureValue(SCInstance *suri) case RUNMODE_PCAP_DEV: case RUNMODE_AFP_DEV: case RUNMODE_AFXDP_DEV: - case RUNMODE_PFRING: nlive = LiveGetDeviceCount(); for (lthread = 0; lthread < nlive; lthread++) { const char *live_dev = LiveGetDeviceName(lthread); diff --git a/src/tm-modules.c b/src/tm-modules.c index b9542b48f0..dbab61fa88 100644 --- a/src/tm-modules.c +++ b/src/tm-modules.c @@ -202,9 +202,7 @@ const char * TmModuleTmmIdToString(TmmId id) CASE_CODE (TMM_RECEIVEPCAP); CASE_CODE (TMM_RECEIVEPCAPFILE); CASE_CODE (TMM_DECODEPCAP); - CASE_CODE (TMM_DECODEPCAPFILE); - CASE_CODE (TMM_RECEIVEPFRING); - CASE_CODE (TMM_DECODEPFRING); + CASE_CODE(TMM_DECODEPCAPFILE); CASE_CODE(TMM_RECEIVEDPDK); CASE_CODE(TMM_DECODEDPDK); CASE_CODE (TMM_RECEIVEPLUGIN); diff --git a/src/tm-threads-common.h b/src/tm-threads-common.h index fa9a731b0d..5a31373ec5 100644 --- a/src/tm-threads-common.h +++ b/src/tm-threads-common.h @@ -39,8 +39,6 @@ typedef enum { TMM_RECEIVEPCAPFILE, TMM_DECODEPCAP, TMM_DECODEPCAPFILE, - TMM_RECEIVEPFRING, - TMM_DECODEPFRING, TMM_RECEIVEPLUGIN, TMM_DECODEPLUGIN, TMM_RESPONDREJECT, diff --git a/src/tm-threads.c b/src/tm-threads.c index 64c27a4235..cd9bf6df1f 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -210,8 +210,6 @@ static int TmThreadTimeoutLoop(ThreadVars *tv, TmSlot *s) callback process_pkt - pfring - pkt read process_pkt diff --git a/src/util-privs.c b/src/util-privs.c index 08f704197c..835247090d 100644 --- a/src/util-privs.c +++ b/src/util-privs.c @@ -65,11 +65,6 @@ void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid) CAP_NET_ADMIN, -1); break; - case RUNMODE_PFRING: - capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, - CAP_NET_ADMIN, CAP_NET_RAW, CAP_SYS_NICE, - -1); - break; case RUNMODE_NFLOG: case RUNMODE_NFQ: capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,