]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
defrag: add exception policy memcap stats counters
authorJuliana Fajardini <jufajardini@oisf.net>
Thu, 30 Mar 2023 19:53:01 +0000 (16:53 -0300)
committerVictor Julien <victor@inliniac.net>
Thu, 11 Apr 2024 12:23:16 +0000 (14:23 +0200)
Add defrag memcap stats counter.

Task #5816

etc/schema.json
src/decode.c
src/decode.h
src/defrag-hash.c
src/defrag-hash.h
src/defrag.c

index 8aa3a028f38b1655755f7cc6ecffa1124349c3aa..587135d8bce0b507fc1a9cf6c1a5f59b4d45308e 100644 (file)
                         "max_frag_hits": {
                             "type": "integer"
                         },
+                        "memcap_exception_policy": {
+                            "description":
+                                    "How many times defrag memcap exception policy was applied, and which one",
+                            "$ref": "#/$defs/exceptionPolicy"
+                        },
                         "ipv4": {
                             "type": "object",
                             "properties": {
index 64a6d43d56f9fb99935271f721df5ab3dd8ff619..9fa39911576e52171dc9eff2f468732465ce6842 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2023 Open Information Security Foundation
+/* Copyright (C) 2007-2024 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
 #include "decode-erspan.h"
 #include "decode-teredo.h"
 
+#include "defrag-hash.h"
+
 #include "util-hash.h"
 #include "util-hash-string.h"
 #include "util-print.h"
 #include "util-profiling.h"
 #include "util-validate.h"
+#include "util-debug.h"
+#include "util-exception-policy.h"
 #include "action-globals.h"
 
 uint32_t default_packet_size = 0;
@@ -76,6 +80,32 @@ extern bool stats_stream_events;
 uint8_t decoder_max_layers = PKT_DEFAULT_MAX_DECODED_LAYERS;
 uint16_t packet_alert_max = PACKET_ALERT_MAX;
 
+/* Settings order as in the enum */
+// clang-format off
+ExceptionPolicyStatsSetts defrag_memcap_eps_stats = {
+    .valid_settings_ids = {
+    /* EXCEPTION_POLICY_NOT_SET */      false,
+    /* EXCEPTION_POLICY_AUTO */         false,
+    /* EXCEPTION_POLICY_PASS_PACKET */  true,
+    /* EXCEPTION_POLICY_PASS_FLOW */    false,
+    /* EXCEPTION_POLICY_BYPASS_FLOW */  true,
+    /* EXCEPTION_POLICY_DROP_PACKET */  false,
+    /* EXCEPTION_POLICY_DROP_FLOW */    false,
+    /* EXCEPTION_POLICY_REJECT */       true,
+    },
+    .valid_settings_ips = {
+    /* EXCEPTION_POLICY_NOT_SET */      false,
+    /* EXCEPTION_POLICY_AUTO */         false,
+    /* EXCEPTION_POLICY_PASS_PACKET */  true,
+    /* EXCEPTION_POLICY_PASS_FLOW */    false,
+    /* EXCEPTION_POLICY_BYPASS_FLOW */  true,
+    /* EXCEPTION_POLICY_DROP_PACKET */  true,
+    /* EXCEPTION_POLICY_DROP_FLOW */    false,
+    /* EXCEPTION_POLICY_REJECT */       true,
+    },
+};
+// clang-format on
+
 /* Settings order as in the enum */
 // clang-format off
 ExceptionPolicyStatsSetts flow_memcap_eps_stats = {
@@ -551,6 +581,14 @@ void DecodeUnregisterCounters(void)
     SCMutexUnlock(&g_counter_table_mutex);
 }
 
+static bool IsDefragMemcapExceptionPolicyStatsValid(enum ExceptionPolicy policy)
+{
+    if (EngineModeIsIPS()) {
+        return defrag_memcap_eps_stats.valid_settings_ips[policy];
+    }
+    return defrag_memcap_eps_stats.valid_settings_ids[policy];
+}
+
 static bool IsFlowMemcapExceptionPolicyStatsValid(enum ExceptionPolicy policy)
 {
     if (EngineModeIsIPS()) {
@@ -638,6 +676,10 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
     dtv->counter_defrag_max_hit =
         StatsRegisterCounter("defrag.max_frag_hits", tv);
 
+    ExceptionPolicySetStatsCounters(tv, &dtv->counter_defrag_memcap_eps, &defrag_memcap_eps_stats,
+            DefragGetMemcapExceptionPolicy(), "defrag.memcap_exception_policy.",
+            IsDefragMemcapExceptionPolicyStatsValid);
+
     for (int i = 0; i < DECODE_EVENT_MAX; i++) {
         BUG_ON(i != (int)DEvents[i].code);
 
index 65e7ac1bb9293209e46d7a66e7151fe419b45c87..cae316923ba6a96ffe971822516575d9af64aab2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2023 Open Information Security Foundation
+/* Copyright (C) 2007-2024 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -739,6 +739,7 @@ typedef struct DecodeThreadVars_
     uint16_t counter_defrag_ipv6_fragments;
     uint16_t counter_defrag_ipv6_reassembled;
     uint16_t counter_defrag_max_hit;
+    ExceptionPolicyCounters counter_defrag_memcap_eps;
 
     uint16_t counter_flow_memcap;
     ExceptionPolicyCounters counter_flow_memcap_eps;
index eb754d6efacec6acd18f350851179952af7797ee..04104ce05645cfbc618caa3bca5eb891418c70ec 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2022 Open Information Security Foundation
+/* Copyright (C) 2007-2024 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -74,6 +74,11 @@ uint64_t DefragTrackerGetMemuse(void)
     return memusecopy;
 }
 
+enum ExceptionPolicy DefragGetMemcapExceptionPolicy(void)
+{
+    return defrag_config.memcap_policy;
+}
+
 uint32_t DefragTrackerSpareQueueGetSize(void)
 {
     return DefragTrackerQueueLen(&defragtracker_spare_q);
@@ -459,6 +464,15 @@ static inline int DefragTrackerCompare(DefragTracker *t, Packet *p)
     return CMP_DEFRAGTRACKER(t, p, id);
 }
 
+static void DefragExceptionPolicyStatsIncr(
+        ThreadVars *tv, DecodeThreadVars *dtv, enum ExceptionPolicy policy)
+{
+    uint16_t id = dtv->counter_defrag_memcap_eps.eps_id[policy];
+    if (likely(tv && id > 0)) {
+        StatsIncr(tv, id);
+    }
+}
+
 /**
  *  \brief Get a new defrag tracker
  *
@@ -467,12 +481,13 @@ static inline int DefragTrackerCompare(DefragTracker *t, Packet *p)
  *
  *  \retval dt *LOCKED* tracker on success, NULL on error.
  */
-static DefragTracker *DefragTrackerGetNew(Packet *p)
+static DefragTracker *DefragTrackerGetNew(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
 {
 #ifdef DEBUG
     if (g_eps_defrag_memcap != UINT64_MAX && g_eps_defrag_memcap == p->pcap_cnt) {
         SCLogNotice("simulating memcap hit for packet %" PRIu64, p->pcap_cnt);
         ExceptionPolicyApply(p, defrag_config.memcap_policy, PKT_DROP_REASON_DEFRAG_MEMCAP);
+        DefragExceptionPolicyStatsIncr(tv, dtv, defrag_config.memcap_policy);
         return NULL;
     }
 #endif
@@ -497,6 +512,7 @@ static DefragTracker *DefragTrackerGetNew(Packet *p)
             dt = DefragTrackerGetUsedDefragTracker();
             if (dt == NULL) {
                 ExceptionPolicyApply(p, defrag_config.memcap_policy, PKT_DROP_REASON_DEFRAG_MEMCAP);
+                DefragExceptionPolicyStatsIncr(tv, dtv, defrag_config.memcap_policy);
                 return NULL;
             }
 
@@ -506,6 +522,7 @@ static DefragTracker *DefragTrackerGetNew(Packet *p)
             dt = DefragTrackerAlloc();
             if (dt == NULL) {
                 ExceptionPolicyApply(p, defrag_config.memcap_policy, PKT_DROP_REASON_DEFRAG_MEMCAP);
+                DefragExceptionPolicyStatsIncr(tv, dtv, defrag_config.memcap_policy);
                 return NULL;
             }
 
@@ -530,7 +547,7 @@ static DefragTracker *DefragTrackerGetNew(Packet *p)
  *
  * returns a *LOCKED* tracker or NULL
  */
-DefragTracker *DefragGetTrackerFromHash (Packet *p)
+DefragTracker *DefragGetTrackerFromHash(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
 {
     DefragTracker *dt = NULL;
 
@@ -542,7 +559,7 @@ DefragTracker *DefragGetTrackerFromHash (Packet *p)
 
     /* see if the bucket already has a tracker */
     if (hb->head == NULL) {
-        dt = DefragTrackerGetNew(p);
+        dt = DefragTrackerGetNew(tv, dtv, p);
         if (dt == NULL) {
             DRLOCK_UNLOCK(hb);
             return NULL;
@@ -571,7 +588,7 @@ DefragTracker *DefragGetTrackerFromHash (Packet *p)
             dt = dt->hnext;
 
             if (dt == NULL) {
-                dt = pdt->hnext = DefragTrackerGetNew(p);
+                dt = pdt->hnext = DefragTrackerGetNew(tv, dtv, p);
                 if (dt == NULL) {
                     DRLOCK_UNLOCK(hb);
                     return NULL;
index 0cbbef184066be322f25b8738e5117c620baf7a2..96368adcec6cb85088b82217fb2a4cb70ac33566 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2023 Open Information Security Foundation
+/* Copyright (C) 2007-2024 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -27,6 +27,7 @@
 #include "decode.h"
 #include "defrag.h"
 #include "util-exception-policy.h"
+#include "util-exception-policy-types.h"
 
 /** Spinlocks or Mutex for the flow buckets. */
 //#define DRLOCK_SPIN
@@ -92,7 +93,7 @@ void DefragInitConfig(bool quiet);
 void DefragHashShutdown(void);
 
 DefragTracker *DefragLookupTrackerFromHash (Packet *);
-DefragTracker *DefragGetTrackerFromHash (Packet *);
+DefragTracker *DefragGetTrackerFromHash(ThreadVars *tv, DecodeThreadVars *dtv, Packet *);
 void DefragTrackerRelease(DefragTracker *);
 void DefragTrackerClearMemory(DefragTracker *);
 void DefragTrackerMoveToSpare(DefragTracker *);
@@ -101,5 +102,6 @@ uint32_t DefragTrackerSpareQueueGetSize(void);
 int DefragTrackerSetMemcap(uint64_t);
 uint64_t DefragTrackerGetMemcap(void);
 uint64_t DefragTrackerGetMemuse(void);
+enum ExceptionPolicy DefragGetMemcapExceptionPolicy(void);
 
 #endif /* SURICATA_DEFRAG_HASH_H */
index 8cebe8fb9590f2c3878e285fbb8ae3ace36230dc..0d54754200414283bcbbf7aa4f5250b04d3b0f4e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2022 Open Information Security Foundation
+/* Copyright (C) 2007-2024 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -985,7 +985,7 @@ DefragGetOsPolicy(Packet *p)
 static DefragTracker *
 DefragGetTracker(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
 {
-    return DefragGetTrackerFromHash(p);
+    return DefragGetTrackerFromHash(tv, dtv, p);
 }
 
 /**