Go to the documentation of this file.
35 static DefragTracker *DefragTrackerGetUsedDefragTracker(
void);
121 #define DefragTrackerIncrUsecnt(dt) \
122 SC_ATOMIC_ADD((dt)->use_cnt, 1)
123 #define DefragTrackerDecrUsecnt(dt) \
124 SC_ATOMIC_SUB((dt)->use_cnt, 1)
160 #define DEFRAG_DEFAULT_HASHSIZE 4096
161 #define DEFRAG_DEFAULT_MEMCAP 16777216
162 #define DEFRAG_DEFAULT_PREALLOC 1000
186 const char *conf_val;
187 uint32_t configval = 0;
189 uint64_t defrag_memcap;
191 if ((
ConfGet(
"defrag.memcap", &conf_val)) == 1)
195 "from conf file - %s. Killing engine",
202 if ((
ConfGet(
"defrag.hash-size", &conf_val)) == 1)
213 if ((
ConfGet(
"defrag.trackers", &conf_val)) == 1)
222 SCLogDebug(
"DefragTracker config from suricata.yaml: memcap: %"PRIu64
", hash-size: "
230 "max defrag memcap is smaller than projected hash size. "
231 "Memcap: %" PRIu64
", Hash table size %" PRIu64
". Calculate "
232 "total hash size by multiplying \"defrag.hash-size\" with %" PRIuMAX
", "
233 "which is the hash bucket size.",
240 FatalError(
"Fatal error encountered in DefragTrackerInitConfig. Exiting...");
251 SCLogConfig(
"allocated %"PRIu64
" bytes of memory for the defrag hash... "
252 "%" PRIu32
" buckets of size %" PRIuMAX
"",
257 if ((
ConfGet(
"defrag.prealloc", &conf_val)) == 1)
263 SCLogError(
"preallocating defrag trackers failed: "
264 "max defrag memcap reached. Memcap %" PRIu64
", "
265 "Memuse %" PRIu64
".",
274 SCLogError(
"preallocating defrag failed: %s", strerror(errno));
280 SCLogConfig(
"preallocated %" PRIu32
" defrag trackers of size %" PRIuMAX
"",
287 SCLogConfig(
"defrag memory usage: %"PRIu64
" bytes, maximum: %"PRIu64,
296 static void DefragTrackerPrintStats (
void)
307 DefragTrackerPrintStats();
312 DefragTrackerFree(dt);
322 DefragTrackerFree(dt);
346 static inline int DefragHashRawAddressIPv6GtU32(
const uint32_t *a,
const uint32_t *b)
348 for (
int i = 0; i < 4; i++) {
391 static inline uint32_t DefragHashGetKey(
Packet *p)
395 if (p->
ip4h != NULL) {
397 if (p->
src.addr_data32[0] > p->
dst.addr_data32[0]) {
398 dhk.
src = p->
src.addr_data32[0];
399 dhk.
dst = p->
dst.addr_data32[0];
401 dhk.
src = p->
dst.addr_data32[0];
402 dhk.
dst = p->
src.addr_data32[0];
410 }
else if (p->
ip6h != NULL) {
412 if (DefragHashRawAddressIPv6GtU32(p->
src.addr_data32, p->
dst.addr_data32)) {
413 dhk.
src[0] = p->
src.addr_data32[0];
414 dhk.
src[1] = p->
src.addr_data32[1];
415 dhk.
src[2] = p->
src.addr_data32[2];
416 dhk.
src[3] = p->
src.addr_data32[3];
417 dhk.
dst[0] = p->
dst.addr_data32[0];
418 dhk.
dst[1] = p->
dst.addr_data32[1];
419 dhk.
dst[2] = p->
dst.addr_data32[2];
420 dhk.
dst[3] = p->
dst.addr_data32[3];
422 dhk.
src[0] = p->
dst.addr_data32[0];
423 dhk.
src[1] = p->
dst.addr_data32[1];
424 dhk.
src[2] = p->
dst.addr_data32[2];
425 dhk.
src[3] = p->
dst.addr_data32[3];
426 dhk.
dst[0] = p->
src.addr_data32[0];
427 dhk.
dst[1] = p->
src.addr_data32[1];
428 dhk.
dst[2] = p->
src.addr_data32[2];
429 dhk.
dst[3] = p->
src.addr_data32[3];
445 #define CMP_DEFRAGTRACKER(d1, d2, id) \
446 (((CMP_ADDR(&(d1)->src_addr, &(d2)->src) && CMP_ADDR(&(d1)->dst_addr, &(d2)->dst)) || \
447 (CMP_ADDR(&(d1)->src_addr, &(d2)->dst) && CMP_ADDR(&(d1)->dst_addr, &(d2)->src))) && \
448 (d1)->proto == IP_GET_IPPROTO(d2) && (d1)->id == (id) && \
449 (d1)->vlan_id[0] == (d2)->vlan_id[0] && (d1)->vlan_id[1] == (d2)->vlan_id[1] && \
450 (d1)->vlan_id[2] == (d2)->vlan_id[2])
475 if (g_eps_defrag_memcap != UINT64_MAX && g_eps_defrag_memcap == p->
pcap_cnt) {
499 dt = DefragTrackerGetUsedDefragTracker();
508 dt = DefragTrackerAlloc();
540 uint32_t key = DefragHashGetKey(p);
546 if (hb->
head == NULL) {
547 dt = DefragTrackerGetNew(p);
558 DefragTrackerInit(dt,p);
568 if (dt->
remove || DefragTrackerCompare(dt, p) == 0) {
576 dt = pdt->
hnext = DefragTrackerGetNew(p);
588 DefragTrackerInit(dt,p);
594 if (DefragTrackerCompare(dt, p) != 0) {
603 if (dt == hb->
tail) {
639 uint32_t key = DefragHashGetKey(p);
645 if (hb->
head == NULL) {
654 if (DefragTrackerCompare(dt, p) == 0) {
663 if (DefragTrackerCompare(dt, p) != 0) {
672 if (dt == hb->
tail) {
708 static DefragTracker *DefragTrackerGetUsedDefragTracker(
void)
742 if (dt->
hprev != NULL)
744 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)
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)
uint32_t DefragTrackerSpareQueueGetSize(void)
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]
uint32_t DefragTrackerQueueLen(DefragTrackerQueue *q)
#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]
#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
#define DRLOCK_DESTROY(fb)
DefragTracker * DefragGetTrackerFromHash(Packet *p)
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.
#define IP_GET_IPPROTO(p)
#define DEFRAG_DEFAULT_PREALLOC
#define DefragTrackerDecrUsecnt(dt)
uint16_t vlan_id[VLAN_MAX_LAYERS]
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.
#define SCMutexTrylock(mut)