From: Oleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) Date: Tue, 13 Sep 2022 13:05:26 +0000 (+0000) Subject: Pull request #3583: detection: add option to reduce rtns by port values X-Git-Tag: 3.1.42.0~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0630981e25ba4089fb498d3adc946eaad500c570;p=thirdparty%2Fsnort3.git Pull request #3583: detection: add option to reduce rtns by port values Merge in SNORT/snort3 from ~VHORBATO/snort3:rtn_deduplication to master Squashed commit of the following: commit e111df05dfd6598100f5140f07d8326f41d68c74 Author: Vitalii Date: Tue Sep 6 18:04:23 2022 +0300 detection: add option to reduce rtns by port values --- diff --git a/src/detection/detection_module.cc b/src/detection/detection_module.cc index 12597bdb5..8bf8273e4 100644 --- a/src/detection/detection_module.cc +++ b/src/detection/detection_module.cc @@ -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; } diff --git a/src/main/snort_config.h b/src/main/snort_config.h index e0e77f2d7..221057bde 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -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 diff --git a/src/parser/dev_notes.txt b/src/parser/dev_notes.txt index c98a5b713..1d453b5dd 100644 --- a/src/parser/dev_notes.txt +++ b/src/parser/dev_notes.txt @@ -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. diff --git a/src/parser/parse_rule.cc b/src/parser/parse_rule.cc index 52eed81c4..a4b3abad1 100644 --- a/src/parser/parse_rule.cc +++ b/src/parser/parse_rule.cc @@ -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; } diff --git a/src/parser/parser.cc b/src/parser/parser.cc index 902473e8b..a34aa9a15 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -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); diff --git a/src/parser/parser.h b/src/parser/parser.h index 16d357ba1..be9fc0194 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -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);