]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3583: detection: add option to reduce rtns by port values
authorOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Tue, 13 Sep 2022 13:05:26 +0000 (13:05 +0000)
committerOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Tue, 13 Sep 2022 13:05:26 +0000 (13:05 +0000)
Merge in SNORT/snort3 from ~VHORBATO/snort3:rtn_deduplication to master

Squashed commit of the following:

commit e111df05dfd6598100f5140f07d8326f41d68c74
Author: Vitalii <vhorbato@cisco.com>
Date:   Tue Sep 6 18:04:23 2022 +0300

    detection: add option to reduce rtns by port values

src/detection/detection_module.cc
src/main/snort_config.h
src/parser/dev_notes.txt
src/parser/parse_rule.cc
src/parser/parser.cc
src/parser/parser.h

index 12597bdb5f928a7e85c6361e39d58d298639feee..8bf8273e4f469cfb1f82d4dcacfae355f0de66f8 100644 (file)
@@ -98,6 +98,10 @@ static const Parameter detection_params[] =
     { "enable_address_anomaly_checks", Parameter::PT_BOOL, nullptr, "false",
       "enable check and alerting of address anomalies" },
 
+    { "enable_strict_reduction", Parameter::PT_BOOL, nullptr, "false",
+      "enable strict deduplication of rule headers by ports (saves memory, but "
+      "loses some speed during config reading)" },
+
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 /* *INDENT-ON* */
@@ -206,5 +210,8 @@ bool DetectionModule::set(const char*, Value& v, SnortConfig* sc)
     else if ( v.is("enable_address_anomaly_checks") )
         sc->address_anomaly_check_enabled = v.get_bool();
 
+    else if ( v.is("enable_strict_reduction") )
+        sc->enable_strict_reduction = v.get_bool();
+
     return true;
 }
index e0e77f2d7936b6836576992560eec839b87da9b4..221057bde9bc92a8115ce7c3a0f3453eb87d6f41 100644 (file)
@@ -234,6 +234,7 @@ public:
     bool global_rule_state = false;
     bool global_default_rule_state = true;
     bool allow_missing_so_rules = false;
+    bool enable_strict_reduction = false;
 
     //------------------------------------------------------
     // process stuff
index c98a5b7130f6bd681436351fb0c73b60da778324..1d453b5dd1e7c2f25d86d491efd09910cc4f0aaf 100644 (file)
@@ -23,9 +23,10 @@ parse the option and its parameters and create an instance.
 
 RTN is a per-policy data. Within a given policy all RTNs which have the
 same action and 5-tuple (protocol, addresses, ports values after expanding
-variables) will be collapsed into a single RTN. This reduces the memory and
-computation efforts to evaluate RTN. Hence, RTN has a counter for OTNs
-referencing it.
+variables) will be collapsed into a single RTN. When strict reduction is enabled,
+port variables with the same values will also be collapsed into single RTNs.
+This reduces the memory and computation efforts to evaluate RTN.
+Hence, RTN has a counter for OTNs referencing it.
 RTNs populate policies when the rule states are applied.
 
 OTN is a global data. It is uniquely identified by gid:sid pair.
index 52eed81c45a15d534e7545d0ca49a63908be4533..a4b3abad1ff8a8cd3808ac74b097390fcc44ae09 100644 (file)
@@ -93,6 +93,7 @@ static std::string s_type;
 static std::string s_body;
 
 static bool action_file_id = false;
+static bool strict_rtn_reduction = false;
 
 struct SoRule
 {
@@ -401,6 +402,9 @@ static int ParsePortList(
     return 0;
 }
 
+void set_strict_rtn_reduction(bool new_strict_rtn_reduction)
+{ strict_rtn_reduction = new_strict_rtn_reduction; }
+
 bool same_headers(RuleTreeNode* rule, RuleTreeNode* rtn)
 {
     if ( !rule or !rtn )
@@ -425,13 +429,22 @@ bool same_headers(RuleTreeNode* rule, RuleTreeNode* rtn)
     if ( rule->dip and rtn->dip and sfvar_compare(rule->dip, rtn->dip) != SFIP_EQUAL )
         return false;
 
-    if ( rule->src_portobject and rtn->src_portobject
-        and !PortObjectEqual(rule->src_portobject, rtn->src_portobject) )
-        return false;
+    if ( strict_rtn_reduction )
+    {
+        if ( rule->src_portobject and rtn->src_portobject
+            and !PortObjectEqual(rule->src_portobject, rtn->src_portobject) )
+            return false;
 
-    if ( rule->dst_portobject and rtn->dst_portobject
-        and !PortObjectEqual(rule->dst_portobject, rtn->dst_portobject) )
-        return false;
+        if ( rule->dst_portobject and rtn->dst_portobject
+            and !PortObjectEqual(rule->dst_portobject, rtn->dst_portobject) )
+            return false;
+    }
+    else
+    {
+        if ( (rule->src_portobject != rtn->src_portobject)
+            or (rule->dst_portobject != rtn->dst_portobject) )
+            return false;
+    }
 
     return true;
 }
index 902473e8bbcf75b5563cdb64136bad0581175ce3..a34aa9a155d8c432aefd022a564c2de63fcc4af2 100644 (file)
@@ -421,6 +421,8 @@ void DestroyRuleTreeNode(RuleTreeNode* rtn)
 
 void ParseRules(SnortConfig* sc)
 {
+    set_strict_rtn_reduction(sc->enable_strict_reduction);
+
     for ( unsigned idx = 0; idx < sc->policy_map->ips_policy_count(); ++idx )
     {
         set_ips_policy(sc, idx);
index 16d357ba14361a0f864b8979aafec9df4a71e449..be9fc0194360b8b9677124532da4ddb6a5a732ac 100644 (file)
@@ -63,6 +63,7 @@ int ParseBool(const char* arg);
 int addRtnToOtn(snort::SnortConfig*, struct OptTreeNode*, RuleTreeNode*);
 int addRtnToOtn(snort::SnortConfig*, struct OptTreeNode*, RuleTreeNode*, PolicyId);
 
+void set_strict_rtn_reduction(bool);
 bool same_headers(RuleTreeNode*, RuleTreeNode*);
 RuleTreeNode* deleteRtnFromOtn(OptTreeNode*, snort::SnortConfig* sc = nullptr);
 RuleTreeNode* deleteRtnFromOtn(struct OptTreeNode*, PolicyId, snort::SnortConfig* sc = nullptr, bool remove = true);