Add basic OpenFlow plugin for Pacf.

This also changes a few types in pacf and adds a few needed bits and
pieces to the OpenFlow framework.

And - it even has a testcase...
This commit is contained in:
Johanna Amann 2015-04-14 15:22:19 -07:00
parent aad988d2f2
commit 7d7578146f
12 changed files with 258 additions and 33 deletions

View file

@ -45,15 +45,20 @@ event bro_init() &priority=5
Log::create_stream(LOG, [$columns=Info, $ev=log_openflow, $path="openflow"]);
}
function log_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool
function log_flow_mod(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool
{
Log::write(LOG, [$ts=network_time(), $dpid=state$log_dpid, $match=match, $flow_mod=flow_mod]);
return T;
}
function log_describe(state: ControllerState): string
{
return fmt("OpenFlog Log Plugin - DPID %d", state$log_dpid);
}
function log_new(dpid: count): OpenFlow::Controller
{
return [$state=[$log_dpid=dpid, $_plugin=OpenFlow::LOG],
$flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear];
$flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear, $describe=log_describe];
}

View file

@ -164,9 +164,14 @@ function ryu_flow_clear(state: OpenFlow::ControllerState): bool
return T;
}
function ryu_describe(state: ControllerState): string
{
return fmt("Ryu Plugin - http://%s:%d - DPID: %d", state$ryu_host, state$ryu_port, state$ryu_dpid);
}
# Ryu controller constructor
function ryu_new(host: addr, host_port: count, dpid: count): OpenFlow::Controller
{
return [$state=[$ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid, $_plugin=OpenFlow::RYU],
$flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear];
$flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear, $describe=ryu_describe];
}

View file

