]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
flow-bypass: introduce update function
authorEric Leblond <eric@regit.org>
Tue, 9 Jan 2018 22:11:23 +0000 (23:11 +0100)
committerEric Leblond <eric@regit.org>
Tue, 6 Feb 2018 15:58:19 +0000 (16:58 +0100)
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.

src/flow-bypass.c
src/flow-bypass.h
src/flow.c

index 9367e8ed854d5bf941e042be683f49c104c1ce50..0b5b48640725df841af47b51ddce55784b563d74 100644 (file)
@@ -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";
index 3f438d4f58a16b38ccf13b13af9748b4aec0d3a6..b3089dc8552d8c138f5162404194df440d8c0b16 100644 (file)
@@ -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
 
index 683d456c2cc30066a09aa734962801f007539360..13e14331805e1c21bb3933c6e48ef2cee097ec24 100644 (file)
@@ -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);
+            }
         }
     }