Go to the documentation of this file.
120 #define DefragTrackerIncrUsecnt(dt) \
121 SC_ATOMIC_ADD((dt)->use_cnt, 1)
122 #define DefragTrackerDecrUsecnt(dt) \
123 SC_ATOMIC_SUB((dt)->use_cnt, 1)
131 if (PacketIsIPv4(
p)) {
132 const IPV4Hdr *ip4h = PacketGetIPv4(
p);
140 dt->
proto = PacketGetIPProto(
p);
161 #define DEFRAG_DEFAULT_HASHSIZE 4096
162 #define DEFRAG_DEFAULT_MEMCAP 16777216
163 #define DEFRAG_DEFAULT_PREALLOC 1000
186 const char *conf_val;
187 uint32_t configval = 0;
189 uint64_t defrag_memcap;
191 if ((
SCConfGet(
"defrag.memcap", &conf_val)) == 1) {
194 "from conf file - %s. Killing engine",
201 if ((
SCConfGet(
"defrag.hash-size", &conf_val)) == 1) {
210 if ((
SCConfGet(
"defrag.trackers", &conf_val)) == 1) {
218 SCLogDebug(
"DefragTracker config from suricata.yaml: memcap: %"PRIu64
", hash-size: "
226 "max defrag memcap is smaller than projected hash size. "
227 "Memcap: %" PRIu64
", Hash table size %" PRIu64
". Calculate "
228 "total hash size by multiplying \"defrag.hash-size\" with %" PRIuMAX
", "
229 "which is the hash bucket size.",
236 FatalError(
"Fatal error encountered in DefragTrackerInitConfig. Exiting...");
247 SCLogConfig(
"allocated %"PRIu64
" bytes of memory for the defrag hash... "
248 "%" PRIu32
" buckets of size %" PRIuMAX
"",
253 if ((
SCConfGet(
"defrag.prealloc", &conf_val)) == 1) {
258 SCLogError(
"preallocating defrag trackers failed: "
259 "max defrag memcap reached. Memcap %" PRIu64
", "
260 "Memuse %" PRIu64
".",
269 SCLogError(
"preallocating defrag failed: %s", strerror(errno));
275 SCLogConfig(
"preallocated %" PRIu32
" defrag trackers of size %" PRIuMAX
"",
283 SCLogConfig(
"defrag memory usage: %"PRIu64
" bytes, maximum: %"PRIu64,
297 DefragTrackerFree(dt);
307 DefragTrackerFree(dt);
330 static inline int DefragHashRawAddressIPv6GtU32(
const uint32_t *a,
const uint32_t *b)
332 for (
int i = 0; i < 4; i++) {
375 static inline uint32_t DefragHashGetKey(
Packet *
p)
379 if (PacketIsIPv4(
p)) {
380 const IPV4Hdr *ip4h = PacketGetIPv4(
p);
382 if (
p->
src.addr_data32[0] >
p->
dst.addr_data32[0]) {
383 dhk.
src =
p->
src.addr_data32[0];
384 dhk.
dst =
p->
dst.addr_data32[0];
386 dhk.
src =
p->
dst.addr_data32[0];
387 dhk.
dst =
p->
src.addr_data32[0];
395 }
else if (PacketIsIPv6(
p)) {
397 if (DefragHashRawAddressIPv6GtU32(
p->
src.addr_data32,
p->
dst.addr_data32)) {
398 dhk.
src[0] =
p->
src.addr_data32[0];
399 dhk.
src[1] =
p->
src.addr_data32[1];
400 dhk.
src[2] =
p->
src.addr_data32[2];
401 dhk.
src[3] =
p->
src.addr_data32[3];
402 dhk.
dst[0] =
p->
dst.addr_data32[0];
403 dhk.
dst[1] =
p->
dst.addr_data32[1];
404 dhk.
dst[2] =
p->
dst.addr_data32[2];
405 dhk.
dst[3] =
p->
dst.addr_data32[3];
407 dhk.
src[0] =
p->
dst.addr_data32[0];
408 dhk.
src[1] =
p->
dst.addr_data32[1];
409 dhk.
src[2] =
p->
dst.addr_data32[2];
410 dhk.
src[3] =
p->
dst.addr_data32[3];
411 dhk.
dst[0] =
p->
src.addr_data32[0];
412 dhk.
dst[1] =
p->
src.addr_data32[1];
413 dhk.
dst[2] =
p->
src.addr_data32[2];
414 dhk.
dst[3] =
p->
src.addr_data32[3];
430 #define CMP_DEFRAGTRACKER(d1, d2, id) \
431 (((CMP_ADDR(&(d1)->src_addr, &(d2)->src) && CMP_ADDR(&(d1)->dst_addr, &(d2)->dst)) || \
432 (CMP_ADDR(&(d1)->src_addr, &(d2)->dst) && CMP_ADDR(&(d1)->dst_addr, &(d2)->src))) && \
433 (d1)->proto == PacketGetIPProto(d2) && (d1)->id == (id) && \
434 (d1)->vlan_id[0] == (d2)->vlan_id[0] && (d1)->vlan_id[1] == (d2)->vlan_id[1] && \
435 (d1)->vlan_id[2] == (d2)->vlan_id[2])
440 if (PacketIsIPv4(
p)) {
441 if (t->
af != AF_INET)
443 const IPV4Hdr *ip4h = PacketGetIPv4(
p);
446 if (t->
af != AF_INET6)
454 static void DefragExceptionPolicyStatsIncr(
474 if (g_eps_defrag_memcap != UINT64_MAX && g_eps_defrag_memcap ==
PcapPacketCntGet(
p)) {
489 dt = DefragTrackerGetUsedDefragTracker(
tv,
dtv);
499 dt = DefragTrackerAlloc();
532 uint32_t key = DefragHashGetKey(
p);
538 if (hb->
head == NULL) {
539 dt = DefragTrackerGetNew(
tv,
dtv,
p);
549 DefragTrackerInit(dt,
p);
567 prev_dt->
hnext = next_dt;
576 goto tracker_removed;
577 }
else if (!dt->
remove && DefragTrackerCompare(dt,
p)) {
590 if (next_dt == NULL) {
591 dt = DefragTrackerGetNew(
tv,
dtv,
p);
602 DefragTrackerInit(dt,
p);
609 }
while (dt != NULL);
627 uint32_t key = DefragHashGetKey(
p);
633 if (hb->
head == NULL) {
642 if (!dt->
remove && DefragTrackerCompare(dt,
p)) {
649 }
else if (dt->
hnext == NULL) {
655 }
while (dt != NULL);
707 bool incr_reuse_cnt = !dt->
remove;
719 if (incr_reuse_cnt) {
@ PKT_DROP_REASON_DEFRAG_MEMCAP
#define IPV4_GET_RAW_IPID(ip4h)
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
int SCConfValIsTrue(const char *val)
Check if a value is true.
#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.
uint64_t PcapPacketCntGet(const Packet *p)
int ParseSizeStringU64(const char *size, uint64_t *res)
uint32_t DefragTrackerStackSize(DefragTrackerStack *q)
return stack size
uint16_t vlan_id[VLAN_MAX_LAYERS]
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
struct DefragTrackerHashRow_ DefragTrackerHashRow
DefragTracker * DefragTrackerDequeue(DefragTrackerStack *q)
remove a tracker from the queue
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)
StatsCounterId counter_defrag_tracker_hard_reuse
uint8_t DefragGetOsPolicy(Packet *p)
Get the defrag policy based on the destination address of the packet.
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]
Per thread variable structure.
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
int DefragTrackerTimedOut(DefragTracker *dt, SCTime_t ts)
#define DEFRAG_DEFAULT_HASHSIZE
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
uint64_t DefragTrackerGetMemcap(void)
Return memcap value.
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
struct DefragHashKey6_ DefragHashKey6
StatsCounterId counter_defrag_tracker_timeout
#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)
void DefragTrackerStackDestroy(DefragTrackerStack *q)
Destroy a tracker queue.
#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.
#define SCLogError(...)
Macro used to log ERROR messages.
Structure to hold thread specific data for all decode modules.
#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
StatsCounterId counter_defrag_tracker_soft_reuse
#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.
DefragTrackerStack * DefragTrackerStackInit(DefragTrackerStack *q)
void DefragTrackerEnqueue(DefragTrackerStack *q, DefragTracker *dt)
add a tracker to a queue
enum ExceptionPolicy DefragGetMemcapExceptionPolicy(void)
StatsCounterId eps_id[EXCEPTION_POLICY_MAX]
#define DEBUG_VALIDATE_BUG_ON(exp)
#define SCMutexTrylock(mut)