zeek/scripts/base/frameworks/openflow/main.bro
Johanna Amann dbc51371cb Rewrite big parts of the Openflow framework.
The API now does not follow the openflow specification quite as closely,
however I think it is much more usable. Furthermore, the Ryu plugin was
basically completely rewritten and is now more usable for general flow
manipulation.

This also adds a debug mode that just outputs the json fragments that
would be sent to ryu. At the moment, Ryu still assumes that every
request that it receives succeeds - it is not possible to get an error
message from the controller. Instead, one has to check if a flow was
added by doing a second REST request. Which seems unnecessary, and also
requires complete json parsing functionality. Hence we are not doing
that at the moment.

The alternative would be to use an external script for the actual
add-and-check-operation.
2015-04-07 15:37:46 -07:00

140 lines
4.2 KiB
Text

##! Bro's openflow control framework
##!
##! This plugin-based framework allows to control Openflow capable
##! switches by implementing communication to an Openflow controller
##! via plugins. The framework has to be instantiated via the new function
##! in one of the plugins. This framework only offers very low-level
##! functionality; if you want to use OpenFlow capable switches, e.g.,
##! for shunting, please look at the PACF framework, which provides higher
##! level functions and can use the OpenFlow framework as a backend.
module Openflow;
@load ./consts
@load ./types
export {
## Global flow_mod function.
##
## controller: The controller which should execute the flow modification
##
## match: The ofp_match record which describes the flow to match.
##
## flow_mod: The openflow flow_mod record which describes the action to take.
##
## Returns: F on error or if the plugin does not support the operation, T when the operation was queued.
global flow_mod: function(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool;
## Clear the current flow table of the controller.
##
## controller: The controller which should execute the flow modification
##
## Returns: F on error or if the plugin does not support the operation, T when the operation was queued.
global flow_clear: function(controller: Controller): bool;
## Event confirming successful modification of a flow rule.
##
## match: The ofp_match record which describes the flow to match.
##
## flow_mod: The openflow flow_mod record which describes the action to take.
##
## msg: An optional informational message by the plugin..
global flow_mod_success: event(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default="");
## Reports an error while installing a flow Rule.
##
## match: The ofp_match record which describes the flow to match.
##
## flow_mod: The openflow flow_mod record which describes the action to take.
##
## msg: Message to describe the event.
global flow_mod_failure: event(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default="");
# ###
# ### Low-level functions for cookie handling.
# ###
## Function to get the unique id out of a given cookie.
##
## cookie: The openflow match cookie.
##
## Returns: The cookie unique id.
global get_cookie_uid: function(cookie: count): count;
## Function to get the group id out of a given cookie.
##
## cookie: The openflow match cookie.
##
## Returns: The cookie group id.
global get_cookie_gid: function(cookie: count): count;
## Function to generate a new cookie using our group id.
##
## cookie: The openflow match cookie.
##
## Returns: The cookie group id.
global generate_cookie: function(cookie: count &default=0): count;
}
# the flow_mod function wrapper
function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool
{
if ( controller?$flow_mod )
return controller$flow_mod(controller$state, match, flow_mod);
else
return F;
}
function flow_clear(controller: Controller): bool
{
if ( controller?$flow_clear )
return controller$flow_clear(controller$state);
else
return F;
}
# local function to forge a flow_mod cookie for this framework.
# all flow entries from the openflow framework should have the
# 42 bit of the cookie set.
function generate_cookie(cookie: count &default=0): count
{
local c = BRO_COOKIE_ID * COOKIE_BID_START;
if ( cookie >= COOKIE_UID_SIZE )
Reporter::warning(fmt("The given cookie uid '%d' is > 32bit and will be discarded", cookie));
else
c += cookie;
return c;
}
# local function to check if a given flow_mod cookie is forged from this framework.
function is_valid_cookie(cookie: count): bool
{
if ( cookie / COOKIE_BID_START == BRO_COOKIE_ID )
return T;
Reporter::warning(fmt("The given Openflow cookie '%d' is not valid", cookie));
return F;
}
function get_cookie_uid(cookie: count): count
{
if( is_valid_cookie(cookie) )
return (cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START));
return INVALID_COOKIE;
}
function get_cookie_gid(cookie: count): count
{
if( is_valid_cookie(cookie) )
return (
(cookie - (COOKIE_BID_START * BRO_COOKIE_ID) -
(cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START))) /
COOKIE_GID_START
);
return INVALID_COOKIE;
}