mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
[ADD] status function to get flows from switch, error handling.
Added a function to receive status from the switch through the openflow controller. (not yet implemented anywhere) The flow_mod and flow_stats function now have default values which report that the function is not implemented when they're called but no plugin has registered its functions for them.
This commit is contained in:
parent
c705375537
commit
8e2c269c2e
4 changed files with 59 additions and 19 deletions
|
@ -212,7 +212,7 @@ export {
|
|||
## Body of reply to OFPST_FLOW request.
|
||||
type ofp_flow_stats: record {
|
||||
## Length of this entry
|
||||
length: count;
|
||||
_length: count;
|
||||
## ID of table flow came from.
|
||||
table_id: count;
|
||||
## Description of fields.
|
||||
|
@ -247,7 +247,24 @@ export {
|
|||
## the flow to delete, modify or add.
|
||||
##
|
||||
## Returns: T, if successful, else F.
|
||||
global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool;
|
||||
global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool
|
||||
&default=function(dpid: count, flow_mod:ofp_flow_mod): bool
|
||||
{
|
||||
Reporter::warning("Openflow::flow_mod function not implemented. Please load the right Openflow plugin");
|
||||
return F;
|
||||
};
|
||||
|
||||
## Function to get flow stats from the openflow switch/router
|
||||
##
|
||||
## dpid: The openflow controller datapath id.
|
||||
##
|
||||
## Returns: list with the installed flows and their statistics
|
||||
global flow_stats: function(dpid: count): vector of ofp_flow_stats
|
||||
&default=function(dpid: count): vector of ofp_flow_stats
|
||||
{
|
||||
Reporter::warning("Openflow::flow_stats function not implemented. Please load the right Openflow plugin");
|
||||
return vector();
|
||||
};
|
||||
|
||||
## Function to get the unique id out of a given cookie
|
||||
##
|
||||
|
@ -285,18 +302,28 @@ export {
|
|||
type FlowModFunc: function(dpid: count, flow_mod: ofp_flow_mod): bool;
|
||||
|
||||
|
||||
# Flow Statistics function prototype
|
||||
type FlowStatsFunc: function(dpid: count): vector of ofp_flow_stats;
|
||||
|
||||
|
||||
# Hook for registering openflow plugins
|
||||
global register_openflow_plugin: hook();
|
||||
|
||||
|
||||
# Function for plugins to call when they
|
||||
# register their flow_mod function.
|
||||
# Function for plugins to call when they register their flow_mod function.
|
||||
function register_openflow_mod_func(func: FlowModFunc)
|
||||
{
|
||||
flow_mod = func;
|
||||
}
|
||||
|
||||
|
||||
# Function for plugins to call when they register their flow_stats function.
|
||||
function register_openflow_stats_func(func: FlowStatsFunc)
|
||||
{
|
||||
flow_stats = func;
|
||||
}
|
||||
|
||||
|
||||
# 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.
|
||||
|
@ -316,7 +343,7 @@ 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 a valid", cookie));
|
||||
Reporter::warning(fmt("The given Openflow cookie '%d' is not valid", cookie));
|
||||
return F;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ const OFP_NO_BUFFER = 0xffffffff;
|
|||
|
||||
# Ryu ReST API flow_mod URL-path
|
||||
const RYU_FLOWENTRY_PATH = "/stats/flowentry/";
|
||||
# Ryu ReST API flow_stats URL-path
|
||||
const RYU_FLOWSTATS_PATH = "/stats/flow/";
|
||||
|
||||
|
||||
# Ryu ReST API action_output type.
|
||||
|
@ -85,7 +87,7 @@ hook register_openflow_plugin()
|
|||
# Check if the controller_ip has been redefined.
|
||||
if(controller_ip == "0.0.0.0")
|
||||
{
|
||||
Reporter::warning(fmt("The constant Openflow::controller_ip must be redefined"));
|
||||
Reporter::warning("The constant Openflow::controller_ip must be redefined");
|
||||
event Openflow::ryu_error(flow_mod, CONTROLLER_IP_REDEF, cat(controller_ip));
|
||||
return F;
|
||||
}
|
||||
|
@ -124,7 +126,7 @@ hook register_openflow_plugin()
|
|||
command_type = "delete";
|
||||
break;
|
||||
default:
|
||||
Reporter::warning(fmt("The given Openflow command type '%s' is not available", result$body));
|
||||
Reporter::warning(fmt("The given Openflow command type '%s' is not available", cat(flow_mod$command)));
|
||||
event Openflow::ryu_error(flow_mod, COMMAND_TYPE_NOT_AVAILABLE, cat(flow_mod$command));
|
||||
return F;
|
||||
}
|
||||
|
@ -150,4 +152,7 @@ hook register_openflow_plugin()
|
|||
return T;
|
||||
}
|
||||
);
|
||||
|
||||
# TODO: implement when a JSON -> record converter exists
|
||||
# register_openflow_stats_func();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,17 @@ export {
|
|||
##
|
||||
## returns: a JSON formatted string.
|
||||
global convert: function(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string;
|
||||
|
||||
global jsonToRecord: function(input: string): any;
|
||||
}
|
||||
|
||||
function jsonToRecord(input: string): any
|
||||
{
|
||||
local lhs: table[count] of string;
|
||||
lhs = split1(input, / /);
|
||||
for (i in lhs)
|
||||
print lhs[i];
|
||||
return lhs;
|
||||
}
|
||||
|
||||
function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string
|
||||
|
|
|
@ -19,9 +19,9 @@ const idle_timeout = 30;
|
|||
const hard_timeout = 0;
|
||||
const in_port = 3;
|
||||
const out_port = 1;
|
||||
|
||||
global delete_flow: bool = F;
|
||||
|
||||
|
||||
export {
|
||||
## Number of bytes transferred before shunting a flow.
|
||||
const size_threshold = 1024000 &redef;
|
||||
|
@ -35,22 +35,14 @@ export {
|
|||
global shunt_triggered: event(c: connection);
|
||||
}
|
||||
|
||||
|
||||
function size_callback(c: connection, cnt: count): interval
|
||||
{
|
||||
# print flow traffic.
|
||||
print fmt(
|
||||
"%s:%s <-> %s:%s reached %s/%s",
|
||||
c$id$orig_h,
|
||||
port_to_count(c$id$orig_p),
|
||||
c$id$resp_h,
|
||||
port_to_count(c$id$resp_p),
|
||||
c$orig$num_bytes_ip + c$resp$num_bytes_ip,
|
||||
size_threshold
|
||||
);
|
||||
# print Openflow::flow_stats(dpid);
|
||||
# if traffic exceeds the given threshold, remove flow.
|
||||
if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold )
|
||||
{
|
||||
# create openflow flow_mod add records from connection data and given default constants
|
||||
# create openflow flow_mod add records from connection data and give default constants
|
||||
local actions: vector of Openflow::ofp_action_output;
|
||||
local reverse_actions: vector of Openflow::ofp_action_output;
|
||||
actions[|actions|] = Openflow::ofp_action_output($_port=out_port);
|
||||
|
@ -120,21 +112,26 @@ function size_callback(c: connection, cnt: count): interval
|
|||
return poll_interval;
|
||||
}
|
||||
|
||||
|
||||
event connection_established(c: connection)
|
||||
{
|
||||
print fmt("new connection");
|
||||
ConnPolling::watch(c, size_callback, 0, 0secs);
|
||||
}
|
||||
|
||||
|
||||
event Openflow::flow_mod_success(flow_mod: Openflow::ofp_flow_mod, msg: string)
|
||||
{
|
||||
print fmt("succsess, %s", cat(flow_mod));
|
||||
}
|
||||
|
||||
|
||||
event Openflow::flow_mod_failure(flow_mod: Openflow::ofp_flow_mod, msg: string)
|
||||
{
|
||||
print fmt("failed, %s", cat(flow_mod));
|
||||
}
|
||||
|
||||
|
||||
event Openflow::ryu_error(flow_mod: Openflow::ofp_flow_mod, error: Openflow::RyuError, msg: string)
|
||||
{
|
||||
print fmt("ERROR: %s, msg: %s\n%s", error, msg, flow_mod);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue