diff --git a/scripts/base/frameworks/netcontrol/cluster.bro b/scripts/base/frameworks/netcontrol/cluster.bro index 1f4738cf2e..b07c119372 100644 --- a/scripts/base/frameworks/netcontrol/cluster.bro +++ b/scripts/base/frameworks/netcontrol/cluster.bro @@ -19,7 +19,7 @@ export { ## Workers need ability to forward commands to manager. redef Cluster::worker2manager_events += /NetControl::cluster_netcontrol_(add|remove|delete)_rule/; ## Workers need to see the result events from the manager. -redef Cluster::manager2worker_events += /NetControl::rule_(added|removed|timeout|error|exists)/; +redef Cluster::manager2worker_events += /NetControl::rule_(added|removed|timeout|error|exists|new|destroyed)/; function activate(p: PluginState, priority: int) { @@ -83,9 +83,7 @@ event NetControl::cluster_netcontrol_remove_rule(id: string) { remove_rule_impl(id); } -@endif -@if ( Cluster::local_node_type() == Cluster::MANAGER ) event rule_expire(r: Rule, p: PluginState) &priority=-5 { rule_expire_impl(r, p); @@ -123,3 +121,26 @@ event rule_error(r: Rule, p: PluginState, msg: string &default="") &priority=-5 } @endif +# Workers use the events to keep track in their local state tables +@if ( Cluster::local_node_type() != Cluster::MANAGER ) + +event rule_new(r: Rule) &priority=5 + { + if ( r$id in rules ) + return; + + rules[r$id] = r; + + add_subnet_entry(r); + } + +event rule_destroyed(r: Rule) &priority=5 + { + if ( r$id !in rules ) + return; + + remove_subnet_entry(r); + delete rules[r$id]; + } + +@endif diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro index f8e4ea26bf..2a5b3c42b1 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -136,12 +136,16 @@ export { ## ## id: The rule to delete, specified as the ID returned by :bro:id:`add_rule` . ## - ## Returns: True if removal is successful, or sent to manager. + ## Returns: True if removal is successful, or sent to manager. ## False if the rule could not be found. global delete_rule: function(id: string) : bool; ## Searches all rules affecting a certain IP address. ## + ## This function works on both the manager and workers of a cluster. Note that on + ## the worker, the internal rule variables (starting with _) will not reflect the + ## current state. + ## ## ip: The ip address to search for ## ## Returns: vector of all rules affecting the IP address @@ -149,6 +153,10 @@ export { ## Searches all rules affecting a certain subnet. ## + ## This function works on both the manager and workers of a cluster. Note that on + ## the worker, the internal rule variables (starting with _) will not reflect the + ## current state. + ## ## sn: The subnet to search for ## ## Returns: vector of all rules affecting the subnet @@ -156,7 +164,7 @@ export { ###### Asynchronous feedback on rules. - ## Confirms that a rule was put in place. + ## Confirms that a rule was put in place by a plugin. ## ## r: The rule now in place. ## @@ -178,7 +186,8 @@ export { ## msg: An optional informational message by the plugin. global rule_exists: event(r: Rule, p: PluginState, msg: string &default=""); - ## Reports that a rule was removed due to a remove: function() call. + ## Reports that a plugin reports a rule was removed due to a + ## remove: function() vall. ## ## r: The rule now removed. ## @@ -188,7 +197,7 @@ export { ## msg: An optional informational message by the plugin. global rule_removed: event(r: Rule, p: PluginState, msg: string &default=""); - ## Reports that a rule was removed internally due to a timeout. + ## Reports that a rule was removed from a plugin due to a timeout. ## ## r: The rule now removed. ## @@ -209,6 +218,26 @@ export { ## msg: An optional informational message by the plugin. global rule_error: event(r: Rule, p: PluginState, msg: string &default=""); + ## This event is raised when a new rule is created by the NetControl framework + ## due to a call to add_rule. From this moment, until the rule_destroyed event + ## is raised, the rule is tracked internally by the NetControl framewory. + ## + ## Note that this event does not mean that a rule was succesfully added by + ## any backend; it just means that the rule has been accepted and addition + ## to the specified backend is queued. To get information when rules are actually + ## installed by the hardware, use the rule_added, rule_exists, rule_removed, rule_timeout + ## and rule_error events. + global rule_new: event(r: Rule); + + ## This event is raised when a rule is deleted from the NetControl framework, + ## because it is no longer in use. This can be caused by the fact that a rule + ## was removed by all plugins to which it was added, by the fact that it timed out + ## or due to rule errors. + ## + ## To get the cause or a rule remove, hook the rule_removed, rule_timeout and + ## rule_error calls. + global rule_destroyed: event(r: Rule); + ## Hook that allows the modification of rules passed to add_rule before they ## are passed on to the plugins. If one of the hooks uses break, the rule is ## ignored and not passed on to any plugin. @@ -759,6 +788,8 @@ function add_rule_impl(rule: Rule) : string add_subnet_entry(rule); + event NetControl::rule_new(rule); + return rule$id; } @@ -775,6 +806,8 @@ function rule_cleanup(r: Rule) delete rule_entities[r$entity, r$ty]; delete rules[r$id]; + + event NetControl::rule_destroyed(r); } function delete_rule_impl(id: string): bool diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout new file mode 100644 index 0000000000..9c961bff21 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout @@ -0,0 +1,4 @@ +Rule added, worker-1:2, 2 +Rule added, worker-1:3, 3 +1 +Rule destroyed, worker-1:3, 3, 0 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout new file mode 100644 index 0000000000..c638f34077 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout @@ -0,0 +1,3 @@ +Rule added, worker-2:2, 4 +Rule added, worker-2:3, 5 +1 diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro index 5c42f0d8eb..051dd3eb82 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -6,7 +6,8 @@ # @TEST-EXEC: sleep 1 # @TEST-EXEC: btest-bg-run worker-2 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-2 bro --pseudo-realtime -C -r $TRACES/tls/ecdhe.pcap %INPUT" # @TEST-EXEC: btest-bg-wait 20 -# @TEST-EXEC: btest-diff manager-1/netcontrol.log +# @TEST-EXEC: btest-diff worker-1/.stdout +# @TEST-EXEC: btest-diff worker-2/.stdout @TEST-START-FILE cluster-layout.bro redef Cluster::nodes = { @@ -59,4 +60,12 @@ event remote_connection_closed(p: event_peer) { event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string &default="") { print "Rule added", r$id, r$cid; + if ( r$entity?$ip ) + print |NetControl::find_rules_subnet(r$entity$ip)|; + } + +event NetControl::rule_destroyed(r: NetControl::Rule) + { + if ( r$entity?$ip ) + print "Rule destroyed", r$id, r$cid, |NetControl::find_rules_subnet(r$entity$ip)|; }