@ -111,6 +111,8 @@ export {
type Controller: record {
## Controller related state.
state: ControllerState;
## function that describes the controller. Has to be implemented.
describe: function(state: ControllerState): string;
## flow_mod function
flow_mod: function(state: ControllerState, match: ofp_match, flow_mod: ofp_flow_mod): bool &optional;
## flow_clear function

View file

@ -81,7 +81,7 @@ export {
## assigned to ``r$id``. Note that "successful" means "a plugin knew how to handle
## the rule", it doesn't necessarily mean that it was indeed successfully put in
## place, because that might happen asynchronously and thus fail only later.
global add_rule: function(r: Rule) : string;
global add_rule: function(r: Rule) : count;
## Removes a rule.
##
@ -91,7 +91,7 @@ export {
## to handle the removal. Note that again "success" means the plugin accepted the
## removal. They might still fail to put it into effect, as that might happen
## asynchronously and thus go wrong at that point.
global remove_rule: function(id: string) : bool;
global remove_rule: function(id: count) : bool;
###### Asynchronous feedback on rules.
@ -152,7 +152,7 @@ export {
## to handle the removal. Note that again "success" means the plugin accepted the
## removal. They might still fail to put it into effect, as that might happen
## asynchronously and thus go wrong at that point.
global remove_notification: function(id: string) : bool;
global remove_notification: function(id: count) : bool;
###### Asynchronous feedback on notifications.
@ -240,6 +240,10 @@ export {
## Plugin triggering the log entry.
plugin: string &log &optional;
};
## Event that can be handled to access the :bro:type:`Pacf::Info`
## record as it is sent on to the logging framework.
global log_pacf: event(rec: Info);
}
redef record Rule += {
@ -248,12 +252,12 @@ redef record Rule += {
};
global plugins: vector of PluginState;
global rule_counter: count = 0;
global rules: table[string] of Rule;
global rule_counter: count = 1;
global rules: table[count] of Rule;
event bro_init() &priority=5
{
Log::create_stream(Pacf::LOG, [$columns=Info]);
Log::create_stream(Pacf::LOG, [$columns=Info, $ev=log_pacf, $path="pacf"]);
}
function entity_to_info(info: Info, e: Entity)
@ -294,7 +298,7 @@ function rule_to_info(info: Info, r: Rule)
if ( r?$location )
info$location = r$location;
entity_to_info(info, r$entity);
}
@ -353,18 +357,18 @@ function drop_address(a: addr, t: interval, location: string &default="") : bool
{
local e: Entity = [$ty=ADDRESS, $ip=addr_to_subnet(a)];
local r: Rule = [$ty=DROP, $target=FORWARD, $entity=e, $expire=t, $location=location];
local id = add_rule(r);
return |id| > 0;
return id > 0;
}
function shunt_flow(f: flow_id, t: interval, location: string &default="") : bool
{
local e: Entity = [$ty=FLOW, $flow=f];
local r: Rule = [$ty=DROP, $target=MONITOR, $entity=e, $expire=t, $location=location];
local id = add_rule(r);
return |id| > 0;
return id > 0;
}
function reset(e: Entity)
@ -377,15 +381,15 @@ function clear()
print "Pacf::clear not implemented yet";
}
function add_rule(r: Rule) : string
function add_rule(r: Rule) : count
{
r$id = fmt("%d", ++rule_counter);
r$id = ++rule_counter;
for ( i in plugins )
{
local p = plugins[i];
if ( p$plugin$add_rule(p, r) )
if ( p$plugin$add_rule(p, r) )
{
r$_plugin = p;
log_rule(r, "ADD", REQUESTED, p);
@ -394,14 +398,15 @@ function add_rule(r: Rule) : string
}
log_rule_no_plugin(r, FAILED, "not supported");
return 0;
}
function remove_rule(id: string) : bool
function remove_rule(id: count) : bool
{
local r = rules[id];
local p = r$_plugin;
if ( ! p$plugin$remove_rule(r$_plugin, r) )
if ( ! p$plugin$remove_rule(r$_plugin, r) )
{
log_rule_error(r, "remove failed", p);
return F;
@ -426,7 +431,7 @@ event rule_added(r: Rule, p: PluginState, msg: string &default="")
log_rule(r, "ADD", SUCCEEDED, p);
rules[r$id] = r;
if ( r?$expire && ! p$plugin$can_expire )
schedule r$expire { rule_expire(r, p) };
}
@ -453,7 +458,7 @@ function add_notification(n: Notification) : string
print "Pacf::add_notification not implemented yet";
}
function remove_notification(id: string) : bool
function remove_notification(id: count) : bool
{
print "Pacf::remove_notification not implemented yet";
}
@ -473,5 +478,3 @@ event notification_timeout(n: Notification, p: PluginState)
event notification_error(n: Notification, p: PluginState, msg: string &default="")
{
}

View file

@ -13,7 +13,7 @@ export {
_priority: int &default=+0;
};
# Definitioan of a plugin.
# Definition of a plugin.
#
# Generally a plugin needs to implement only what it can support. By
# returning failure, it indicates that it can't support something and the
@ -37,7 +37,7 @@ export {
can_expire: bool;
# One-time initialization functionl called when plugin gets registered, and
# befire any ther methods are called.
# before any other methods are called.
init: function(state: PluginState) &optional;
# One-time finalization function called when a plugin is shutdown; no further
@ -72,7 +72,7 @@ export {
# A transaction groups a number of operations. The plugin can add them internally
# and postpone putting them into effect until committed. This allows to build a
# configuration of multiple rules at once, including replaying a previous state.
# configuration of multiple rules at once, including replaying a previous state.
transaction_begin: function(state: PluginState) &optional;
transaction_end: function(state: PluginState) &optional;
};

View file

@ -1 +1,2 @@
@load ./debug
@load ./openflow

View file

@ -0,0 +1,164 @@
@load ../plugin
@load base/frameworks/openflow
module Pacf;
export {
type OfConfig: record {
monitor: bool &default=T;
forward: bool &default=T;
idle_timeout: count &default=60;
table_id: count &optional;
};
redef record PluginState += {
## OpenFlow controller for Pacf OpenFlow plugin
of_controller: OpenFlow::Controller &optional;
## OpenFlow configuration record that is passed on initialization
of_config: OfConfig &optional;
};
## Instantiates an openflow plugin for the PACF framework.
global create_openflow: function(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState;
}
function openflow_name(p: PluginState) : string
{
return fmt("Openflow - %s", p$of_controller$describe(p$of_controller$state));
}
function openflow_check_rule(c: OfConfig, r: Rule) : bool
{
if ( r$target == MONITOR && c$monitor )
return T;
if ( r$target == FORWARD && c$forward )
return T;
return F;
}
function entity_to_match(e: Entity): vector of OpenFlow::ofp_match
{
local v : vector of OpenFlow::ofp_match = vector();
if ( e$ty == CONNECTION )
{
v[|v|] = OpenFlow::match_conn(e$conn); # forward and...
v[|v|] = OpenFlow::match_conn(e$conn, T); # reverse
return v;
}
local dl_type = OpenFlow::ETH_IPv4;
if ( e$ty == ADDRESS || e$ty == RESPONDER || e$ty == ORIGINATOR )
{
if ( is_v6_subnet(e$ip) )
dl_type = OpenFlow::ETH_IPv6;
if ( e$ty == ADDRESS || e$ty == ORIGINATOR )
v[|v|] = OpenFlow::ofp_match(
$dl_type=dl_type,
$nw_src=e$ip
);
if ( e$ty == ADDRESS || e$ty == RESPONDER )
v[|v|] = OpenFlow::ofp_match(
$dl_type=dl_type,
$nw_dst=e$ip
);
return v;
}
local proto = OpenFlow::IP_TCP;
if ( e$ty == FLOW )
{
if ( is_v6_addr(e$flow$src_h) )
dl_type = OpenFlow::ETH_IPv6;
if ( is_udp_port(e$flow$src_p) )
proto = OpenFlow::IP_UDP;
else if ( is_icmp_port(e$flow$src_p) )
proto = OpenFlow::IP_ICMP;
v[|v|] = OpenFlow::ofp_match(
$dl_type=dl_type,
$nw_proto=proto,
$nw_src=addr_to_subnet(e$flow$src_h),
$tp_src=e$flow$src_p,
$nw_dst=addr_to_subnet(e$flow$dst_h),
$tp_dst=e$flow$dst_p
);
return v;
}
Reporter::error(fmt("Entity type %s not supported for openflow yet", cat(e$ty)));
return v;
}
function openflow_add_rule(p: PluginState, r: Rule) : bool
{
local c = p$of_config;
if ( ! openflow_check_rule(c, r) )
return F;
local flow_mod: OpenFlow::ofp_flow_mod = [
$cookie=r$id,
$command=OpenFlow::OFPFC_ADD,
$idle_timeout=c$idle_timeout,
$priority=int_to_count(r$priority)
];
if ( r?$expire )
flow_mod$hard_timeout = double_to_count(interval_to_double(r$expire));
if ( c?$table_id )
flow_mod$table_id = c$table_id;
local matches = entity_to_match(r$entity);
for ( i in matches )
{
if ( ! OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) )
event rule_error(r, p, "Error while executing OpenFlow::flow_mod");
}
return T;
}
function openflow_remove_rule(p: PluginState, r: Rule) : bool
{
if ( ! openflow_check_rule(p$of_config, r) )
return F;
local flow_mod: OpenFlow::ofp_flow_mod = [
$cookie=r$id,
$command=OpenFlow::OFPFC_DELETE
];
OpenFlow::flow_mod(p$of_controller, [], flow_mod);
return T;
}
global openflow_plugin = Plugin(
$name=openflow_name,
$can_expire = T,
# $init = openflow_init,
# $done = openflow_done,
$add_rule = openflow_add_rule,
$remove_rule = openflow_remove_rule
# $add_notification = openflow_add_notification,
# $remove_notification = openflow_remove_notification,
# $transaction_begin = openflow_transaction_begin,
# $transaction_end = openflow_transaction_end
);
function create_openflow(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState
{
local p: PluginState = [$plugin=openflow_plugin, $of_controller=controller, $of_config=config];
return p;
}

View file

@ -81,7 +81,7 @@ export {
d: double &optional; ##< Argument for rule types requiring a double argument.
s: string &optional; ##< Argument for rule types requiring a string argument.
id: string &default=""; ##< Internally determined unique ID for this rule. Will be set when added.
id: count &default=0; ##< Internally determined unique ID for this rule. Will be set when added.
};
## Type of notifications that the framework supports. Each type lists the
@ -113,7 +113,7 @@ export {
d: double; ##< Argument for notification types requiring a double argument.
s: string; ##< Argument for notification types requiring a string argument.
id: string &default=""; ##< Internally determined unique ID for this notification. Will be set when added.
id: count &default=0; ##< Internally determined unique ID for this notification. Will be set when added.
};
}

View file

@ -1,4 +1,4 @@
pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=<uninitialized>, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=<uninitialized>, mac=<uninitialized>], expire=30.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=1, _plugin=<uninitialized>]
pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=10.10.1.4/32, mac=<uninitialized>], expire=15.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=2, _plugin=<uninitialized>]
pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=10.10.1.4/32, mac=<uninitialized>], expire=15.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=2, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}]]]
pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=<uninitialized>, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=<uninitialized>, mac=<uninitialized>], expire=30.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=1, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}]]]
pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=<uninitialized>, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=<uninitialized>, mac=<uninitialized>], expire=30.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=2, _plugin=<uninitialized>]
pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=10.10.1.4/32, mac=<uninitialized>], expire=15.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=3, _plugin=<uninitialized>]
pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=<uninitialized>, flow=<uninitialized>, ip=10.10.1.4/32, mac=<uninitialized>], expire=15.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=3, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}], of_controller=<uninitialized>, of_config=<uninitialized>]]
pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=<uninitialized>, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=<uninitialized>, mac=<uninitialized>], expire=30.0 secs, priority=0, location=, i=<uninitialized>, d=<uninitialized>, s=<uninitialized>, id=2, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}], of_controller=<uninitialized>, of_config=<uninitialized>]]

View file

@ -0,0 +1,12 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path openflow
#open 2015-04-14-22-20-31
#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_group flow_mod.flags flow_mod.out_ports
#types time count count string string count count count count count subnet subnet port port count count enum count count count count count vector[count]
1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 2 - OpenFlow::OFPFC_ADD 60 30 0 - 0 (empty)
1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - 0 (empty)
1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - 0 (empty)
#close 2015-04-14-22-20-31

View file

@ -0,0 +1,12 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path pacf
#open 2015-04-14-22-20-31
#fields ts category cmd state action target entity_type entity msg location plugin
#types time enum string enum string enum string string string string string
0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42
1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42
1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42
#close 2015-04-14-22-20-31

View file

@ -0,0 +1,21 @@
# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT
# @TEST-EXEC: btest-diff pacf.log
# @TEST-EXEC: btest-diff openflow.log
@load base/frameworks/pacf
global of_controller: OpenFlow::Controller;
event bro_init()
{
of_controller = OpenFlow::log_new(42);
local pacf_of = Pacf::create_openflow(of_controller);
Pacf::activate(pacf_of, 0);
}
event connection_established(c: connection)
{
local id = c$id;
Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec);
Pacf::drop_address(id$orig_h, 15sec);
}