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)
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) {
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 */
#include "flow-private.h"
#include "util-ebpf.h"
-#ifndef OS_WIN32
+#ifdef CAPTURE_OFFLOAD_MANAGER
#define FLOW_BYPASS_DELAY 10
/** \brief spawn the flow bypass manager thread */
void BypassedFlowManagerThreadSpawn()
{
-#ifndef OS_WIN32
+#ifdef CAPTURE_OFFLOAD_MANAGER
#ifdef AFLFUZZ_DISABLE_MGTTHREADS
return;
#endif
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;
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;
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;
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;
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;
}
return 1;
}
}
+#endif /* CAPTURE_OFFLOAD */
return 1;
}
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);
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;
counters->clo++;
break;
case FLOW_STATE_LOCAL_BYPASSED:
+#ifdef CAPTURE_OFFLOAD
case FLOW_STATE_CAPTURE_BYPASSED:
+#endif
counters->byp++;
break;
}
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));
{
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) {
}
}
}
-
+#endif
/* update flags and counters */
if (FlowGetPacketDirection(f, p) == TOSERVER) {
f->todstpktcnt++;
FLOW_STATE_ESTABLISHED,
FLOW_STATE_CLOSED,
FLOW_STATE_LOCAL_BYPASSED,
+#ifdef CAPTURE_OFFLOAD
FLOW_STATE_CAPTURE_BYPASSED,
+#endif
};
typedef struct FlowProtoTimeout_ {
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",