From: Eric Leblond Date: Tue, 9 Jan 2018 22:11:23 +0000 (+0100) Subject: flow-bypass: introduce update function X-Git-Tag: suricata-4.1.0-beta1~187 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bec54158fc09a772457c52448cfc4fc6cc743f6;p=thirdparty%2Fsuricata.git flow-bypass: introduce update function Main objective of the function is to be able to bypass a flow on other interfaces. This is necessary in AF_PACKET case as the flow table are per interface. --- diff --git a/src/flow-bypass.c b/src/flow-bypass.c index 9367e8ed85..0b5b486407 100644 --- a/src/flow-bypass.c +++ b/src/flow-bypass.c @@ -40,6 +40,9 @@ typedef struct BypassedFlowManagerThreadData_ { int g_bypassed_func_max_index = 0; BypassedCheckFunc BypassedFuncList[BYPASSFUNCMAX]; +int g_bypassed_update_max_index = 0; +BypassedUpdateFunc UpdateFuncList[BYPASSFUNCMAX]; + static TmEcode BypassedFlowManager(ThreadVars *th_v, void *thread_data) { #ifdef HAVE_PACKET_EBPF @@ -82,6 +85,16 @@ static TmEcode BypassedFlowManager(ThreadVars *th_v, void *thread_data) return TM_ECODE_OK; } +void BypassedFlowUpdate(Flow *f, Packet *p) +{ + int i; + + for (i = 0; i < g_bypassed_update_max_index; i++) { + if (UpdateFuncList[i](f, p)) { + return; + } + } +} static TmEcode BypassedFlowManagerThreadInit(ThreadVars *t, const void *initdata, void **data) { @@ -141,6 +154,20 @@ int BypassedFlowManagerRegisterCheckFunc(BypassedCheckFunc CheckFunc) return 0; } +int BypassedFlowManagerRegisterUpdateFunc(BypassedUpdateFunc UpdateFunc) +{ + if (!UpdateFunc) { + return -1; + } + if (g_bypassed_update_max_index < BYPASSFUNCMAX) { + UpdateFuncList[g_bypassed_update_max_index] = UpdateFunc; + g_bypassed_update_max_index++; + } else { + return -1; + } + return 0; +} + void TmModuleBypassedFlowManagerRegister (void) { tmm_modules[TMM_BYPASSEDFLOWMANAGER].name = "BypassedFlowManager"; diff --git a/src/flow-bypass.h b/src/flow-bypass.h index 3f438d4f58..b3089dc855 100644 --- a/src/flow-bypass.h +++ b/src/flow-bypass.h @@ -32,6 +32,7 @@ struct flows_stats { typedef int (*BypassedCheckFunc)(struct flows_stats *bypassstats, struct timespec *curtime); +typedef int (*BypassedUpdateFunc)(Flow *f, Packet *p); void FlowAddToBypassed(Flow *f); @@ -39,6 +40,9 @@ void BypassedFlowManagerThreadSpawn(void); void TmModuleBypassedFlowManagerRegister(void); int BypassedFlowManagerRegisterCheckFunc(BypassedCheckFunc CheckFunc); +int BypassedFlowManagerRegisterUpdateFunc(BypassedUpdateFunc UpdateFunc); + +void BypassedFlowUpdate(Flow *f, Packet *p); #endif diff --git a/src/flow.c b/src/flow.c index 683d456c2c..13e1433180 100644 --- a/src/flow.c +++ b/src/flow.c @@ -43,6 +43,7 @@ #include "flow-timeout.h" #include "flow-manager.h" #include "flow-storage.h" +#include "flow-bypass.h" #include "stream-tcp-private.h" #include "stream-tcp-reassemble.h" @@ -341,6 +342,12 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p) SCLogDebug("Downgrading flow to local bypass"); COPY_TIMESTAMP(&p->ts, &f->lastts); FlowUpdateState(f, FLOW_STATE_LOCAL_BYPASSED); + } else { + /* In IPS mode the packet could come from the over interface so it would + * need to be bypassed */ + if (EngineModeIsIPS()) { + BypassedFlowUpdate(f, p); + } } }