]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
bypass: fix wait time at exit
authorEric Leblond <eric@regit.org>
Tue, 28 May 2019 10:26:23 +0000 (12:26 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 18 Jun 2019 05:07:02 +0000 (07:07 +0200)
The loop on bypassed flow maps can take a few seconds on heavily
loaded system causing Suricata to not honor a stop before a few
seconds.

This patch adds the code needed to detect the need to exit from
the check loop.

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

index 1564e139827fc67d323ec9a9a26c21d466c5a092..ae7b2f621f8a6e856840b986b1378263c2013da8 100644 (file)
@@ -70,7 +70,7 @@ static TmEcode BypassedFlowManager(ThreadVars *th_v, void *thread_data)
     }
     for (i = 0; i < g_bypassed_func_max_index; i++) {
         if (bypassedfunclist[i].FuncInit) {
-            bypassedfunclist[i].FuncInit(&curtime, bypassedfunclist[i].data);
+            bypassedfunclist[i].FuncInit(th_v, &curtime, bypassedfunclist[i].data);
         }
     }
 
@@ -82,7 +82,7 @@ static TmEcode BypassedFlowManager(ThreadVars *th_v, void *thread_data)
         }
         for (i = 0; i < g_bypassed_func_max_index; i++) {
             struct flows_stats bypassstats = { 0, 0, 0};
-            tcount = bypassedfunclist[i].Func(&bypassstats, &curtime, bypassedfunclist[i].data);
+            tcount = bypassedfunclist[i].Func(th_v, &bypassstats, &curtime, bypassedfunclist[i].data);
             if (tcount) {
                 StatsAddUI64(th_v, ftd->flow_bypassed_cnt_clo, (uint64_t)bypassstats.count);
                 StatsAddUI64(th_v, ftd->flow_bypassed_pkts, (uint64_t)bypassstats.packets);
index c41a95edb7754cf003ed16b7aac3f8e9095e19ac..50acc0ddceca47c9a76e952b26bab68938a11018 100644 (file)
@@ -30,9 +30,11 @@ struct flows_stats {
     uint64_t bytes;
 };
 
-typedef int (*BypassedCheckFunc)(struct flows_stats *bypassstats,
+typedef int (*BypassedCheckFunc)(ThreadVars *th_v,
+                                 struct flows_stats *bypassstats,
                                  struct timespec *curtime, void *data);
-typedef int (*BypassedCheckFuncInit)(struct timespec *curtime, void *data);
+typedef int (*BypassedCheckFuncInit)(ThreadVars *th_v,
+                                     struct timespec *curtime, void *data);
 typedef int (*BypassedUpdateFunc)(Flow *f, Packet *p, void *data);
 
 void FlowAddToBypassed(Flow *f);
index 10a07b7c740a5fe052bf3a30fff5d1ad5e890533..f4a3b320822ff62ccdb28c3ca2710c904c60c68f 100644 (file)
@@ -49,6 +49,7 @@
 #include "flow-storage.h"
 #include "flow.h"
 #include "flow-hash.h"
+#include "tm-threads.h"
 
 #include <bpf/libbpf.h>
 #include <bpf/bpf.h>
@@ -583,7 +584,7 @@ typedef int (*OpFlowForKey)(struct flows_stats *flowstats, FlowKey *flow_key,
  * This function iterates on all the flows of the IPv4 table
  * looking for timeouted flow to delete from the flow table.
  */
-static int EBPFForEachFlowV4Table(LiveDevice *dev, const char *name,
+static int EBPFForEachFlowV4Table(ThreadVars *th_v, LiveDevice *dev, const char *name,
                                   struct flows_stats *flowstats,
                                   struct timespec *ctime,
                                   struct ebpf_timeout_config *tcfg,
@@ -658,6 +659,11 @@ static int EBPFForEachFlowV4Table(LiveDevice *dev, const char *name,
         if (pkts_cnt > 0) {
             found = 1;
         }
+
+        if (TmThreadsCheckFlag(th_v, THV_KILL)) {
+            return 0;
+        }
+
         key = next_key;
     }
     if (pkts_cnt > 0) {
@@ -677,7 +683,8 @@ static int EBPFForEachFlowV4Table(LiveDevice *dev, const char *name,
  * This function iterates on all the flows of the IPv4 table
  * looking for timeouted flow to delete from the flow table.
  */
-static int EBPFForEachFlowV6Table(LiveDevice *dev, const char *name,
+static int EBPFForEachFlowV6Table(ThreadVars *th_v,
+                                  LiveDevice *dev, const char *name,
                                   struct flows_stats *flowstats,
                                   struct timespec *ctime,
                                   struct ebpf_timeout_config *tcfg,
@@ -750,6 +757,11 @@ static int EBPFForEachFlowV6Table(LiveDevice *dev, const char *name,
         if (pkts_cnt > 0) {
             found = 1;
         }
+
+        if (TmThreadsCheckFlag(th_v, THV_KILL)) {
+            return 0;
+        }
+
         key = next_key;
     }
     if (pkts_cnt > 0) {
@@ -763,16 +775,16 @@ static int EBPFForEachFlowV6Table(LiveDevice *dev, const char *name,
 }
 
 
-int EBPFCheckBypassedFlowCreate(struct timespec *curtime, void *data)
+int EBPFCheckBypassedFlowCreate(ThreadVars *th_v, struct timespec *curtime, void *data)
 {
     struct flows_stats local_bypassstats = { 0, 0, 0};
     LiveDevice *ldev = NULL, *ndev;
     struct ebpf_timeout_config *cfg = (struct ebpf_timeout_config *)data;
     while(LiveDeviceForEach(&ldev, &ndev)) {
-        EBPFForEachFlowV4Table(ldev, "flow_table_v4",
+        EBPFForEachFlowV4Table(th_v, ldev, "flow_table_v4",
                 &local_bypassstats, curtime,
                 cfg, EBPFCreateFlowForKey);
-        EBPFForEachFlowV6Table(ldev, "flow_table_v6",
+        EBPFForEachFlowV6Table(th_v, ldev, "flow_table_v6",
                 &local_bypassstats, curtime,
                 cfg, EBPFCreateFlowForKey);
     }
@@ -787,7 +799,7 @@ int EBPFCheckBypassedFlowCreate(struct timespec *curtime, void *data)
  * of entries in the kernel/userspace flow table if needed.
  *
  */
-int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats,
+int EBPFCheckBypassedFlowTimeout(ThreadVars *th_v, struct flows_stats *bypassstats,
                                         struct timespec *curtime,
                                         void *data)
 {
@@ -801,7 +813,7 @@ int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats,
 
     while(LiveDeviceForEach(&ldev, &ndev)) {
         memset(&local_bypassstats, 0, sizeof(local_bypassstats));
-        tcount = EBPFForEachFlowV4Table(ldev, "flow_table_v4",
+        tcount = EBPFForEachFlowV4Table(th_v, ldev, "flow_table_v4",
                                &local_bypassstats, curtime,
                                cfg, EBPFUpdateFlowForKey);
         bypassstats->count = local_bypassstats.count;
@@ -811,7 +823,7 @@ int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats,
             ret = 1;
         }
         memset(&local_bypassstats, 0, sizeof(local_bypassstats));
-        tcount = EBPFForEachFlowV6Table(ldev, "flow_table_v6",
+        tcount = EBPFForEachFlowV6Table(th_v, ldev, "flow_table_v6",
                                         &local_bypassstats, curtime,
                                         cfg, EBPFUpdateFlowForKey);
         bypassstats->count += local_bypassstats.count;
index 078870aa4b4126c01d851aa9cf3eb73412f3a892..757b864d42ff0f6704907b415cb540a3e25ca2ce 100644 (file)
@@ -71,10 +71,10 @@ int EBPFLoadFile(const char *iface, const char *path, const char * section,
                  int *val, struct ebpf_timeout_config *config);
 int EBPFSetupXDP(const char *iface, int fd, uint8_t flags);
 
-int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats,
+int EBPFCheckBypassedFlowTimeout(ThreadVars *th_v, struct flows_stats *bypassstats,
                                         struct timespec *curtime,
                                         void *data);
-int EBPFCheckBypassedFlowCreate(struct timespec *curtime, void *data);
+int EBPFCheckBypassedFlowCreate(ThreadVars *th_v, struct timespec *curtime, void *data);
 
 void EBPFRegisterExtension(void);