]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream/midstream: add counter for exception policy
authorJuliana Fajardini <jufajardini@oisf.net>
Wed, 22 Mar 2023 19:04:50 +0000 (16:04 -0300)
committerVictor Julien <victor@inliniac.net>
Thu, 11 Apr 2024 12:23:16 +0000 (14:23 +0200)
Add stats counters for when there is an exception policy applied in case
of a session picked up midstream.

Task #5816

etc/schema.json
src/stream-tcp.c
src/stream-tcp.h

index 28e26df5eadbf3eb32d0c944e0576e28f15532f3..15f148e4f6a2d215d8d681756d0527ff5d4269c4 100644 (file)
                         "midstream_pickups": {
                             "type": "integer"
                         },
+                        "midstream_exception_policy": {
+                            "description":
+                                    "How many times midstream exception policy was applied, and which one",
+                            "$ref": "#/$defs/exceptionPolicy"
+                        },
                         "no_flow": {
                             "type": "integer"
                         },
index dca1811de17efa92b5ac50936b53161a1254c843..df2f7d26a07aaf6c574bb3c9f2174424db3dbfbd 100644 (file)
@@ -142,6 +142,58 @@ ExceptionPolicyStatsSetts stream_reassembly_memcap_eps_stats = {
 };
 // clang-format on
 
+/* Settings order as in the enum */
+// clang-format off
+ExceptionPolicyStatsSetts stream_midstream_enabled_eps_stats = {
+    .valid_settings_ids = {
+    /* EXCEPTION_POLICY_NOT_SET */      false,
+    /* EXCEPTION_POLICY_AUTO */         false,
+    /* EXCEPTION_POLICY_PASS_PACKET */  false,
+    /* EXCEPTION_POLICY_PASS_FLOW */    true,
+    /* EXCEPTION_POLICY_BYPASS_FLOW */  false,
+    /* EXCEPTION_POLICY_DROP_PACKET */  false,
+    /* EXCEPTION_POLICY_DROP_FLOW */    false,
+    /* EXCEPTION_POLICY_REJECT */       false,
+    },
+    .valid_settings_ips = {
+    /* EXCEPTION_POLICY_NOT_SET */      false,
+    /* EXCEPTION_POLICY_AUTO */         false,
+    /* EXCEPTION_POLICY_PASS_PACKET */  false,
+    /* EXCEPTION_POLICY_PASS_FLOW */    true,
+    /* EXCEPTION_POLICY_BYPASS_FLOW */  false,
+    /* EXCEPTION_POLICY_DROP_PACKET */  false,
+    /* EXCEPTION_POLICY_DROP_FLOW */    false,
+    /* EXCEPTION_POLICY_REJECT */       false,
+    },
+};
+// clang-format on
+
+/* Settings order as in the enum */
+// clang-format off
+ExceptionPolicyStatsSetts stream_midstream_disabled_eps_stats = {
+    .valid_settings_ids = {
+    /* EXCEPTION_POLICY_NOT_SET */      false,
+    /* EXCEPTION_POLICY_AUTO */         false,
+    /* EXCEPTION_POLICY_PASS_PACKET */  false,
+    /* EXCEPTION_POLICY_PASS_FLOW */    true,
+    /* 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 */  false,
+    /* EXCEPTION_POLICY_PASS_FLOW */    true,
+    /* EXCEPTION_POLICY_BYPASS_FLOW */  true,
+    /* EXCEPTION_POLICY_DROP_PACKET */  false,
+    /* EXCEPTION_POLICY_DROP_FLOW */    true,
+    /* EXCEPTION_POLICY_REJECT */       true,
+    },
+};
+// clang-format on
+
 static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *, TcpSession *, Packet *);
 void StreamTcpReturnStreamSegments (TcpStream *);
 void StreamTcpInitConfig(bool);
@@ -982,6 +1034,29 @@ static inline void StreamTcpCloseSsnWithReset(Packet *p, TcpSession *ssn)
             "TCP_CLOSED", ssn, StreamTcpStateAsString(ssn->state));
 }
 
