mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
194 lines
5.4 KiB
Text
194 lines
5.4 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="");
|
|
|
|
## Convert a conn_id record into an ofp_match record that can be used to
|
|
## create match objects for OpenFlow.
|
|
##
|
|
## id: the conn_id record that describes the record.
|
|
##
|
|
## reverse: reverse the sources and destinations when creating the match record (default F)
|
|
##
|
|
## Returns: ofp_match object for the conn_id record.
|
|
global match_conn: function(id: conn_id, reverse: bool &default=F): ofp_match;
|
|
|
|
# ###
|
|
# ### 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;
|
|
}
|
|
|
|
function match_conn(id: conn_id, reverse: bool &default=F): ofp_match
|
|
{
|
|
local dl_type = ETH_IPv4;
|
|
local proto = IP_TCP;
|
|
|
|
local orig_h: addr;
|
|
local orig_p: port;
|
|
local resp_h: addr;
|
|
local resp_p: port;
|
|
|
|
if ( reverse == F )
|
|
{
|
|
orig_h = id$orig_h;
|
|
orig_p = id$orig_p;
|
|
resp_h = id$resp_h;
|
|
resp_p = id$resp_p;
|
|
}
|
|
else
|
|
{
|
|
orig_h = id$resp_h;
|
|
orig_p = id$resp_p;
|
|
resp_h = id$orig_h;
|
|
resp_p = id$resp_p;
|
|
}
|
|
|
|
if ( is_v6_addr(orig_h) )
|
|
dl_type = ETH_IPv6;
|
|
|
|
if ( is_udp_port(orig_p) )
|
|
proto = IP_UDP;
|
|
else if ( is_icmp_port(orig_p) )
|
|
proto = IP_ICMP;
|
|
|
|
return ofp_match(
|
|
$dl_type=dl_type,
|
|
$nw_proto=proto,
|
|
$nw_src=addr_to_subnet(orig_h),
|
|
$tp_src=orig_p,
|
|
$nw_dst=addr_to_subnet(resp_h),
|
|
$tp_dst=resp_p
|
|
);
|
|
}
|
|
|
|
# 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;
|
|
}
|