From: Russ Combs Date: Sat, 22 Oct 2016 22:21:31 +0000 (-0400) Subject: move fp detect thread locals to ips context X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a3f55b5324032b6caee93080b2ca670ff49681f;p=thirdparty%2Fsnort3.git move fp detect thread locals to ips context --- diff --git a/src/detection/detection_engine.cc b/src/detection/detection_engine.cc index 7eb2d7a50..1505c5cd4 100644 --- a/src/detection/detection_engine.cc +++ b/src/detection/detection_engine.cc @@ -51,6 +51,9 @@ DetectionEngine::DetectionEngine() DetectionEngine::~DetectionEngine() { clear_packet(); } +IpsContext* DetectionEngine::get_context() +{ return Snort::get_switcher()->get_context(); } + SF_EVENTQ* DetectionEngine::get_event_queue() { return Snort::get_switcher()->get_context()->equeue; } @@ -60,6 +63,9 @@ Packet* DetectionEngine::get_current_packet() Packet* DetectionEngine::get_packet() { return get_current_packet(); } +MpseStash* DetectionEngine::get_stash() +{ return Snort::get_switcher()->get_context()->stash; } + Packet* DetectionEngine::set_packet() { // we need to stay in the current context until rebuild is successful diff --git a/src/detection/detection_engine.h b/src/detection/detection_engine.h index 2de6912c2..b8330cbda 100644 --- a/src/detection/detection_engine.h +++ b/src/detection/detection_engine.h @@ -28,6 +28,7 @@ #include "actions/actions.h" #include "main/snort_types.h" +class IpsContext; class IpsContextData; struct Packet; @@ -40,10 +41,13 @@ public: Packet* get_packet(); public: + static IpsContext* get_context(); + static Packet* get_current_packet(); static Packet* set_packet(); static void clear_packet(); + static class MpseStash* get_stash(); static uint8_t* get_buffer(unsigned& max); static void set_data(unsigned id, IpsContextData*); diff --git a/src/detection/detection_options.cc b/src/detection/detection_options.cc index 627f364f4..e6c9088a7 100644 --- a/src/detection/detection_options.cc +++ b/src/detection/detection_options.cc @@ -53,6 +53,16 @@ #include "fp_detect.h" #include "pattern_match_data.h" +#include "detection_defines.h" +#include "detection_engine.h" +#include "detection_util.h" +#include "fp_create.h" +#include "fp_detect.h" +#include "ips_context.h" +#include "pattern_match_data.h" +#include "rules.h" +#include "treenodes.h" + #define HASH_RULE_OPTIONS 16384 #define HASH_RULE_TREE 8192 @@ -353,8 +363,9 @@ int detection_option_node_evaluate( char flowbits_setoperation = 0; int loop_count = 0; uint32_t tmp_byte_extract_vars[NUM_BYTE_EXTRACT_VARS]; - uint64_t cur_eval_pkt_count = - (rule_eval_pkt_count + (PacketManager::get_rebuilt_packet_count())); + + uint64_t cur_eval_pkt_count = DetectionEngine::get_context()->pkt_count + + PacketManager::get_rebuilt_packet_count(); if ( !eval_data || !eval_data->p || !eval_data->pomd ) return 0; @@ -413,7 +424,7 @@ int detection_option_node_evaluate( int16_t app_proto = p->get_application_protocol(); int check_ports = 1; - if ( app_proto and ((OTNX_MATCH_DATA*)(pomd))->check_ports != 2 ) + if ( app_proto and ((OtnxMatchData*)(pomd))->check_ports != 2 ) { auto sig_info = otn->sigInfo; @@ -463,7 +474,7 @@ int detection_option_node_evaluate( { PatternMatchData* pmd = (PatternMatchData*)eval_data->pmd; int pattern_size = pmd ? pmd->pattern_size : 0; - fpAddMatch((OTNX_MATCH_DATA*)pomd, pattern_size, otn); + fpAddMatch((OtnxMatchData*)pomd, pattern_size, otn); } result = rval = DETECTION_OPTION_MATCH; } diff --git a/src/detection/fp_detect.cc b/src/detection/fp_detect.cc index 3de73cc0b..d73f484c5 100644 --- a/src/detection/fp_detect.cc +++ b/src/detection/fp_detect.cc @@ -76,30 +76,11 @@ THREAD_LOCAL ProfileStats ruleRTNEvalPerfStats; THREAD_LOCAL ProfileStats ruleOTNEvalPerfStats; THREAD_LOCAL ProfileStats ruleNFPEvalPerfStats; -THREAD_LOCAL uint64_t rule_eval_pkt_count = 0; - -static THREAD_LOCAL OTNX_MATCH_DATA t_omd; - -/* initialize the global OTNX_MATCH_DATA variable */ -void otnx_match_data_init(int num_rule_types) -{ - t_omd.iMatchInfoArraySize = num_rule_types; - t_omd.matchInfo = (MATCH_INFO*)snort_calloc(num_rule_types, sizeof(MATCH_INFO)); -} - -void otnx_match_data_term() -{ - if ( t_omd.matchInfo ) - snort_free(t_omd.matchInfo); - - t_omd.matchInfo = nullptr; -} - -// Initialize the OTNX_MATCH_DATA structure. We do this for +// Initialize the OtnxMatchData structure. We do this for // every packet so this only sets the necessary counters to // zero which saves us time. -static inline void InitMatchInfo(OTNX_MATCH_DATA* o) +static inline void init_match_info(OtnxMatchData* o) { for ( int i = 0; i < o->iMatchInfoArraySize; i++ ) o->matchInfo[i].iMatchCount = 0; @@ -230,17 +211,13 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p) } /* -** -** NAME -** fpAddMatch:: -** ** DESCRIPTION ** Add and Event to the appropriate Match Queue: Alert, Pass, or Log. ** This allows us to find multiple events per packet and pick the 'best' ** one. This function also allows us to change the order of alert, ** pass, and log signatures by cacheing them for decision later. ** -** IMPORTANT NOTE: +** IMPORTANT NOTE: ** fpAddMatch must be called even when the queue has been maxed ** out. This is because there are three different queues (alert, ** pass, log) and unless all three are filled (or at least the @@ -248,7 +225,7 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p) ** at to see if they are members of a queue that is not maxed out. ** ** FORMAL INPUTS -** OTNX_MATCH_DATA * - the omd to add the event to. +** OtnxMatchData * - the omd to add the event to. ** int pLen - length of pattern that matched, 0 for no content ** OptTreeNode * - the otn to add. ** @@ -256,7 +233,7 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p) ** int - 1 max_events variable hit, 0 successful. ** */ -int fpAddMatch(OTNX_MATCH_DATA* omd_local, int /*pLen*/, const OptTreeNode* otn) +int fpAddMatch(OtnxMatchData* omd_local, int /*pLen*/, const OptTreeNode* otn) { RuleTreeNode* rtn = getRuntimeRtnFromOtn(otn); int evalIndex = rtn->listhead->ruleListNode->evalIndex; @@ -267,7 +244,7 @@ int fpAddMatch(OTNX_MATCH_DATA* omd_local, int /*pLen*/, const OptTreeNode* otn) pc.match_limit++; return 1; } - MATCH_INFO* pmi = &omd_local->matchInfo[evalIndex]; + MatchInfo* pmi = &omd_local->matchInfo[evalIndex]; /* ** If we hit the max number of unique events for any rule type alert, @@ -296,10 +273,6 @@ int fpAddMatch(OTNX_MATCH_DATA* omd_local, int /*pLen*/, const OptTreeNode* otn) } /* -** -** NAME -** fpEvalRTN:: -** ** DESCRIPTION ** Evaluates an RTN against a packet. We can probably get rid of ** the check_ports variable, but it's in there for good luck. :) @@ -311,7 +284,6 @@ int fpAddMatch(OTNX_MATCH_DATA* omd_local, int /*pLen*/, const OptTreeNode* otn) ** ** FORMAL OUTPUT ** int - 1 if match, 0 if match failed. -** */ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports) { @@ -334,11 +306,6 @@ int fpEvalRTN(RuleTreeNode* rtn, Packet* p, int check_ports) return 0; } - DebugMessage(DEBUG_DETECT, - "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); - DebugFormat(DEBUG_DETECT, " => RTN %p Matched!\n", (void*) rtn); - DebugMessage(DEBUG_DETECT, - "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n"); /* ** Return that there is a rule match and log the event outside ** of this routine. @@ -373,7 +340,7 @@ static int rule_tree_match( void* user, void* tree, int index, void* context, void* neg_list) { PMX* pmx = (PMX*)user; - OTNX_MATCH_DATA* pomd = (OTNX_MATCH_DATA*)context; + OtnxMatchData* pomd = (OtnxMatchData*)context; detection_option_tree_root_t* root = (detection_option_tree_root_t*)tree; detection_option_eval_data_t eval_data; @@ -402,8 +369,8 @@ static int rule_tree_match( last_check->ts.tv_sec = eval_data.p->pkth->ts.tv_sec; last_check->ts.tv_usec = eval_data.p->pkth->ts.tv_usec; - last_check->packet_number = (rule_eval_pkt_count - + (PacketManager::get_rebuilt_packet_count())); + last_check->packet_number = DetectionEngine::get_context()->pkt_count + + PacketManager::get_rebuilt_packet_count(); last_check->rebuild_flag = (eval_data.p->packet_flags & PKT_REBUILT_STREAM); } @@ -522,10 +489,6 @@ static int sortOrderByContentLength(const void* e1, const void* e2) } /* -** -** NAME -** fpAddSessionAlert:: -** ** DESCRIPTION ** This function flags an alert per session. ** @@ -536,7 +499,6 @@ static int sortOrderByContentLength(const void* e1, const void* e2) ** FORMAL OUTPUTS ** int - 0 if not flagged ** 1 if flagged -** */ static inline int fpAddSessionAlert(Packet* p, const OptTreeNode* otn) { @@ -551,10 +513,6 @@ static inline int fpAddSessionAlert(Packet* p, const OptTreeNode* otn) } /* -** -** NAME -** fpSessionAlerted:: -** ** DESCRIPTION ** This function indicates whether or not an alert has been generated previously ** in this session, but only if this is a rebuilt packet. @@ -566,7 +524,6 @@ static inline int fpAddSessionAlert(Packet* p, const OptTreeNode* otn) ** FORMAL OUTPUTS ** int - 0 if alert NOT previously generated ** 1 if alert previously generated -** */ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn) { @@ -579,10 +536,6 @@ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn) } /* -** -** NAME -** fpFinalSelectEvent:: -** ** DESCRIPTION ** fpFinalSelectEvent is called at the end of packet processing ** to decide, if there hasn't already been a selection, to decide @@ -594,7 +547,7 @@ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn) ** same event twice. This can happen with unique conflicts some ** of the time. ** -** IMPORTANT NOTE: +** IMPORTANT NOTE: ** We call fpFinalSelectEvent() after all processing of the packet ** has been completed. The reason this must be called afterwards is ** because of unique rule group conflicts for a packet. If there is @@ -608,7 +561,7 @@ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn) ** precedence. We now inspect both rule groups before doing a final ** event select. ** -** NOTES +** MORE NOTES ** Jan 2006 : marc norton ** Previously it was possible to not log all desired events, if for ** instance the rule order was alert->drop in inline mode we would @@ -644,14 +597,13 @@ static inline int fpSessionAlerted(Packet* p, const OptTreeNode* otn) ** the --alert-on-drop flag ) ** ** FORMAL INPUTS -** OTNX_MATCH_DATA * - omd to select event from. +** OtnxMatchData * - omd to select event from. ** Packet * - pointer to packet to log. ** ** FORMAL OUTPUT ** int - return 0 if no match, 1 if match. -** */ -static inline int fpFinalSelectEvent(OTNX_MATCH_DATA* o, Packet* p) +static inline int fpFinalSelectEvent(OtnxMatchData* o, Packet* p) { if ( !o->have_match ) return 0; @@ -788,8 +740,6 @@ private: } queue[max]; }; -static THREAD_LOCAL MpseStash stash; - // uniquely insert into q, should splay elements for performance // return true if maxed out to trigger a flush bool MpseStash::push(void* user, void* tree, int index, void* list) @@ -846,13 +796,35 @@ bool MpseStash::process(MpseMatch match, void* context) return false; } +void fp_set_context(IpsContext& c) +{ + c.stash = new MpseStash; + + c.otnx = (OtnxMatchData*)snort_calloc(sizeof(OtnxMatchData)); + c.otnx->iMatchInfoArraySize = snort_conf->num_rule_types; + + c.otnx->matchInfo = (MatchInfo*)snort_calloc( + snort_conf->num_rule_types, sizeof(MatchInfo)); + + c.pkt_count = 0; +} + +void fp_clear_context(IpsContext& c) +{ + delete c.stash; + snort_free(c.otnx->matchInfo); + snort_free(c.otnx); +} + // rule_tree_match() could be used instead to bypass the queuing static int rule_tree_queue( void* user, void* tree, int index, void* context, void* list) { - if ( stash.push(user, tree, index, list) ) + MpseStash* stash = DetectionEngine::get_stash(); + + if ( stash->push(user, tree, index, list) ) { - if ( stash.process(rule_tree_match, context) ) + if ( stash->process(rule_tree_match, context) ) { return 1; } @@ -866,9 +838,10 @@ static int rule_tree_queue( int start_state = 0; \ cnt++; \ omd->data = buf; omd->size = len; \ - stash.init(); \ + MpseStash* stash = DetectionEngine::get_stash(); \ + stash->init(); \ so->search(buf, len, rule_tree_queue, omd, &start_state); \ - stash.process(rule_tree_match, omd); \ + stash->process(rule_tree_match, omd); \ if ( PacketLatency::fastpath() ) \ return 1; \ } @@ -882,7 +855,7 @@ static int rule_tree_queue( static int fp_search( PortGroup* port_group, Packet* p, - int check_ports, int type, OTNX_MATCH_DATA* omd) + int check_ports, int type, OtnxMatchData* omd) { Inspector* gadget = p->flow ? p->flow->gadget : nullptr; InspectionBuffer buf; @@ -939,10 +912,6 @@ static int fp_search( } /* -** -** NAME -** fpEvalHeaderSW:: -** ** DESCRIPTION ** This function does a set-wise match on content, and walks an otn list ** for non-content. The otn list search will eventually be redone for @@ -957,10 +926,9 @@ static int fp_search( ** FORMAL OUTPUTS ** int - 0 for failed pattern match ** 1 for sucessful pattern match -** */ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p, - int check_ports, char ip_rule, int type, OTNX_MATCH_DATA* omd) + int check_ports, char ip_rule, int type, OtnxMatchData* omd) { const uint8_t* tmp_payload; int8_t curr_ip_layer = 0; @@ -1058,7 +1026,7 @@ static inline int fpEvalHeaderSW(PortGroup* port_group, Packet* p, return 0; } -static inline void fpEvalHeaderIp(Packet* p, OTNX_MATCH_DATA* omd) +static inline void fpEvalHeaderIp(Packet* p, OtnxMatchData* omd) { PortGroup* any = nullptr, * ip_group = nullptr; @@ -1075,7 +1043,7 @@ static inline void fpEvalHeaderIp(Packet* p, OTNX_MATCH_DATA* omd) fpEvalHeaderSW(any, p, 0, 1, 0, omd); } -static inline void fpEvalHeaderIcmp(Packet* p, OTNX_MATCH_DATA* omd) +static inline void fpEvalHeaderIcmp(Packet* p, OtnxMatchData* omd) { PortGroup* any = nullptr, * type = nullptr; @@ -1089,7 +1057,7 @@ static inline void fpEvalHeaderIcmp(Packet* p, OTNX_MATCH_DATA* omd) fpEvalHeaderSW(any, p, 0, 0, 0, omd); } -static inline void fpEvalHeaderTcp(Packet* p, OTNX_MATCH_DATA* omd) +static inline void fpEvalHeaderTcp(Packet* p, OtnxMatchData* omd) { PortGroup* src = nullptr, * dst = nullptr, * any = nullptr; @@ -1110,7 +1078,7 @@ static inline void fpEvalHeaderTcp(Packet* p, OTNX_MATCH_DATA* omd) fpEvalHeaderSW(any, p, 1, 0, 0, omd); } -static inline void fpEvalHeaderUdp(Packet* p, OTNX_MATCH_DATA* omd) +static inline void fpEvalHeaderUdp(Packet* p, OtnxMatchData* omd) { PortGroup* src = nullptr, * dst = nullptr, * any = nullptr; @@ -1131,7 +1099,7 @@ static inline void fpEvalHeaderUdp(Packet* p, OTNX_MATCH_DATA* omd) fpEvalHeaderSW(any, p, 1, 0, 0, omd) ; } -static inline bool fpEvalHeaderSvc(Packet* p, OTNX_MATCH_DATA* omd, int proto) +static inline bool fpEvalHeaderSvc(Packet* p, OtnxMatchData* omd, int proto) { PortGroup* svc = nullptr, * file = nullptr; @@ -1177,7 +1145,7 @@ static inline bool fpEvalHeaderSvc(Packet* p, OTNX_MATCH_DATA* omd, int proto) static void fpEvalPacketUdp(Packet* p) { - OTNX_MATCH_DATA* omd = &t_omd; + OtnxMatchData* omd = DetectionEngine::get_context()->otnx; uint16_t tmp_sp = p->ptrs.sp; uint16_t tmp_dp = p->ptrs.dp; @@ -1236,8 +1204,8 @@ static void fpEvalPacketUdp(Packet* p) */ int fpEvalPacket(Packet* p) { - OTNX_MATCH_DATA* omd = &t_omd; - InitMatchInfo(omd); + OtnxMatchData* omd = DetectionEngine::get_context()->otnx; + init_match_info(omd); /* Run UDP rules against the UDP header of Teredo packets */ // FIXIT-L udph is always inner; need to check for outer @@ -1294,20 +1262,3 @@ int fpEvalPacket(Packet* p) return fpFinalSelectEvent(omd, p); } -OptTreeNode* GetOTN(uint32_t gid, uint32_t sid) -{ - OptTreeNode* otn = OtnLookup(snort_conf->otn_map, gid, sid); - - if ( !otn ) - return nullptr; - - if ( !getRtnFromOtn(otn) ) - { - // If not configured to autogenerate and there isn't an RTN, meaning - // this rule isn't in the current policy, return nullptr. - return nullptr; - } - - return otn; -} - diff --git a/src/detection/fp_detect.h b/src/detection/fp_detect.h index ba18ec2b7..39b2ac893 100644 --- a/src/detection/fp_detect.h +++ b/src/detection/fp_detect.h @@ -61,12 +61,11 @@ int fpEvalRTN(RuleTreeNode*, Packet*, int check_ports); #define MAX_EVENT_MATCH 100 /* -** MATCH_INFO ** The events that are matched get held in this structure, ** and iMatchIndex gets set to the event that holds the ** highest priority. */ -struct MATCH_INFO +struct MatchInfo { const OptTreeNode* MatchArray[MAX_EVENT_MATCH]; int iMatchCount; @@ -75,7 +74,6 @@ struct MATCH_INFO }; /* -** OTNX_MATCH_DATA ** This structure holds information that is ** referenced during setwise pattern matches. ** It also contains information regarding the @@ -83,7 +81,7 @@ struct MATCH_INFO ** the event to log based on the event comparison ** function. */ -struct OTNX_MATCH_DATA +struct OtnxMatchData { PortGroup* pg; Packet* p; @@ -94,19 +92,15 @@ struct OTNX_MATCH_DATA int check_ports; bool have_match; - MATCH_INFO* matchInfo; + MatchInfo* matchInfo; int iMatchInfoArraySize; }; -void otnx_match_data_init(int); -void otnx_match_data_term(); +int fpAddMatch(OtnxMatchData*, int pLen, const OptTreeNode*); -int fpAddMatch(OTNX_MATCH_DATA*, int pLen, const OptTreeNode*); -OptTreeNode* GetOTN(uint32_t gid, uint32_t sid); - -/* counter for number of times we evaluate rules. Used to - * cache result of check for rule option tree nodes. */ -extern THREAD_LOCAL uint64_t rule_eval_pkt_count; +class IpsContext; +void fp_set_context(IpsContext&); +void fp_clear_context(IpsContext&); #endif diff --git a/src/detection/ips_context.cc b/src/detection/ips_context.cc index 6e228bd36..277d69b3d 100644 --- a/src/detection/ips_context.cc +++ b/src/detection/ips_context.cc @@ -29,6 +29,8 @@ #include "events/sfeventq.h" #include "main/snort_config.h" +#include "fp_detect.h" + #ifdef UNIT_TEST #include "catch/catch.hpp" #endif @@ -60,6 +62,8 @@ IpsContext::IpsContext(unsigned size) : const EventQueueConfig* qc = snort_conf->event_queue_config; equeue = sfeventq_new(qc->max_events, qc->log_events, sizeof(EventNode)); + + fp_set_context(*this); } IpsContext::~IpsContext() @@ -69,6 +73,7 @@ IpsContext::~IpsContext() delete p; sfeventq_free(equeue); + fp_clear_context(*this); delete[] buf; delete pkth; diff --git a/src/detection/ips_context.h b/src/detection/ips_context.h index 6c7e421ab..cdd5be86b 100644 --- a/src/detection/ips_context.h +++ b/src/detection/ips_context.h @@ -66,6 +66,11 @@ public: Packet* packet; DAQ_PktHdr_t* pkth; uint8_t* buf; + + class MpseStash* stash; + struct OtnxMatchData* otnx; + uint64_t pkt_count; + struct SF_EVENTQ* equeue; static const unsigned buf_size = 65536; diff --git a/src/detection/signature.cc b/src/detection/signature.cc index 2427cbef6..b64b6bfe4 100644 --- a/src/detection/signature.cc +++ b/src/detection/signature.cc @@ -353,6 +353,23 @@ OptTreeNode* OtnLookup(SFGHASH* otn_map, uint32_t gid, uint32_t sid) return otn; } +OptTreeNode* GetOTN(uint32_t gid, uint32_t sid) +{ + OptTreeNode* otn = OtnLookup(snort_conf->otn_map, gid, sid); + + if ( !otn ) + return nullptr; + + if ( !getRtnFromOtn(otn) ) + { + // If not configured to autogenerate and there isn't an RTN, meaning + // this rule isn't in the current policy, return nullptr. + return nullptr; + } + + return otn; +} + void OtnLookupFree(SFGHASH* otn_map) { if (otn_map == NULL) diff --git a/src/detection/signature.h b/src/detection/signature.h index 4f2215c69..28455071c 100644 --- a/src/detection/signature.h +++ b/src/detection/signature.h @@ -107,5 +107,7 @@ void OtnRemove(SFGHASH*, OptTreeNode*); void OtnDeleteData(void* data); void OtnFree(void* data); +OptTreeNode* GetOTN(uint32_t gid, uint32_t sid); + #endif diff --git a/src/main/snort.cc b/src/main/snort.cc index fdc5b7d37..50c78adaa 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -676,8 +676,6 @@ void Snort::thread_init_unprivileged() EventTrace_Init(); detection_filter_init(snort_conf->detection_filter_config); - otnx_match_data_init(snort_conf->num_rule_types); - EventManager::open_outputs(); IpsManager::setup_options(); ActionManager::thread_init(snort_conf); @@ -721,7 +719,6 @@ void Snort::thread_term() Profiler::consolidate_stats(); - otnx_match_data_term(); detection_filter_term(); EventTrace_Term(); CleanupTag(); @@ -846,7 +843,6 @@ DAQ_Verdict Snort::packet_callback( Profile profile(totalPerfStats); pc.total_from_daq++; - rule_eval_pkt_count++; packet_time_update(&pkthdr->ts); if ( snort_conf->pkt_skip && pc.total_from_daq <= snort_conf->pkt_skip ) @@ -854,6 +850,7 @@ DAQ_Verdict Snort::packet_callback( s_switcher->start(); s_packet = s_switcher->get_context()->packet; + s_switcher->get_context()->pkt_count++; sfthreshold_reset(); ActionManager::reset_queue();