]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
flow: get/set memcap value
authorGiuseppe Longo <glongo@stamus-networks.com>
Mon, 20 Nov 2017 14:02:32 +0000 (15:02 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 19 Dec 2017 10:18:57 +0000 (11:18 +0100)
This adds new functions that will be called
through unix-socket and permit to update
and show memcap value.

The memcap value needs to be handled in a
thread safe way, so for this reason it is
declared as atomic var.

FlowGetMemuse() function is made as public
because the memuse value will be shown
through unix-socket.

src/flow-manager.c
src/flow-util.h
src/flow.c
src/flow.h

index b0c9f95faf2ff01e840b6a805343b1405fee4a7f..77bfd9f6b6412b9ca7636b0d1727933697b43fa5 100644 (file)
@@ -803,12 +803,6 @@ static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
     return TM_ECODE_OK;
 }
 
-static uint64_t FlowGetMemuse(void)
-{
-    uint64_t flow_memuse = SC_ATOMIC_GET(flow_memuse);
-    return flow_memuse;
-}
-
 /** \brief spawn the flow manager thread */
 void FlowManagerThreadSpawn()
 {
@@ -1366,7 +1360,7 @@ static int FlowMgrTest05 (void)
 
     uint32_t ini = 0;
     uint32_t end = flow_spare_q.len;
-    flow_config.memcap = 10000;
+    SC_ATOMIC_SET(flow_config.memcap, 10000);
     flow_config.prealloc = 100;
 
     /* Let's get the flow_spare_q empty */
index eac473e0a19dae897c942f185c02dbc726bd52b7..11109c3c5ac47a401316d5dbfa40c089af2dc697 100644 (file)
  *  \retval 0 no fit
  */
 #define FLOW_CHECK_MEMCAP(size) \
-    ((((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)(size)) <= flow_config.memcap))
+    ((((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)(size)) <= SC_ATOMIC_GET(flow_config.memcap)))
 
 Flow *FlowAlloc(void);
 Flow *FlowAllocDirect(void);
index ac8541f11fb632d05adb300ce4fe84757afbe56e..683d456c2cc30066a09aa734962801f007539360 100644 (file)
@@ -89,6 +89,38 @@ int FlowSetProtoFreeFunc(uint8_t, void (*Free)(void *));
 /* Run mode selected at suricata.c */
 extern int run_mode;
 
+/**
+ *  \brief Update memcap value
+ *
+ *  \param size new memcap value
+ */
+int FlowSetMemcap(uint64_t size)
+{
+    if ((uint64_t)SC_ATOMIC_GET(flow_memuse) < size) {
+        SC_ATOMIC_SET(flow_config.memcap, size);
+        return 1;
+    }
+
+    return 0;
+}
+
+/**
+ *  \brief Return memcap value
+ *
+ *  \retval memcap value
+ */
+uint64_t FlowGetMemcap(void)
+{
+    uint64_t memcapcopy = SC_ATOMIC_GET(flow_config.memcap);
+    return memcapcopy;
+}
+
+uint64_t FlowGetMemuse(void)
+{
+    uint64_t memusecopy = SC_ATOMIC_GET(flow_memuse);
+    return memusecopy;
+}
+
 void FlowCleanupAppLayer(Flow *f)
 {
     if (f == NULL || f->proto == 0)
@@ -405,14 +437,15 @@ void FlowInitConfig(char quiet)
     SC_ATOMIC_INIT(flow_flags);
     SC_ATOMIC_INIT(flow_memuse);
     SC_ATOMIC_INIT(flow_prune_idx);
+    SC_ATOMIC_INIT(flow_config.memcap);
     FlowQueueInit(&flow_spare_q);
     FlowQueueInit(&flow_recycle_q);
 
     /* set defaults */
     flow_config.hash_rand   = (uint32_t)RandomGet();
     flow_config.hash_size   = FLOW_DEFAULT_HASHSIZE;
-    flow_config.memcap      = FLOW_DEFAULT_MEMCAP;
     flow_config.prealloc    = FLOW_DEFAULT_PREALLOC;
+    SC_ATOMIC_SET(flow_config.memcap, FLOW_DEFAULT_MEMCAP);
 
     /* If we have specific config, overwrite the defaults with them,
      * otherwise, leave the default values */
@@ -434,6 +467,7 @@ void FlowInitConfig(char quiet)
     uint32_t configval = 0;
 
     /** set config values for memcap, prealloc and hash_size */
+    uint64_t flow_memcap_copy;
     if ((ConfGet("flow.memcap", &conf_val)) == 1)
     {
         if (conf_val == NULL) {
@@ -441,11 +475,13 @@ void FlowInitConfig(char quiet)
            exit(EXIT_FAILURE);
         }
 
-        if (ParseSizeStringU64(conf_val, &flow_config.memcap) < 0) {
+        if (ParseSizeStringU64(conf_val, &flow_memcap_copy) < 0) {
             SCLogError(SC_ERR_SIZE_PARSE, "Error parsing flow.memcap "
                        "from conf file - %s.  Killing engine",
                        conf_val);
             exit(EXIT_FAILURE);
+        } else {
+            SC_ATOMIC_SET(flow_config.memcap, flow_memcap_copy);
         }
     }
     if ((ConfGet("flow.hash-size", &conf_val)) == 1)
@@ -473,7 +509,7 @@ void FlowInitConfig(char quiet)
         }
     }
     SCLogDebug("Flow config from suricata.yaml: memcap: %"PRIu64", hash-size: "
-               "%"PRIu32", prealloc: %"PRIu32, flow_config.memcap,
+               "%"PRIu32", prealloc: %"PRIu32, SC_ATOMIC_GET(flow_config.memcap),
                flow_config.hash_size, flow_config.prealloc);
 
     /* alloc hash memory */
@@ -483,7 +519,7 @@ void FlowInitConfig(char quiet)
                 "max flow memcap is smaller than projected hash size. "
                 "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate "
                 "total hash size by multiplying \"flow.hash-size\" with %"PRIuMAX", "
-                "which is the hash bucket size.", flow_config.memcap, hash_size,
+                "which is the hash bucket size.", SC_ATOMIC_GET(flow_config.memcap), hash_size,
                 (uintmax_t)sizeof(FlowBucket));
         exit(EXIT_FAILURE);
     }
