diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 20d62e06f3..73a3b7fac0 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -26,6 +26,10 @@ export { type OfTable: record { p: PluginState; r: Rule; + c: count &default=0; # how many replies did we see so far? needed for ids where we have multiple rules... + packet_count: count &default=0; + byte_count: count &default=0; + duration_sec: double &default=0.0; }; ## the time interval after which an openflow message is considered to be timed out @@ -206,7 +210,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow local c = p$of_config; local flow_mod = OpenFlow::ofp_flow_mod( - $cookie=OpenFlow::generate_cookie(r$id), + $cookie=OpenFlow::generate_cookie(r$id*2), # leave one space for the cases in which we need two rules. $command=OpenFlow::OFPFC_ADD, $idle_timeout=c$idle_timeout, $priority=int_to_count(r$priority + c$priority_offset) @@ -272,7 +276,11 @@ function openflow_add_rule(p: PluginState, r: Rule) : bool for ( i in matches ) { if ( OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) + { of_messages[r$id, flow_mod$command] = OfTable($p=p, $r=r); + flow_mod = copy(flow_mod); + ++flow_mod$cookie; + } else event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); } @@ -293,19 +301,39 @@ function openflow_remove_rule(p: PluginState, r: Rule) : bool if ( OpenFlow::flow_mod(p$of_controller, [], flow_mod) ) of_messages[r$id, flow_mod$command] = OfTable($p=p, $r=r); else + { event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); + return F; + } + + # if this was an address or mac match, we also need to remove the reverse + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + local flow_mod_2 = copy(flow_mod); + ++flow_mod_2$cookie; + OpenFlow::flow_mod(p$of_controller, [], flow_mod_2); + } return T; } event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 { - local id = OpenFlow::get_cookie_uid(flow_mod$cookie); + local id = OpenFlow::get_cookie_uid(flow_mod$cookie)/2; if ( [id, flow_mod$command] !in of_messages ) return; local r = of_messages[id,flow_mod$command]$r; local p = of_messages[id,flow_mod$command]$p; + local c = of_messages[id,flow_mod$command]$c; + + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + ++of_messages[id,flow_mod$command]$c; + if ( of_messages[id,flow_mod$command]$c < 2 ) + return; # will do stuff once the second part arrives... + } + delete of_messages[id,flow_mod$command]; if ( p$of_controller$supports_flow_removed ) @@ -319,7 +347,7 @@ event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow: event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 { - local id = OpenFlow::get_cookie_uid(flow_mod$cookie); + local id = OpenFlow::get_cookie_uid(flow_mod$cookie)/2; if ( [id, flow_mod$command] !in of_messages ) return; @@ -332,12 +360,24 @@ event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow: event OpenFlow::flow_removed(match: OpenFlow::ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count) { - local id = OpenFlow::get_cookie_uid(cookie); + local id = OpenFlow::get_cookie_uid(cookie)/2; if ( id !in of_flows ) return; - local r = of_flows[id]$r; - local p = of_flows[id]$p; + local rec = of_flows[id]; + local r = rec$r; + local p = rec$p; + + if ( r$entity$ty == ADDRESS || r$entity$ty == MAC ) + { + ++of_flows[id]$c; + if ( of_flows[id]$c < 2 ) + return; # will do stuff once the second part arrives... + else + event Pacf::rule_timeout(r, FlowInfo($duration=double_to_interval((rec$duration_sec+duration_sec)/2), $packet_count=packet_count+rec$packet_count, $byte_count=byte_count+rec$byte_count), p); + + return; + } event Pacf::rule_timeout(r, FlowInfo($duration=double_to_interval(duration_sec+0.0), $packet_count=packet_count, $byte_count=byte_count), p); } diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index 00baa60d23..fc81807f6d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-22-20-37-34 +#open 2015-05-23-01-58-18 #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_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst #types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511106 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - -#close 2015-05-22-20-37-34 +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511108 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - +#close 2015-05-23-01-58-18