From: Eric Leblond Date: Thu, 20 Jun 2019 11:08:44 +0000 (+0200) Subject: bypass: introduce CAPTURE_OFFLOAD X-Git-Tag: suricata-5.0.0-rc1~137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=53a62953e902d708a4930c2867ce6146bb24d8b0;p=thirdparty%2Fsuricata.git bypass: introduce CAPTURE_OFFLOAD This define is used to remove reference to capture bypass in case no capture method implementing this is active. This patch also introduces CAPTURE_OFFLOAD_MANAGER that is defined if we need the flow bypass manager code. --- diff --git a/configure.ac b/configure.ac index c5f23f51e4..411f702763 100644 --- a/configure.ac +++ b/configure.ac @@ -2457,6 +2457,13 @@ fi fi fi +if test "${enable_ebpf}" = "yes" || test "${enable_unittests}" = "yes"; then + AC_DEFINE([CAPTURE_OFFLOAD_MANAGER], [1],[Building flow bypass manager code]) +fi +if test "${enable_ebpf}" = "yes" || test "${enable_nfqueue}" = "yes" || test "${enable_pfring}" = "yes" || test "${enable_unittests}" = "yes"; then + AC_DEFINE([CAPTURE_OFFLOAD], [1],[Building flow capture bypass code]) +fi + AC_SUBST(CFLAGS) AC_SUBST(LDFLAGS) AC_SUBST(CPPFLAGS) diff --git a/src/decode.c b/src/decode.c index f0f793f81c..2516bc0802 100644 --- a/src/decode.c +++ b/src/decode.c @@ -400,6 +400,7 @@ void PacketDefragPktSetupParent(Packet *parent) void PacketBypassCallback(Packet *p) { +#ifdef CAPTURE_OFFLOAD /* Don't try to bypass if flow is already out or * if we have failed to do it once */ if (p->flow) { @@ -424,6 +425,14 @@ void PacketBypassCallback(Packet *p) FlowUpdateState(p->flow, FLOW_STATE_LOCAL_BYPASSED); } } +#else /* CAPTURE_OFFLOAD */ + if (p->flow) { + int state = SC_ATOMIC_GET(p->flow->flow_state); + if (state == FLOW_STATE_LOCAL_BYPASSED) + return; + FlowUpdateState(p->flow, FLOW_STATE_LOCAL_BYPASSED); + } +#endif } /** \brief switch direction of a packet */ diff --git a/src/flow-bypass.c b/src/flow-bypass.c index 3629de7c8d..267e2b4b52 100644 --- a/src/flow-bypass.c +++ b/src/flow-bypass.c @@ -28,7 +28,7 @@ #include "flow-private.h" #include "util-ebpf.h" -#ifndef OS_WIN32 +#ifdef CAPTURE_OFFLOAD_MANAGER #define FLOW_BYPASS_DELAY 10 @@ -175,7 +175,7 @@ int BypassedFlowManagerRegisterUpdateFunc(BypassedUpdateFunc UpdateFunc, /** \brief spawn the flow bypass manager thread */ void BypassedFlowManagerThreadSpawn() { -#ifndef OS_WIN32 +#ifdef CAPTURE_OFFLOAD_MANAGER #ifdef AFLFUZZ_DISABLE_MGTTHREADS return; #endif @@ -198,7 +198,7 @@ void BypassedFlowManagerThreadSpawn() void BypassedFlowUpdate(Flow *f, Packet *p) { -#ifndef OS_WIN32 +#ifdef CAPTURE_OFFLOAD_MANAGER for (int i = 0; i < g_bypassed_update_max_index; i++) { if (updatefunclist[i].Func(f, p, updatefunclist[i].data)) { return; @@ -209,7 +209,7 @@ void BypassedFlowUpdate(Flow *f, Packet *p) void TmModuleBypassedFlowManagerRegister (void) { -#ifndef OS_WIN32 +#ifdef CAPTURE_OFFLOAD_MANAGER tmm_modules[TMM_BYPASSEDFLOWMANAGER].name = "BypassedFlowManager"; tmm_modules[TMM_BYPASSEDFLOWMANAGER].ThreadInit = BypassedFlowManagerThreadInit; tmm_modules[TMM_BYPASSEDFLOWMANAGER].ThreadDeinit = BypassedFlowManagerThreadDeinit; diff --git a/src/flow-hash.c b/src/flow-hash.c index e7788b2f1b..9a4280778f 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -930,8 +930,10 @@ static Flow *FlowGetUsedFlow(ThreadVars *tv, DecodeThreadVars *dtv) f->flow_end_flags |= FLOW_END_FLAG_STATE_ESTABLISHED; else if (state == FLOW_STATE_CLOSED) f->flow_end_flags |= FLOW_END_FLAG_STATE_CLOSED; +#ifdef CAPTURE_OFFLOAD else if (state == FLOW_STATE_CAPTURE_BYPASSED) f->flow_end_flags |= FLOW_END_FLAG_STATE_BYPASSED; +#endif else if (state == FLOW_STATE_LOCAL_BYPASSED) f->flow_end_flags |= FLOW_END_FLAG_STATE_BYPASSED; diff --git a/src/flow-manager.c b/src/flow-manager.c index 54f5e5d64a..e515332192 100644 --- a/src/flow-manager.c +++ b/src/flow-manager.c @@ -222,9 +222,11 @@ static inline uint32_t FlowGetFlowTimeout(const Flow *f, enum FlowState state) case FLOW_STATE_CLOSED: timeout = flow_timeouts[f->protomap].closed_timeout; break; +#ifdef CAPTURE_OFFLOAD case FLOW_STATE_CAPTURE_BYPASSED: timeout = FLOW_BYPASSED_TIMEOUT; break; +#endif case FLOW_STATE_LOCAL_BYPASSED: timeout = flow_timeouts[f->protomap].bypassed_timeout; break; @@ -262,6 +264,7 @@ static int FlowManagerFlowTimeout(Flow *f, enum FlowState state, struct timeval static inline int FlowBypassedTimeout(Flow *f, struct timeval *ts, FlowTimeoutCounters *counters) { +#ifdef CAPTURE_OFFLOAD if (SC_ATOMIC_GET(f->flow_state) != FLOW_STATE_CAPTURE_BYPASSED) { return 1; } @@ -300,6 +303,7 @@ static inline int FlowBypassedTimeout(Flow *f, struct timeval *ts, return 1; } } +#endif /* CAPTURE_OFFLOAD */ return 1; } @@ -329,7 +333,9 @@ static inline int FlowManagerFlowTimedOut(Flow *f, struct timeval *ts, int server = 0, client = 0; if (!(f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE) && +#ifdef CAPTURE_OFFLOAD SC_ATOMIC_GET(f->flow_state) != FLOW_STATE_CAPTURE_BYPASSED && +#endif SC_ATOMIC_GET(f->flow_state) != FLOW_STATE_LOCAL_BYPASSED && FlowForceReassemblyNeedReassembly(f, &server, &client) == 1) { FlowForceReassemblyForFlow(f, server, client); @@ -417,8 +423,10 @@ static uint32_t FlowManagerHashRowTimeout(Flow *f, struct timeval *ts, f->flow_end_flags |= FLOW_END_FLAG_STATE_CLOSED; else if (state == FLOW_STATE_LOCAL_BYPASSED) f->flow_end_flags |= FLOW_END_FLAG_STATE_BYPASSED; +#ifdef CAPTURE_OFFLOAD else if (state == FLOW_STATE_CAPTURE_BYPASSED) f->flow_end_flags |= FLOW_END_FLAG_STATE_BYPASSED; +#endif if (emergency) f->flow_end_flags |= FLOW_END_FLAG_EMERGENCY; @@ -443,7 +451,9 @@ static uint32_t FlowManagerHashRowTimeout(Flow *f, struct timeval *ts, counters->clo++; break; case FLOW_STATE_LOCAL_BYPASSED: +#ifdef CAPTURE_OFFLOAD case FLOW_STATE_CAPTURE_BYPASSED: +#endif counters->byp++; break; } diff --git a/src/flow-worker.c b/src/flow-worker.c index d6b421e9d0..7c6cf22401 100644 --- a/src/flow-worker.c +++ b/src/flow-worker.c @@ -78,10 +78,12 @@ static inline TmEcode FlowUpdate(ThreadVars *tv, FlowWorkerThreadData *fw, Packe int state = SC_ATOMIC_GET(p->flow->flow_state); switch (state) { +#ifdef CAPTURE_OFFLOAD case FLOW_STATE_CAPTURE_BYPASSED: StatsAddUI64(tv, fw->both_bypass_pkts, 1); StatsAddUI64(tv, fw->both_bypass_bytes, GET_PKT_LEN(p)); return TM_ECODE_DONE; +#endif case FLOW_STATE_LOCAL_BYPASSED: StatsAddUI64(tv, fw->local_bypass_pkts, 1); StatsAddUI64(tv, fw->local_bypass_bytes, GET_PKT_LEN(p)); diff --git a/src/flow.c b/src/flow.c index 201e48875c..5fcf531357 100644 --- a/src/flow.c +++ b/src/flow.c @@ -399,11 +399,14 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p) { SCLogDebug("packet %"PRIu64" -- flow %p", p->pcap_cnt, f); +#ifdef CAPTURE_OFFLOAD int state = SC_ATOMIC_GET(f->flow_state); if (state != FLOW_STATE_CAPTURE_BYPASSED) { +#endif /* update the last seen timestamp of this flow */ COPY_TIMESTAMP(&p->ts, &f->lastts); +#ifdef CAPTURE_OFFLOAD } else { /* still seeing packet, we downgrade to local bypass */ if (p->ts.tv_sec - f->lastts.tv_sec > FLOW_BYPASSED_TIMEOUT / 2) { @@ -418,7 +421,7 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p) } } } - +#endif /* update flags and counters */ if (FlowGetPacketDirection(f, p) == TOSERVER) { f->todstpktcnt++; diff --git a/src/flow.h b/src/flow.h index 6727816135..62dcd67ea1 100644 --- a/src/flow.h +++ b/src/flow.h @@ -468,7 +468,9 @@ enum FlowState { FLOW_STATE_ESTABLISHED, FLOW_STATE_CLOSED, FLOW_STATE_LOCAL_BYPASSED, +#ifdef CAPTURE_OFFLOAD FLOW_STATE_CAPTURE_BYPASSED, +#endif }; typedef struct FlowProtoTimeout_ { diff --git a/src/output-json-flow.c b/src/output-json-flow.c index 88a3a547f9..55f2b908e4 100644 --- a/src/output-json-flow.c +++ b/src/output-json-flow.c @@ -274,10 +274,12 @@ static void JsonFlowLogJSON(JsonFlowLogThread *aft, json_t *js, Flow *f) json_object_set_new(hjs, "bypass", json_string("local")); break; +#ifdef CAPTURE_OFFLOAD case FLOW_STATE_CAPTURE_BYPASSED: json_object_set_new(hjs, "bypass", json_string("capture")); break; +#endif default: SCLogError(SC_ERR_INVALID_VALUE, "Invalid flow state: %d, contact developers",