Go to the documentation of this file.
122 #define DefragTrackerIncrUsecnt(dt) \
123 SC_ATOMIC_ADD((dt)->use_cnt, 1)
124 #define DefragTrackerDecrUsecnt(dt) \
125 SC_ATOMIC_SUB((dt)->use_cnt, 1)
133 if (PacketIsIPv4(p)) {
134 const IPV4Hdr *ip4h = PacketGetIPv4(p);
142 dt->
proto = PacketGetIPProto(p);
163 #define DEFRAG_DEFAULT_HASHSIZE 4096
164 #define DEFRAG_DEFAULT_MEMCAP 16777216
165 #define DEFRAG_DEFAULT_PREALLOC 1000
188 const char *conf_val;
189 uint32_t configval = 0;
191 uint64_t defrag_memcap;
193 if ((
SCConfGet(
"defrag.memcap", &conf_val)) == 1) {
196 "from conf file - %s. Killing engine",
203 if ((
SCConfGet(
"defrag.hash-size", &conf_val)) == 1) {
212 if ((
SCConfGet(
"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 ((
SCConfGet(
"defrag.prealloc", &conf_val)) == 1) {
260 SCLogError(
"preallocating defrag trackers failed: "
261 "max defrag memcap reached. Memcap %" PRIu64
", "
262 "Memuse %" PRIu64
".",
271 SCLogError(
"preallocating defrag failed: %s", strerror(errno));
277 SCLogConfig(
"preallocated %" PRIu32
" defrag trackers of size %" PRIuMAX
"",
284 SCLogConfig(
"defrag memory usage: %"PRIu64
" bytes, maximum: %"PRIu64,
298 DefragTrackerFree(dt);
308 DefragTrackerFree(dt);
331 static inline int DefragHashRawAddressIPv6GtU32(
const uint32_t *a,
const uint32_t *b)
333 for (
int i = 0; i < 4; i++) {
376 static inline uint32_t DefragHashGetKey(
Packet *p)
380 if (PacketIsIPv4(p)) {
381 const IPV4Hdr *ip4h = PacketGetIPv4(p);
383 if (p->
src.addr_data32[0] > p->
dst.addr_data32[0]) {
384 dhk.
src = p->
src.addr_data32[0];
385 dhk.
dst = p->
dst.addr_data32[0];
387 dhk.
src = p->
dst.addr_data32[0];
388 dhk.
dst = p->
src.addr_data32[0];
396 }
else if (PacketIsIPv6(p)) {
398 if (DefragHashRawAddressIPv6GtU32(p->
src.addr_data32, p->
dst.addr_data32)) {
399 dhk.
src[0] = p->
src.addr_data32[0];
400 dhk.
src[1] = p->
src.addr_data32[1];
401 dhk.
src[2] = p->
src.addr_data32[2];
402 dhk.
src[3] = p->
src.addr_data32[3];
403 dhk.
dst[0] = p->
dst.addr_data32[0];
404 dhk.
dst[1] = p->
dst.addr_data32[1];
405 dhk.
dst[2] = p->
dst.addr_data32[2];
406 dhk.
dst[3] = p->
dst.addr_data32[3];
408 dhk.
src[0] = p->
dst.addr_data32[0];
409 dhk.
src[1] = p->
dst.addr_data32[1];
410 dhk.
src[2] = p->
dst.addr_data32[2];
411 dhk.
src[3] = p->
dst.addr_data32[3];
412 dhk.
dst[0] = p->
src.addr_data32[0];
413 dhk.
dst[1] = p->
src.addr_data32[1];
414 dhk.
dst[2] = p->
src.addr_data32[2];
415 dhk.
dst[3] = p->
src.addr_data32[3];
431 #define CMP_DEFRAGTRACKER(d1, d2, id) \
432 (((CMP_ADDR(&(d1)->src_addr, &(d2)->src) && CMP_ADDR(&(d1)->dst_addr, &(d2)->dst)) || \
433 (CMP_ADDR(&(d1)->src_addr, &(d2)->dst) && CMP_ADDR(&(d1)->dst_addr, &(d2)->src))) && \
434 (d1)->proto == PacketGetIPProto(d2) && (d1)->id == (id) && \
435 (d1)->vlan_id[0] == (d2)->vlan_id[0] && (d1)->vlan_id[1] == (d2)->vlan_id[1] && \
436 (d1)->vlan_id[2] == (d2)->vlan_id[2])
441 if (PacketIsIPv4(p)) {
442 const IPV4Hdr *ip4h = PacketGetIPv4(p);
451 static void DefragExceptionPolicyStatsIncr(
471 if (g_eps_defrag_memcap != UINT64_MAX && g_eps_defrag_memcap == p->
pcap_cnt) {
486 dt = DefragTrackerGetUsedDefragTracker(
tv,
dtv);
496 dt = DefragTrackerAlloc();
529 uint32_t key = DefragHashGetKey(p);
535 if (hb->
head == NULL) {
536 dt = DefragTrackerGetNew(
tv,
dtv, p);
546 DefragTrackerInit(dt,p);
564 prev_dt->
hnext = next_dt;
573 goto tracker_removed;
574 }
else if (!dt->
remove && DefragTrackerCompare(dt, p)) {
587 if (next_dt == NULL) {
588 dt = DefragTrackerGetNew(
tv,
dtv, p);
599 DefragTrackerInit(dt, p);
606 }
while (dt != NULL);
624 uint32_t key = DefragHashGetKey(p);
630 if (hb->
head == NULL) {
639 if (!dt->
remove && DefragTrackerCompare(dt, p)) {
646 }
else if (dt->
hnext == NULL) {
652 }
while (dt != NULL);
704 bool incr_reuse_cnt = !dt->
remove;
716 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)
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]
#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)
uint8_t DefragGetOsPolicy(Packet *p)
Get the defrag policy based on the destination address of the packet.
uint16_t counter_defrag_tracker_timeout
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.
int DefragTrackerTimedOut(DefragTracker *dt, SCTime_t ts)
#define DEFRAG_DEFAULT_HASHSIZE
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
uint16_t counter_defrag_tracker_hard_reuse
uint64_t DefragTrackerGetMemcap(void)
Return memcap value.
#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)
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
#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)
#define DEBUG_VALIDATE_BUG_ON(exp)
#define SCMutexTrylock(mut)
uint16_t counter_defrag_tracker_soft_reuse