Go to the documentation of this file.
35 static DefragTracker *DefragTrackerGetUsedDefragTracker(
void);
119 #define DefragTrackerIncrUsecnt(dt) \
120 SC_ATOMIC_ADD((dt)->use_cnt, 1)
121 #define DefragTrackerDecrUsecnt(dt) \
122 SC_ATOMIC_SUB((dt)->use_cnt, 1)
158 #define DEFRAG_DEFAULT_HASHSIZE 4096
159 #define DEFRAG_DEFAULT_MEMCAP 16777216
160 #define DEFRAG_DEFAULT_PREALLOC 1000
184 const char *conf_val;
185 uint32_t configval = 0;
187 uint64_t defrag_memcap;
189 if ((
ConfGet(
"defrag.memcap", &conf_val)) == 1)
193 "from conf file - %s. Killing engine",
200 if ((
ConfGet(
"defrag.hash-size", &conf_val)) == 1)
211 if ((
ConfGet(
"defrag.trackers", &conf_val)) == 1)
220 SCLogDebug(
"DefragTracker config from suricata.yaml: memcap: %"PRIu64
", hash-size: "
228 "max defrag memcap is smaller than projected hash size. "
229 "Memcap: %" PRIu64
", Hash table size %" PRIu64
". Calculate "
230 "total hash size by multiplying \"defrag.hash-size\" with %" PRIuMAX
", "
231 "which is the hash bucket size.",
238 FatalError(
"Fatal error encountered in DefragTrackerInitConfig. Exiting...");
249 SCLogConfig(
"allocated %"PRIu64
" bytes of memory for the defrag hash... "
250 "%" PRIu32
" buckets of size %" PRIuMAX
"",
255 if ((
ConfGet(
"defrag.prealloc", &conf_val)) == 1)
261 SCLogError(
"preallocating defrag trackers failed: "
262 "max defrag memcap reached. Memcap %" PRIu64
", "
263 "Memuse %" PRIu64
".",
272 SCLogError(
"preallocating defrag failed: %s", strerror(errno));
278 SCLogConfig(
"preallocated %" PRIu32
" defrag trackers of size %" PRIuMAX
"",
285 SCLogConfig(
"defrag memory usage: %"PRIu64
" bytes, maximum: %"PRIu64,
294 static void DefragTrackerPrintStats (
void)
305 DefragTrackerPrintStats();
310 DefragTrackerFree(dt);
320 DefragTrackerFree(dt);
344 static inline int DefragHashRawAddressIPv6GtU32(
const uint32_t *a,
const uint32_t *b)
346 for (
int i = 0; i < 4; i++) {
389 static inline uint32_t DefragHashGetKey(
Packet *p)
393 if (p->
ip4h != NULL) {
395 if (p->
src.addr_data32[0] > p->
dst.addr_data32[0]) {
396 dhk.
src = p->
src.addr_data32[0];
397 dhk.
dst = p->
dst.addr_data32[0];
399 dhk.
src = p->
dst.addr_data32[0];
400 dhk.
dst = p->
src.addr_data32[0];
408 }
else if (p->
ip6h != NULL) {
410 if (DefragHashRawAddressIPv6GtU32(p->
src.addr_data32, p->
dst.addr_data32)) {
411 dhk.
src[0] = p->
src.addr_data32[0];
412 dhk.
src[1] = p->
src.addr_data32[1];
413 dhk.
src[2] = p->
src.addr_data32[2];
414 dhk.
src[3] = p->
src.addr_data32[3];
415 dhk.
dst[0] = p->
dst.addr_data32[0];
416 dhk.
dst[1] = p->
dst.addr_data32[1];
417 dhk.
dst[2] = p->
dst.addr_data32[2];
418 dhk.
dst[3] = p->
dst.addr_data32[3];
420 dhk.
src[0] = p->
dst.addr_data32[0];
421 dhk.
src[1] = p->
dst.addr_data32[1];
422 dhk.
src[2] = p->
dst.addr_data32[2];
423 dhk.
src[3] = p->
dst.addr_data32[3];
424 dhk.
dst[0] = p->
src.addr_data32[0];
425 dhk.
dst[1] = p->
src.addr_data32[1];
426 dhk.
dst[2] = p->
src.addr_data32[2];
427 dhk.
dst[3] = p->
src.addr_data32[3];
443 #define CMP_DEFRAGTRACKER(d1, d2, id) \
444 (((CMP_ADDR(&(d1)->src_addr, &(d2)->src) && CMP_ADDR(&(d1)->dst_addr, &(d2)->dst)) || \
445 (CMP_ADDR(&(d1)->src_addr, &(d2)->dst) && CMP_ADDR(&(d1)->dst_addr, &(d2)->src))) && \
446 (d1)->proto == IP_GET_IPPROTO(d2) && (d1)->id == (id) && \
447 (d1)->vlan_id[0] == (d2)->vlan_id[0] && (d1)->vlan_id[1] == (d2)->vlan_id[1] && \
448 (d1)->vlan_id[2] == (d2)->vlan_id[2])
462 static void DefragExceptionPolicyStatsIncr(
482 if (g_eps_defrag_memcap != UINT64_MAX && g_eps_defrag_memcap == p->
pcap_cnt) {
507 dt = DefragTrackerGetUsedDefragTracker();
517 dt = DefragTrackerAlloc();
550 uint32_t key = DefragHashGetKey(p);
556 if (hb->
head == NULL) {
557 dt = DefragTrackerGetNew(
tv,
dtv, p);
568 DefragTrackerInit(dt,p);
578 if (dt->
remove || DefragTrackerCompare(dt, p) == 0) {
586 dt = pdt->
hnext = DefragTrackerGetNew(
tv,
dtv, p);
598 DefragTrackerInit(dt,p);
604 if (DefragTrackerCompare(dt, p) != 0) {
613 if (dt == hb->
tail) {
649 uint32_t key = DefragHashGetKey(p);
655 if (hb->
head == NULL) {
664 if (DefragTrackerCompare(dt, p) == 0) {
673 if (DefragTrackerCompare(dt, p) != 0) {
682 if (dt == hb->
tail) {
718 static DefragTracker *DefragTrackerGetUsedDefragTracker(
void)
752 if (dt->
hprev != NULL)
754 if (dt->
hnext != NULL)
@ PKT_DROP_REASON_DEFRAG_MEMCAP
void DefragTrackerFreeFrags(DefragTracker *tracker)
Free all frags associated with a tracker.
DefragTracker * DefragLookupTrackerFromHash(Packet *p)
look up a tracker in the hash
void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDropReason drop_reason)
struct DefragHashKey4_ DefragHashKey4
#define IPV6_EXTHDR_GET_FH_ID(p)
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval)
struct DefragTracker_ * hnext
DefragTrackerHashRow * defragtracker_hash
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define DefragTrackerIncrUsecnt(dt)
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
int ParseSizeStringU64(const char *size, uint64_t *res)
uint16_t vlan_id[VLAN_MAX_LAYERS]
void DefragTrackerQueueDestroy(DefragTrackerQueue *q)
Destroy a tracker queue.
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
struct DefragTrackerHashRow_ DefragTrackerHashRow
void DefragTrackerClearMemory(DefragTracker *dt)
uint64_t DefragTrackerGetMemuse(void)
Return memuse value.
int DefragPolicyGetHostTimeout(Packet *p)
enum ExceptionPolicy ExceptionPolicyParse(const char *option, bool support_flow)
void DefragTrackerMoveToSpare(DefragTracker *h)
int ConfValIsTrue(const char *val)
Check if a value is true.
struct DefragTracker_ * hprev
uint8_t DefragGetOsPolicy(Packet *p)
Get the defrag policy based on the destination address of the packet.
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
DefragConfig defrag_config
uint16_t vlan_id[VLAN_MAX_LAYERS]
#define SCMutexUnlock(mut)
#define DEFRAG_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
uint16_t vlan_id[VLAN_MAX_LAYERS]
uint16_t eps_id[EXCEPTION_POLICY_MAX]
Per thread variable structure.
#define DEFRAG_DEFAULT_HASHSIZE
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
uint64_t DefragTrackerGetMemcap(void)
Return memcap value.
DefragTracker * DefragTrackerDequeue(DefragTrackerQueue *q)
remove a tracker from the queue
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
struct DefragHashKey6_ DefragHashKey6
#define DRLOCK_UNLOCK(fb)
void DefragInitConfig(bool quiet)
initialize the configuration
#define DEFRAG_DEFAULT_MEMCAP
void DefragTrackerRelease(DefragTracker *t)
#define SCMutexInit(mut, mutattrs)
#define WarnInvalidConfEntry(param_name, format, value)
Generic API that can be used by all to log an invalid conf entry.
enum ExceptionPolicy memcap_policy
ExceptionPolicyCounters counter_defrag_memcap_eps
#define DRLOCK_DESTROY(fb)
DefragTrackerQueue * DefragTrackerQueueInit(DefragTrackerQueue *q)
#define CMP_DEFRAGTRACKER(d1, d2, id)
#define DRLOCK_TRYLOCK(fb)
int DefragTrackerSetMemcap(uint64_t size)
Update memcap value.
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
void DefragTrackerEnqueue(DefragTrackerQueue *q, DefragTracker *dt)
add a tracker to a queue
#define SCLogError(...)
Macro used to log ERROR messages.
Structure to hold thread specific data for all decode modules.
#define IP_GET_IPPROTO(p)
#define DEFRAG_DEFAULT_PREALLOC
#define DefragTrackerDecrUsecnt(dt)
uint16_t vlan_id[VLAN_MAX_LAYERS]
DefragTracker * DefragGetTrackerFromHash(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
void DefragHashShutdown(void)
shutdown the flow engine
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define COPY_ADDRESS(a, b)
SC_ATOMIC_DECLARE(uint64_t, defrag_memuse)
#define SCLogNotice(...)
Macro used to log NOTICE messages.
enum ExceptionPolicy DefragGetMemcapExceptionPolicy(void)
#define SCMutexTrylock(mut)