@@ -513,7 +549,7 @@ void FlowInitConfig(char quiet)
         if (!(FLOW_CHECK_MEMCAP(sizeof(Flow) + FlowStorageSize()))) {
             SCLogError(SC_ERR_FLOW_INIT, "preallocating flows failed: "
                     "max flow memcap reached. Memcap %"PRIu64", "
-                    "Memuse %"PRIu64".", flow_config.memcap,
+                    "Memuse %"PRIu64".", SC_ATOMIC_GET(flow_config.memcap),
                     ((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)sizeof(Flow)));
             exit(EXIT_FAILURE);
         }
@@ -531,7 +567,7 @@ void FlowInitConfig(char quiet)
         SCLogConfig("preallocated %" PRIu32 " flows of size %" PRIuMAX "",
                 flow_spare_q.len, (uintmax_t)(sizeof(Flow) + + FlowStorageSize()));
         SCLogConfig("flow memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
-                SC_ATOMIC_GET(flow_memuse), flow_config.memcap);
+                SC_ATOMIC_GET(flow_memuse), SC_ATOMIC_GET(flow_config.memcap));
     }
 
     FlowInitFlowProto();
@@ -589,6 +625,7 @@ void FlowShutdown(void)
     FlowQueueDestroy(&flow_spare_q);
     FlowQueueDestroy(&flow_recycle_q);
 
+    SC_ATOMIC_DESTROY(flow_config.memcap);
     SC_ATOMIC_DESTROY(flow_prune_idx);
     SC_ATOMIC_DESTROY(flow_memuse);
     SC_ATOMIC_DESTROY(flow_flags);
@@ -1079,7 +1116,7 @@ static int FlowTest07 (void)
 
     uint32_t ini = 0;
     uint32_t end = flow_spare_q.len;
-    flow_config.memcap = 10000;
+    SC_ATOMIC_SET(flow_config.memcap, 10000);
     flow_config.prealloc = 100;
 
     /* Let's get the flow_spare_q empty */
@@ -1126,7 +1163,7 @@ static int FlowTest08 (void)
 
     uint32_t ini = 0;
     uint32_t end = flow_spare_q.len;
-    flow_config.memcap = 10000;
+    SC_ATOMIC_SET(flow_config.memcap, 10000);
     flow_config.prealloc = 100;
 
     /* Let's get the flow_spare_q empty */
@@ -1173,7 +1210,7 @@ static int FlowTest09 (void)
 
     uint32_t ini = 0;
     uint32_t end = flow_spare_q.len;
-    flow_config.memcap = 10000;
+    SC_ATOMIC_SET(flow_config.memcap, 10000);
     flow_config.prealloc = 100;
 
     /* Let's get the flow_spare_q empty */
index f2aa47df014894518f40d1393b75d0a59b3ca784..a13aa5eb9fd0467c3ef4dd2da3736365db932ffd 100644 (file)
@@ -245,7 +245,6 @@ typedef struct FlowCnf_
 {
     uint32_t hash_rand;
     uint32_t hash_size;
-    uint64_t memcap;
     uint32_t max_flows;
     uint32_t prealloc;
 
@@ -256,6 +255,7 @@ typedef struct FlowCnf_
     uint32_t emerg_timeout_est;
     uint32_t emergency_recovery;
 
+    SC_ATOMIC_DECLARE(uint64_t, memcap);
 } FlowConfig;
 
 /* Hash key for the flow hash */
@@ -497,6 +497,10 @@ void FlowCleanupAppLayer(Flow *);
 
 void FlowUpdateState(Flow *f, enum FlowState s);
 
+int FlowSetMemcap(uint64_t size);
+uint64_t FlowGetMemcap(void);
+uint64_t FlowGetMemuse(void);
+
 /** ----- Inline functions ----- */
 
 /** \brief Set the No Packet Inspection Flag without locking the flow.