NetControl: find_rules_subnet works in cluster mode

This introduces two new events, NetControl::rule_new and
NetControl::rule_destroyed, which are raised when rules are first added
and then deleted from the internal state tracking.
This commit is contained in:
Johanna Amann 2016-05-20 10:42:12 -07:00
parent 52d694f3bd
commit 6779325520
5 changed files with 78 additions and 8 deletions

View file

@ -19,7 +19,7 @@ export {
## Workers need ability to forward commands to manager. ## Workers need ability to forward commands to manager.
redef Cluster::worker2manager_events += /NetControl::cluster_netcontrol_(add|remove|delete)_rule/; redef Cluster::worker2manager_events += /NetControl::cluster_netcontrol_(add|remove|delete)_rule/;
## Workers need to see the result events from the manager. ## 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) function activate(p: PluginState, priority: int)
{ {
@ -83,9 +83,7 @@ event NetControl::cluster_netcontrol_remove_rule(id: string)
{ {
remove_rule_impl(id); remove_rule_impl(id);
} }
@endif
@if ( Cluster::local_node_type() == Cluster::MANAGER )
event rule_expire(r: Rule, p: PluginState) &priority=-5 event rule_expire(r: Rule, p: PluginState) &priority=-5
{ {
rule_expire_impl(r, p); rule_expire_impl(r, p);
@ -123,3 +121,26 @@ event rule_error(r: Rule, p: PluginState, msg: string &default="") &priority=-5
} }
@endif @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

View file

@ -136,12 +136,16 @@ export {
## ##
## id: The rule to delete, specified as the ID returned by :bro:id:`add_rule` . ## 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. ## False if the rule could not be found.
global delete_rule: function(id: string) : bool; global delete_rule: function(id: string) : bool;
## Searches all rules affecting a certain IP address. ## 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 ## ip: The ip address to search for
## ##
## Returns: vector of all rules affecting the IP address ## Returns: vector of all rules affecting the IP address
@ -149,6 +153,10 @@ export {
## Searches all rules affecting a certain subnet. ## 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 ## sn: The subnet to search for
## ##
## Returns: vector of all rules affecting the subnet ## Returns: vector of all rules affecting the subnet
@ -156,7 +164,7 @@ export {
###### Asynchronous feedback on rules. ###### 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. ## r: The rule now in place.
## ##
@ -178,7 +186,8 @@ export {
## msg: An optional informational message by the plugin. ## msg: An optional informational message by the plugin.
global rule_exists: event(r: Rule, p: PluginState, msg: string &default=""); 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. ## r: The rule now removed.
## ##
@ -188,7 +197,7 @@ export {
## msg: An optional informational message by the plugin. ## msg: An optional informational message by the plugin.
global rule_removed: event(r: Rule, p: PluginState, msg: string &default=""); 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. ## r: The rule now removed.
## ##
@ -209,6 +218,26 @@ export {
## msg: An optional informational message by the plugin. ## msg: An optional informational message by the plugin.
global rule_error: event(r: Rule, p: PluginState, msg: string &default=""); 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 ## 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 ## are passed on to the plugins. If one of the hooks uses break, the rule is
## ignored and not passed on to any plugin. ## ignored and not passed on to any plugin.
@ -759,6 +788,8 @@ function add_rule_impl(rule: Rule) : string
add_subnet_entry(rule); add_subnet_entry(rule);
event NetControl::rule_new(rule);
return rule$id; return rule$id;
} }
@ -775,6 +806,8 @@ function rule_cleanup(r: Rule)
delete rule_entities[r$entity, r$ty]; delete rule_entities[r$entity, r$ty];
delete rules[r$id]; delete rules[r$id];
event NetControl::rule_destroyed(r);
} }
function delete_rule_impl(id: string): bool function delete_rule_impl(id: string): bool

View file

@ -0,0 +1,4 @@
Rule added, worker-1:2, 2
Rule added, worker-1:3, 3
1
Rule destroyed, worker-1:3, 3, 0

View file

@ -0,0 +1,3 @@
Rule added, worker-2:2, 4
Rule added, worker-2:3, 5
1

View file

@ -6,7 +6,8 @@
# @TEST-EXEC: sleep 1 # @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-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-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 @TEST-START-FILE cluster-layout.bro
redef Cluster::nodes = { 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="") event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string &default="")
{ {
print "Rule added", r$id, r$cid; 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)|;
} }