mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
a few small fixes to openflow
*rename module from Openflow to OpenFlow *add match_conn function to convert conn_id to openflow match *add a few things back into the openflow records like... table_id *and - a test
This commit is contained in:
parent
70f6635cb1
commit
46058d0b02
6 changed files with 120 additions and 19 deletions
|
@ -1,7 +1,7 @@
|
|||
# All types/constants not specific to Openflow will be defined here
|
||||
# unitl they somehow get into bro.
|
||||
|
||||
module Openflow;
|
||||
module OpenFlow;
|
||||
|
||||
# Some cookie specific constants.
|
||||
# first 24 bits
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
##! for shunting, please look at the PACF framework, which provides higher
|
||||
##! level functions and can use the OpenFlow framework as a backend.
|
||||
|
||||
module Openflow;
|
||||
module OpenFlow;
|
||||
|
||||
@load ./consts
|
||||
@load ./types
|
||||
|
@ -50,6 +50,16 @@ export {
|
|||
## 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.
|
||||
# ###
|
||||
|
@ -76,6 +86,7 @@ export {
|
|||
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
|
||||
{
|
||||
|
@ -93,6 +104,49 @@ function flow_clear(controller: Controller): bool
|
|||
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=orig_h,
|
||||
$tp_src=orig_p,
|
||||
$nw_dst=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.
|
||||
|
@ -131,7 +185,7 @@ function get_cookie_gid(cookie: count): count
|
|||
{
|
||||
if( is_valid_cookie(cookie) )
|
||||
return (
|
||||
(cookie - (COOKIE_BID_START * BRO_COOKIE_ID) -
|
||||
(cookie - (COOKIE_BID_START * BRO_COOKIE_ID) -
|
||||
(cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START))) /
|
||||
COOKIE_GID_START
|
||||
);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
@load base/utils/exec
|
||||
@load base/utils/json
|
||||
|
||||
module Openflow;
|
||||
module OpenFlow;
|
||||
|
||||
export {
|
||||
redef enum Plugin += {
|
||||
|
@ -16,17 +16,17 @@ export {
|
|||
##
|
||||
## host_port: Controller listen port.
|
||||
##
|
||||
## dpid: Openflow switch datapath id.
|
||||
## dpid: OpenFlow switch datapath id.
|
||||
##
|
||||
## Returns: Openflow::Controller record
|
||||
global ryu_new: function(host: addr, host_port: count, dpid: count): Openflow::Controller;
|
||||
## Returns: OpenFlow::Controller record
|
||||
global ryu_new: function(host: addr, host_port: count, dpid: count): OpenFlow::Controller;
|
||||
|
||||
redef record ControllerState += {
|
||||
## Controller ip.
|
||||
ryu_host: addr &optional;
|
||||
## Controller listen port.
|
||||
ryu_port: count &optional;
|
||||
## Openflow switch datapath id.
|
||||
## OpenFlow switch datapath id.
|
||||
ryu_dpid: count &optional;
|
||||
## Enable debug mode - output JSON to stdout; do not perform actions
|
||||
ryu_debug: bool &default=F;
|
||||
|
@ -58,7 +58,7 @@ type ryu_ofp_flow_mod: record {
|
|||
hard_timeout: count &optional;
|
||||
priority: count &optional;
|
||||
flags: count &optional;
|
||||
match: Openflow::ofp_match;
|
||||
match: OpenFlow::ofp_match;
|
||||
actions: vector of ryu_flow_action;
|
||||
};
|
||||
|
||||
|
@ -72,7 +72,7 @@ const ryu_url: table[ofp_flow_mod_command] of string = {
|
|||
};
|
||||
|
||||
# Ryu flow_mod function
|
||||
function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_mod: Openflow::ofp_flow_mod): bool
|
||||
function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool
|
||||
{
|
||||
if ( state$_plugin != RYU )
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m
|
|||
# Generate our ryu_flow_mod record for the ReST API call.
|
||||
local mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod(
|
||||
$dpid=state$ryu_dpid,
|
||||
$cookie=Openflow::generate_cookie(flow_mod$cookie),
|
||||
$cookie=OpenFlow::generate_cookie(flow_mod$cookie),
|
||||
$idle_timeout=flow_mod$idle_timeout,
|
||||
$hard_timeout=flow_mod$hard_timeout,
|
||||
$priority=flow_mod$priority,
|
||||
|
@ -105,7 +105,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m
|
|||
command_type = ryu_url[flow_mod$command];
|
||||
else
|
||||
{
|
||||
Reporter::warning(fmt("The given Openflow command type '%s' is not available", cat(flow_mod$command)));
|
||||
Reporter::warning(fmt("The given OpenFlow command type '%s' is not available", cat(flow_mod$command)));
|
||||
return F;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m
|
|||
{
|
||||
print url;
|
||||
print to_json(mod);
|
||||
event Openflow::flow_mod_success(match, flow_mod);
|
||||
event OpenFlow::flow_mod_success(match, flow_mod);
|
||||
return T;
|
||||
}
|
||||
|
||||
|
@ -130,11 +130,11 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m
|
|||
when ( local result = ActiveHTTP::request(request) )
|
||||
{
|
||||
if(result$code == 200)
|
||||
event Openflow::flow_mod_success(match, flow_mod, result$body);
|
||||
event OpenFlow::flow_mod_success(match, flow_mod, result$body);
|
||||
else
|
||||
{
|
||||
Reporter::warning(fmt("Flow modification failed with error: %s", result$body));
|
||||
event Openflow::flow_mod_failure(match, flow_mod, result$body);
|
||||
event OpenFlow::flow_mod_failure(match, flow_mod, result$body);
|
||||
return F;
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m
|
|||
return T;
|
||||
}
|
||||
|
||||
function ryu_flow_clear(state: Openflow::ControllerState): bool
|
||||
function ryu_flow_clear(state: OpenFlow::ControllerState): bool
|
||||
{
|
||||
local url=cat("http://", cat(state$ryu_host), ":", cat(state$ryu_port), RYU_FLOWENTRY_PATH, "clear", "/", state$ryu_dpid);
|
||||
|
||||
|
@ -165,8 +165,8 @@ function ryu_flow_clear(state: Openflow::ControllerState): bool
|
|||
}
|
||||
|
||||
# Ryu controller constructor
|
||||
function ryu_new(host: addr, host_port: count, dpid: count): Openflow::Controller
|
||||
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],
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module Openflow;
|
||||
module OpenFlow;
|
||||
|
||||
@load ./consts
|
||||
|
||||
|
@ -39,6 +39,8 @@ export {
|
|||
nw_tos: count &optional;
|
||||
# IP protocol or lower 8 bits of ARP opcode.
|
||||
nw_proto: count &optional;
|
||||
# At the moment, we store both v4 and v6 in the same fields.
|
||||
# This is not how OpenFlow does it, we might want to change that...
|
||||
# IP source address.
|
||||
nw_src: addr &optional;
|
||||
# IP destination address.
|
||||
|
@ -56,6 +58,9 @@ export {
|
|||
# it so we always can identify our flows...
|
||||
cookie: count; # &default=BRO_COOKIE_ID * COOKIE_BID_START;
|
||||
# Flow actions
|
||||
## Table to put the flow in. OFPTT_ALL can be used for delete,
|
||||
## to delete flows from all matching tables.
|
||||
table_id: count &optional;
|
||||
## One of OFPFC_*.
|
||||
command: ofp_flow_mod_command; # &default=OFPFC_ADD;
|
||||
## Idle time before discarding (seconds).
|
||||
|
@ -64,6 +69,9 @@ export {
|
|||
hard_timeout: count &default=0;
|
||||
## Priority level of flow entry.
|
||||
priority: count &default=0;
|
||||
## For OFPFC_DELETE* commands, require matching entried to include
|
||||
## this as an output port. OFPP_ANY means no restrictions.
|
||||
out_group: count &optional;
|
||||
## Bitmap of the OFPFF_* flags
|
||||
flags: count &default=0;
|
||||
## Output ports to send data to.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue