flow: get/set memcap value

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.
pull/3104/head
Giuseppe Longo 8 years ago committed by Victor Julien
parent 80bf728bfe
commit 6fdad7d9e5

@ -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 */

@ -127,7 +127,7 @@
* \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);

@ -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 */

@ -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.

Loading…
Cancel
Save