From: Russ Combs (rucombs) Date: Fri, 4 Aug 2017 16:36:21 +0000 (-0400) Subject: Merge pull request #953 in SNORT/snort3 from reload_inspector to master X-Git-Tag: 3.0.0-240~75 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=19ab78a7f8b3340a2942c26f78f050130be1b444;p=thirdparty%2Fsnort3.git Merge pull request #953 in SNORT/snort3 from reload_inspector to master Squashed commit of the following: commit c5ec856a1fd022d83fddc05eac88aa5969dede2c Author: Bhagya Tholpady Date: Thu Aug 3 23:53:09 2017 -0400 control: dev notes updates, updates to code per review commit 4c020ea967d22d3db38468fd46810c304bbba64e Author: Bhagya Tholpady Date: Mon Jul 31 09:35:40 2017 -0400 control: updates to reload_policy per review commit a1218168afb28e65253bd0a5e4984438e0214bba Author: Bhagya Tholpady Date: Wed Jul 26 12:39:02 2017 -0400 control: enforce fname argument for reload policy commit 80a3a2d95d0738818017904920546e42738d3cd7 Author: Bhagya Tholpady Date: Wed Jul 26 12:17:29 2017 -0400 control: renaming the stats for policy reloads commit fa2456f55f3cd0925a227ca0e26083b87ee91c26 Author: Bhagya Tholpady Date: Wed Jul 26 11:37:55 2017 -0400 control: update snort_config.cc per master commit 408f6872cda9970d940ea8623486fdb829e36024 Author: Bhagya Tholpady Date: Sun Jul 23 16:16:49 2017 -0400 updating unit tests commit 249eeee92fdcff74e4fd093e4c5022451aeb484f Author: Bhagya Tholpady Date: Sat Jul 22 16:07:28 2017 -0400 control: update binder with new inspector commit cd0b2b8f38af2d1a38f4b6aedb574791ccf30512 Author: Bhagya Tholpady Date: Mon Jul 17 21:44:41 2017 -0400 control: Changes per code review : reinstantiate default binder when inspectors are enabled. rename command to reload_policy commit 06e84c034ec8da7fe8daea2afb8d0ed9e26136cc Author: Bhagya Tholpady Date: Fri Jul 14 16:48:34 2017 -0400 control: delete the old binder while reloading inspector commit 9b1928c8587b878b518eb7b5339ec290c613daa5 Author: Bhagya Tholpady Date: Wed Jul 26 11:05:30 2017 -0400 control: resolve merge conflicts --- diff --git a/src/dev_notes.txt b/src/dev_notes.txt index 47e88274b..a1a78ea07 100644 --- a/src/dev_notes.txt +++ b/src/dev_notes.txt @@ -23,3 +23,16 @@ Reload is implemented by swapping a thread local config pointer by each running Pig. The inspector manager is called to empty trash if the main loop is not otherwise busy. +Reload policy is implemented by cloning the thread local config and +overwriting the policy map and the inspection policy in the main thread. +The inspector list from the old config's inspection policy is copied +into the inspection policy of the new config. After the config pointer +is cloned, the new inspection policy elements (reloadable) such as +inspectors, binder, wizard etc are read and instantiated. +The inspector list of the new config is updated by swapping out the +old inspectors, binder etc. with the newly instantiated elements. The +reloaded inspectors, binders and other inspection policy elements are +marked for deletion. After the new inspection policy is loaded, the +thread local config pointer is swapped with the new cloned config +by running Pig. This happens in the packet thread. The inspector manager + is then called to delete any reloaded policy elements and empty trash. diff --git a/src/hash/test/sfghash_test.cc b/src/hash/test/sfghash_test.cc index 72ca020c8..fe27ff77e 100644 --- a/src/hash/test/sfghash_test.cc +++ b/src/hash/test/sfghash_test.cc @@ -33,7 +33,8 @@ // Stubs whose sole purpose is to make the test code link SnortConfig my_config; THREAD_LOCAL SnortConfig *snort_conf = &my_config; -SnortConfig::SnortConfig() { snort_conf->run_flags = 0;} // run_flags is used indirectly from SFHASHFCN class by calling SnortConfig::static_hash() +SnortConfig::SnortConfig(SnortConfig*) +{ snort_conf->run_flags = 0;} // run_flags is used indirectly from SFHASHFCN class by calling SnortConfig::static_hash() SnortConfig::~SnortConfig() {} // implement functions for virtual FileVerdict FilePolicy::type_lookup(Flow* , FileContext* ) { return FILE_VERDICT_UNKNOWN;} diff --git a/src/ips_options/test/ips_regex_test.cc b/src/ips_options/test/ips_regex_test.cc index 1f72cdde8..0a59ede06 100644 --- a/src/ips_options/test/ips_regex_test.cc +++ b/src/ips_options/test/ips_regex_test.cc @@ -65,7 +65,7 @@ THREAD_LOCAL SnortConfig* snort_conf = &s_conf; static SnortState s_state; -SnortConfig::SnortConfig() +SnortConfig::SnortConfig(SnortConfig*) { state = &s_state; memset(state, 0, sizeof(*state)); diff --git a/src/main.cc b/src/main.cc index 1325d8a57..52e341d4c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -329,6 +329,47 @@ int main_reload_config(lua_State* L) return 0; } +int main_reload_policy(lua_State* L) +{ + if ( Swapper::get_reload_in_progress() ) + { + current_request->respond("== reload pending; retry\n"); + return 0; + } + const char* fname = nullptr; + + if ( L ) + { + Lua::ManageStack(L, 1); + fname = luaL_checkstring(L, 1); + } + + if ( fname and *fname ) + current_request->respond(".. reloading policy\n"); + else + { + current_request->respond("== filename required\n"); + return 0; + } + + SnortConfig* old = snort_conf; + SnortConfig* sc = Snort::get_reloaded_policy(old, fname); + + if ( !sc ) + { + current_request->respond("== reload failed\n"); + return 0; + } + snort_conf = sc; + proc_stats.policy_reloads++; + + bool from_shell = ( L != nullptr ); + current_request->respond(".. swapping policy\n", from_shell); + broadcast(get_command(new ACSwap(new Swapper(old, sc)), from_shell)); + + return 0; +} + int main_reload_daq(lua_State* L) { bool from_shell = ( L != nullptr ); diff --git a/src/main.h b/src/main.h index 555ae3f8a..c9a7e88e3 100644 --- a/src/main.h +++ b/src/main.h @@ -29,6 +29,7 @@ const char* get_prompt(); int main_dump_stats(lua_State* = nullptr); int main_rotate_stats(lua_State* = nullptr); int main_reload_config(lua_State* = nullptr); +int main_reload_policy(lua_State* = nullptr); int main_reload_daq(lua_State* = nullptr); int main_reload_hosts(lua_State* = nullptr); int main_process(lua_State* = nullptr); diff --git a/src/main/policy.cc b/src/main/policy.cc index b72cb0e17..5a61ee18a 100644 --- a/src/main/policy.cc +++ b/src/main/policy.cc @@ -65,16 +65,17 @@ public: { DetectionEngine::detect((Packet*)e.get_packet()); } // FIXIT-L not const! }; -InspectionPolicy::InspectionPolicy() +InspectionPolicy::InspectionPolicy(InspectionPolicy* other_inspection_policy) { framework_policy = nullptr; + cloned = false; - InspectorManager::new_policy(this); + InspectorManager::new_policy(this, other_inspection_policy); } InspectionPolicy::~InspectionPolicy() { - InspectorManager::delete_policy(this); + InspectorManager::delete_policy(this, cloned); } void InspectionPolicy::configure() @@ -121,9 +122,12 @@ IpsPolicy::~IpsPolicy() // policy map //------------------------------------------------------------------------- -PolicyMap::PolicyMap() +PolicyMap::PolicyMap(PolicyMap* other_map) { - add_shell(new Shell); + if ( other_map ) + clone(other_map); + else + add_shell(new Shell); set_inspection_policy(inspection_policy[0]); set_ips_policy(ips_policy[0]); @@ -132,17 +136,29 @@ PolicyMap::PolicyMap() PolicyMap::~PolicyMap() { - for ( auto p : shells ) - delete p; + if ( cloned ) + { + if ( inspection_policy.size() ) + { + InspectionPolicy* default_policy = inspection_policy[0]; + default_policy->cloned = true; + delete default_policy; + } + } + else + { + for ( auto p : shells ) + delete p; - for ( auto p : inspection_policy ) - delete p; + for ( auto p : inspection_policy ) + delete p; - for ( auto p : ips_policy ) - delete p; + for ( auto p : ips_policy ) + delete p; - for ( auto p : network_policy ) - delete p; + for ( auto p : network_policy ) + delete p; + } shells.clear(); inspection_policy.clear(); @@ -150,6 +166,23 @@ PolicyMap::~PolicyMap() network_policy.clear(); } +void PolicyMap::clone(PolicyMap *other_map) +{ + shells = other_map->shells; + ips_policy = other_map->ips_policy; + network_policy = other_map->network_policy; + + for ( unsigned i = 0; i < (other_map->inspection_policy.size()); i++) + { + if ( i == 0 ) + { + inspection_policy.push_back(new InspectionPolicy(other_map->inspection_policy[i])); + } + else + inspection_policy.push_back(other_map->inspection_policy[i]); + } +} + unsigned PolicyMap::add_shell(Shell* sh) { unsigned idx = shells.size(); diff --git a/src/main/policy.h b/src/main/policy.h index cb156e64e..429152ea5 100644 --- a/src/main/policy.h +++ b/src/main/policy.h @@ -85,7 +85,7 @@ public: struct InspectionPolicy { public: - InspectionPolicy(); + InspectionPolicy(InspectionPolicy* old_inspection_policy = nullptr); ~InspectionPolicy(); void configure(); @@ -93,6 +93,7 @@ public: public: struct FrameworkPolicy* framework_policy; DataBus dbus; + bool cloned; }; //------------------------------------------------------------------------- @@ -143,10 +144,11 @@ class Shell; class PolicyMap { public: - PolicyMap(); + PolicyMap(PolicyMap* old_map = nullptr); ~PolicyMap(); unsigned add_shell(Shell*); + void clone(PolicyMap *old_map); Shell* get_shell(unsigned i = 0) { return i < shells.size() ? shells[i] : nullptr; } @@ -156,6 +158,7 @@ public: // FIXIT-M make impl private std::vector inspection_policy; std::vector ips_policy; std::vector network_policy; + bool cloned = false; }; //------------------------------------------------------------------------- diff --git a/src/main/snort.cc b/src/main/snort.cc index ebf4c684e..f1cfb9fb6 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -56,6 +56,7 @@ #include "log/packet_tracer.h" #include "loggers/loggers.h" #include "main.h" +#include "main/shell.h" #include "managers/action_manager.h" #include "managers/codec_manager.h" #include "managers/inspector_manager.h" @@ -630,6 +631,41 @@ SnortConfig* Snort::get_reload_config(const char* fname) return sc; } +SnortConfig* Snort::get_reloaded_policy(SnortConfig* other_conf, const char* fname) +{ + reloading = true; + + SnortConfig* sc = new SnortConfig(other_conf); + Shell sh = Shell(fname); + sh.configure(sc); + + if ( ModuleManager::get_errors() || !sc->verify() ) + { + sc->cloned = true; + InspectorManager::update_policy(other_conf); + delete sc; + set_policies(other_conf); + reloading = false; + return nullptr; + } + + if ( !InspectorManager::configure(sc, true) ) + { + sc->cloned = true; + InspectorManager::update_policy(other_conf); + delete sc; + set_policies(other_conf); + reloading = false; + return nullptr; + } + + other_conf->cloned = true; + + InspectorManager::update_policy(sc); + reloading = false; + return sc; +} + void Snort::capture_packet() { if ( snort_main_thread_pid == gettid() ) diff --git a/src/main/snort.h b/src/main/snort.h index 449ad50ff..cb19533ca 100644 --- a/src/main/snort.h +++ b/src/main/snort.h @@ -38,6 +38,7 @@ class Snort { public: static SnortConfig* get_reload_config(const char* fname); + static SnortConfig* get_reloaded_policy(SnortConfig*, const char* fname); static void setup(int argc, char* argv[]); static bool drop_privileges(); static void do_pidfile(); diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 44be55320..b25cf1c96 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -168,37 +168,56 @@ static void init_policies(SnortConfig* sc) * but the goal is to minimize config checks at run time when running in * IDS mode so we keep things simple and enforce that the only difference * among run_modes is how we handle packets via the log_func. */ -SnortConfig::SnortConfig() +SnortConfig::SnortConfig(SnortConfig* other_conf) { - num_layers = DEFAULT_LAYERMAX; + homenet.clear(); + obfuscation_net.clear(); - max_attribute_hosts = DEFAULT_MAX_ATTRIBUTE_HOSTS; - max_attribute_services_per_host = DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST; + if ( !other_conf ) + { + num_layers = DEFAULT_LAYERMAX; - max_metadata_services = DEFAULT_MAX_METADATA_SERVICES; - mpls_stack_depth = DEFAULT_LABELCHAIN_LENGTH; + max_attribute_hosts = DEFAULT_MAX_ATTRIBUTE_HOSTS; + max_attribute_services_per_host = DEFAULT_MAX_ATTRIBUTE_SERVICES_PER_HOST; - daq_config = new SFDAQConfig(); - InspectorManager::new_config(this); + max_metadata_services = DEFAULT_MAX_METADATA_SERVICES; + mpls_stack_depth = DEFAULT_LABELCHAIN_LENGTH; - num_slots = ThreadConfig::get_instance_max(); - state = (SnortState*)snort_calloc(num_slots, sizeof(SnortState)); + daq_config = new SFDAQConfig(); + InspectorManager::new_config(this); - profiler = new ProfilerConfig; - latency = new LatencyConfig(); - memory = new MemoryConfig(); - policy_map = new PolicyMap; - thread_config = new ThreadConfig(); + num_slots = ThreadConfig::get_instance_max(); + state = (SnortState*)snort_calloc(num_slots, sizeof(SnortState)); - homenet.clear(); - obfuscation_net.clear(); + profiler = new ProfilerConfig; + latency = new LatencyConfig(); + memory = new MemoryConfig(); + policy_map = new PolicyMap; + thread_config = new ThreadConfig(); - memset(evalOrder, 0, sizeof(evalOrder)); - proto_ref = new ProtocolReference; + memset(evalOrder, 0, sizeof(evalOrder)); + proto_ref = new ProtocolReference; + } + else + { + clone(other_conf); + policy_map = new PolicyMap(other_conf->policy_map); + } + + set_inspection_policy(get_inspection_policy()); + set_ips_policy(get_ips_policy()); + set_network_policy(get_network_policy()); } SnortConfig::~SnortConfig() { + if ( cloned ) + { + policy_map->cloned = true; + delete policy_map; + return; + } + free_rule_state_list(); FreeClassifications(classifications); FreeReferences(references); @@ -298,6 +317,17 @@ void SnortConfig::post_setup() #endif } +void SnortConfig::clone(SnortConfig* conf) +{ + *this = *conf; + if (conf->homenet.get_family() != 0) + memcpy(&homenet, &conf->homenet, sizeof(homenet)); + + if (conf->obfuscation_net.get_family() != 0) + memcpy(&obfuscation_net, &conf->obfuscation_net, sizeof(obfuscation_net)); + +} + // merge in everything from the command line config void SnortConfig::merge(SnortConfig* cmd_line) { diff --git a/src/main/snort_config.h b/src/main/snort_config.h index c2199f746..27712d83a 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -140,7 +140,7 @@ struct SnortState struct SnortConfig { public: - SnortConfig(); + SnortConfig(SnortConfig* other_conf = nullptr ); ~SnortConfig(); void setup(); @@ -148,6 +148,7 @@ public: bool verify(); void merge(SnortConfig*); + void clone(SnortConfig*); public: //------------------------------------------------------ @@ -347,6 +348,11 @@ public: ThreadConfig* thread_config; + //------------------------------------------------------ + //Reload inspector related + + bool cloned = false; + //------------------------------------------------------ // policy access InspectionPolicy* get_inspection_policy() diff --git a/src/main/snort_module.cc b/src/main/snort_module.cc index 424b03b63..afdbfd8b2 100644 --- a/src/main/snort_module.cc +++ b/src/main/snort_module.cc @@ -65,6 +65,7 @@ static const Command snort_cmds[] = { "dump_stats", main_dump_stats, nullptr, "show summary statistics" }, { "rotate_stats", main_rotate_stats, nullptr, "roll perfmonitor log files" }, { "reload_config", main_reload_config, s_reload, "load new configuration" }, + { "reload_policy", main_reload_policy, s_reload, "reload part or all of the default policy" }, { "reload_daq", main_reload_daq, nullptr, "reload daq module" }, { "reload_hosts", main_reload_hosts, s_reload, "load a new hosts table" }, diff --git a/src/managers/inspector_manager.cc b/src/managers/inspector_manager.cc index cdf2efb29..61d4cfb1c 100644 --- a/src/managers/inspector_manager.cc +++ b/src/managers/inspector_manager.cc @@ -33,6 +33,7 @@ #include "flow/flow.h" #include "flow/session.h" #include "log/messages.h" +#include "main/snort.h" #include "main/snort_config.h" #include "main/thread_config.h" #include "protocols/packet.h" @@ -95,11 +96,19 @@ struct PHClass { return ( a->api.type < b->api.type ); } }; +enum ReloadType { + RELOAD_TYPE_NONE = 0, + RELOAD_TYPE_REENABLED, + RELOAD_TYPE_NEW, + RELOAD_TYPE_MAX +}; + struct PHInstance { PHClass& pp_class; Inspector* handler; string name; + ReloadType reload_type; PHInstance(PHClass&, SnortConfig*, Module* = nullptr); ~PHInstance(); @@ -109,10 +118,21 @@ struct PHInstance void set_name(const char* s) { name = s; } + + void set_reloaded(ReloadType val) + { reload_type = val; } + + bool is_reloaded() + { return ((reload_type == RELOAD_TYPE_REENABLED) or + (reload_type == RELOAD_TYPE_NEW)); } + + ReloadType get_reload_type() + { return reload_type; } }; PHInstance::PHInstance(PHClass& p, SnortConfig* sc, Module* mod) : pp_class(p) { + reload_type = RELOAD_TYPE_NONE; handler = p.api.ctor(mod); if ( handler ) @@ -179,6 +199,8 @@ struct FrameworkPolicy Inspector* binder; Inspector* wizard; + bool default_binder; + void vectorize(); }; @@ -331,54 +353,51 @@ void InspectorManager::empty_trash() // policy stuff //------------------------------------------------------------------------- -void InspectorManager::new_policy(InspectionPolicy* pi) -{ - pi->framework_policy = new FrameworkPolicy; - - pi->framework_policy->binder = nullptr; - pi->framework_policy->wizard = nullptr; -} - -void InspectorManager::delete_policy(InspectionPolicy* pi) -{ - for ( auto* p : pi->framework_policy->ilist ) - { - if ( p->handler->get_api()->type == IT_PASSIVE ) - s_trash2.push_back(p->handler); - else - s_trash.push_back(p->handler); - delete p; - } - delete pi->framework_policy; - pi->framework_policy = nullptr; -} - // FIXIT-L allowing lookup by name or type or key is kinda hinky // would be helpful to have specific lookups -static PHInstance* get_instance( - FrameworkPolicy* fp, const char* keyword, bool dflt_only = false) +static bool get_instance( + FrameworkPolicy* fp, const char* keyword, bool dflt_only, std::vector::iterator& it) { - for ( auto* p : fp->ilist ) + for ( it = fp->ilist.begin(); it != fp->ilist.end(); ++it ) { + PHInstance* p = *it; if ( p->name.size() && p->name == keyword ) - return p; + return true; else if ( !strcmp(p->pp_class.api.base.name, keyword) ) - return (!p->name.size() || !dflt_only) ? p : nullptr; + return (!p->name.size() || !dflt_only) ? true : false; else if ( p->pp_class.api.service && !strcmp(p->pp_class.api.service, keyword) ) - return p; + return true; } - return nullptr; + return false; +} + +static PHInstance* get_instance( + FrameworkPolicy* fp, const char* keyword, bool dflt_only = false) +{ + std::vector::iterator it; + return get_instance(fp, keyword, dflt_only, it)? *it : nullptr; } static PHInstance* get_new( PHClass* ppc, FrameworkPolicy* fp, const char* keyword, Module* mod, SnortConfig* sc) { - PHInstance* p = get_instance(fp, keyword); + PHInstance* p = nullptr; + bool reloaded = false; + std::vector::iterator old_it; - if ( p ) - return p; + if ( get_instance(fp, keyword, false, old_it) ) + { + if ( Snort::is_reloading() ) + { + (*old_it)->set_reloaded(RELOAD_TYPE_REENABLED); + fp->ilist.erase(old_it); + reloaded = true; + } + else + return *old_it; + } p = new PHInstance(*ppc, sc, mod); @@ -388,10 +407,59 @@ static PHInstance* get_new( return NULL; } + if ( Snort::is_reloading() ) + { + if ( reloaded ) + p->set_reloaded(RELOAD_TYPE_REENABLED); + else + p->set_reloaded(RELOAD_TYPE_NEW); + } fp->ilist.push_back(p); return p; } +void InspectorManager::new_policy(InspectionPolicy* pi, InspectionPolicy* other_pi) +{ + pi->framework_policy = new FrameworkPolicy; + bool default_binder = false; + + if ( other_pi ) + { + pi->framework_policy->ilist = other_pi->framework_policy->ilist; + default_binder = other_pi->framework_policy->default_binder; + } + + pi->framework_policy->default_binder = default_binder; + pi->framework_policy->binder = nullptr; + pi->framework_policy->wizard = nullptr; +} + +void InspectorManager::delete_policy(InspectionPolicy* pi, bool cloned) +{ + for ( auto* p : pi->framework_policy->ilist ) + { + if ( cloned and !(p->is_reloaded()) ) + continue; + + if ( p->handler->get_api()->type == IT_PASSIVE ) + s_trash2.push_back(p->handler); + else + s_trash.push_back(p->handler); + delete p; + } + delete pi->framework_policy; + pi->framework_policy = nullptr; +} + +void InspectorManager::update_policy(SnortConfig* sc) +{ + if ( sc->policy_map->inspection_policy.size() ) + { + InspectionPolicy* pi = sc->policy_map->inspection_policy[0]; + for ( auto* p : pi->framework_policy->ilist ) + p->set_reloaded(RELOAD_TYPE_NONE); + } +} // FIXIT-M create a separate list for meta handlers? is there really more than one? void InspectorManager::dispatch_meta(FrameworkPolicy* fp, int type, const uint8_t* data) { @@ -651,14 +719,51 @@ static void instantiate_binder(SnortConfig* sc, FrameworkPolicy* fp) InspectorManager::instantiate(api, m, sc); fp->binder = get_instance(fp, bind_id)->handler; fp->binder->configure(sc); + fp->default_binder = true; } -static bool configure(SnortConfig* sc, FrameworkPolicy* fp) +static bool configure(SnortConfig* sc, FrameworkPolicy* fp, bool cloned) { bool ok = true; + bool new_ins = false; + bool reenabled_ins = false; for ( auto* p : fp->ilist ) + { + ReloadType reload_type = p->get_reload_type(); + + if ( cloned ) + { + if ( reload_type == RELOAD_TYPE_NEW ) + new_ins = true; + else if ( reload_type == RELOAD_TYPE_REENABLED ) + reenabled_ins = true; + else + continue; + } ok = p->handler->configure(sc) && ok; + } + + if ( new_ins or reenabled_ins ) + { + std::vector::iterator old_binder; + if ( get_instance(fp, "binder", false, old_binder) ) + { + if ( new_ins and fp->default_binder ) + { + if ( !((*old_binder)->is_reloaded()) ) + { + (*old_binder)->set_reloaded(RELOAD_TYPE_REENABLED); + fp->ilist.erase(old_binder); + } + fp->default_binder = false; + } + else if ( reenabled_ins and !((*old_binder)->is_reloaded()) ) + { + (*old_binder)->handler->configure(sc); + } + } + } sort(fp->ilist.begin(), fp->ilist.end(), PHInstance::comp); fp->vectorize(); @@ -688,7 +793,7 @@ void InspectorManager::release(Inspector* pi) pi->rem_ref(); } -bool InspectorManager::configure(SnortConfig* sc) +bool InspectorManager::configure(SnortConfig* sc, bool cloned) { if ( !s_sorted ) { @@ -699,10 +804,13 @@ bool InspectorManager::configure(SnortConfig* sc) for ( unsigned idx = 0; idx < sc->policy_map->inspection_policy.size(); ++idx ) { + if ( cloned and idx ) + break; + set_policies(sc, idx); InspectionPolicy* p = sc->policy_map->inspection_policy[idx]; p->configure(); - ok = ::configure(sc, p->framework_policy) && ok; + ok = ::configure(sc, p->framework_policy, cloned) && ok; } set_policies(sc); diff --git a/src/managers/inspector_manager.h b/src/managers/inspector_manager.h index e726a6b42..d1fe4f0be 100644 --- a/src/managers/inspector_manager.h +++ b/src/managers/inspector_manager.h @@ -44,8 +44,9 @@ public: static void dump_buffers(); static void release_plugins(); - static void new_policy(InspectionPolicy*); - static void delete_policy(InspectionPolicy*); + static void new_policy(InspectionPolicy*, InspectionPolicy*); + static void delete_policy(InspectionPolicy*, bool cloned); + static void update_policy(SnortConfig* sc); static void new_config(SnortConfig*); static void delete_config(SnortConfig*); @@ -65,7 +66,7 @@ public: SO_PUBLIC static Inspector* acquire(const char* key, SnortConfig*); SO_PUBLIC static void release(Inspector*); - static bool configure(SnortConfig*); + static bool configure(SnortConfig*, bool cloned = false); static void print_config(SnortConfig*); static void thread_init(SnortConfig*); diff --git a/src/managers/module_manager.cc b/src/managers/module_manager.cc index 9b502f174..993087c9d 100644 --- a/src/managers/module_manager.cc +++ b/src/managers/module_manager.cc @@ -665,7 +665,8 @@ SO_PUBLIC bool open_table(const char* s, int idx) return false; // FIXIT-M only basic modules and inspectors can be reloaded at present - if ( Snort::is_reloading() and h->api and h->api->type != PT_INSPECTOR ) + if ( ( Snort::is_reloading() ) + and h->api and h->api->type != PT_INSPECTOR ) return false; Module* m = h->mod; diff --git a/src/search_engines/test/hyperscan_test.cc b/src/search_engines/test/hyperscan_test.cc index 1fd0990a8..8c25cb83e 100644 --- a/src/search_engines/test/hyperscan_test.cc +++ b/src/search_engines/test/hyperscan_test.cc @@ -78,7 +78,7 @@ THREAD_LOCAL SnortConfig* snort_conf = &s_conf; static SnortState s_state; -SnortConfig::SnortConfig() +SnortConfig::SnortConfig(SnortConfig*) { state = &s_state; memset(state, 0, sizeof(*state)); diff --git a/src/search_engines/test/search_tool_test.cc b/src/search_engines/test/search_tool_test.cc index bc185a478..1c7bf15c0 100644 --- a/src/search_engines/test/search_tool_test.cc +++ b/src/search_engines/test/search_tool_test.cc @@ -47,7 +47,7 @@ THREAD_LOCAL SnortConfig* snort_conf = &s_conf; static SnortState s_state; -SnortConfig::SnortConfig() +SnortConfig::SnortConfig(SnortConfig*) { state = &s_state; memset(state, 0, sizeof(*state)); diff --git a/src/utils/stats.cc b/src/utils/stats.cc index 83871a38b..67c102424 100644 --- a/src/utils/stats.cc +++ b/src/utils/stats.cc @@ -218,6 +218,7 @@ const PegInfo proc_names[] = { "remote_commands", "total remote commands processed" }, { "signals", "total signals processed" }, { "conf_reloads", "number of times configuration was reloaded" }, + { "policy_reloads", "number of times policies were reloaded" }, { "daq_reloads", "number of times daq configuration was reloaded" }, { "attribute_table_reloads", "number of times hosts table was reloaded" }, { "attribute_table_hosts", "total number of hosts in table" }, diff --git a/src/utils/stats.h b/src/utils/stats.h index 84d9db66d..7e08423d9 100644 --- a/src/utils/stats.h +++ b/src/utils/stats.h @@ -61,6 +61,7 @@ struct ProcessCount PegCount remote_commands; PegCount signals; PegCount conf_reloads; + PegCount policy_reloads; PegCount daq_reloads; PegCount attribute_table_reloads; PegCount attribute_table_hosts;