+static bool IsMidstreamExceptionPolicyStatsValid(enum ExceptionPolicy policy)
+{
+    if (EngineModeIsIPS()) {
+        if (stream_config.midstream) {
+            return stream_midstream_enabled_eps_stats.valid_settings_ips[policy];
+        }
+        return stream_midstream_disabled_eps_stats.valid_settings_ips[policy];
+    }
+    if (stream_config.midstream) {
+        return stream_midstream_enabled_eps_stats.valid_settings_ids[policy];
+    }
+    return stream_midstream_disabled_eps_stats.valid_settings_ids[policy];
+}
+
+static void StreamTcpMidstreamExceptionPolicyStatsIncr(
+        ThreadVars *tv, StreamTcpThread *stt, enum ExceptionPolicy policy)
+{
+    const uint16_t id = stt->counter_tcp_midstream_eps.eps_id[policy];
+    if (likely(tv && id > 0)) {
+        StatsIncr(tv, id);
+    }
+}
+
 static int StreamTcpPacketIsRetransmission(TcpStream *stream, Packet *p)
 {
     if (p->payload_len == 0)
@@ -1035,6 +1110,7 @@ static int StreamTcpPacketStateNone(
     } else if (p->tcph->th_flags & TH_FIN) {
         /* Drop reason will only be used if midstream policy is set to fail closed */
         ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM);
+        StreamTcpMidstreamExceptionPolicyStatsIncr(tv, stt, stream_config.midstream_policy);
 
         if (!stream_config.midstream || p->payload_len == 0) {
             StreamTcpSetEvent(p, STREAM_FIN_BUT_NO_SESSION);
@@ -1131,6 +1207,7 @@ static int StreamTcpPacketStateNone(
     } else if ((p->tcph->th_flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
         /* Drop reason will only be used if midstream policy is set to fail closed */
         ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM);
+        StreamTcpMidstreamExceptionPolicyStatsIncr(tv, stt, stream_config.midstream_policy);
 
         if (!stream_config.midstream && !stream_config.async_oneside) {
             SCLogDebug("Midstream not enabled, so won't pick up a session");
@@ -1303,6 +1380,7 @@ static int StreamTcpPacketStateNone(
     } else if (p->tcph->th_flags & TH_ACK) {
         /* Drop reason will only be used if midstream policy is set to fail closed */
         ExceptionPolicyApply(p, stream_config.midstream_policy, PKT_DROP_REASON_STREAM_MIDSTREAM);
+        StreamTcpMidstreamExceptionPolicyStatsIncr(tv, stt, stream_config.midstream_policy);
 
         if (!stream_config.midstream) {
             SCLogDebug("Midstream not enabled, so won't pick up a session");
@@ -5850,6 +5928,16 @@ TmEcode StreamTcpThreadInit(ThreadVars *tv, void *initdata, void **data)
     stt->counter_tcp_pseudo_failed = StatsRegisterCounter("tcp.pseudo_failed", tv);
     stt->counter_tcp_invalid_checksum = StatsRegisterCounter("tcp.invalid_checksum", tv);
     stt->counter_tcp_midstream_pickups = StatsRegisterCounter("tcp.midstream_pickups", tv);
+    if (stream_config.midstream) {
+        ExceptionPolicySetStatsCounters(tv, &stt->counter_tcp_midstream_eps,
+                &stream_midstream_enabled_eps_stats, stream_config.midstream_policy,
+                "tcp.midstream_exception_policy.", IsMidstreamExceptionPolicyStatsValid);
+    } else {
+        ExceptionPolicySetStatsCounters(tv, &stt->counter_tcp_midstream_eps,
+                &stream_midstream_disabled_eps_stats, stream_config.midstream_policy,
+                "tcp.midstream_exception_policy.", IsMidstreamExceptionPolicyStatsValid);
+    }
+
     stt->counter_tcp_wrong_thread = StatsRegisterCounter("tcp.pkt_on_wrong_thread", tv);
     stt->counter_tcp_ack_unseen_data = StatsRegisterCounter("tcp.ack_unseen_data", tv);
 
index 8bdb4f7a3a2e5d48393a300abd34053f44fcd811..4f5bb35e7711b3b6f8f769492204719d18731811 100644 (file)
@@ -96,6 +96,8 @@ typedef struct StreamTcpThread_ {
     uint16_t counter_tcp_invalid_checksum;
     /** midstream pickups */
     uint16_t counter_tcp_midstream_pickups;
+    /** exception policy stats */
+    ExceptionPolicyCounters counter_tcp_midstream_eps;
     /** wrong thread */
     uint16_t counter_tcp_wrong_thread;
     /** ack for unseen data */