2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-30 22:05:19 +00:00

Introduce ofputil_protocol, to abstract the protocol in use on a connection.

Open vSwitch already handles a few different protocol variations, but it
does so in a nonuniform manner:

  - OpenFlow 1.0 and NXM flow formats are distinguished using the NXFF_*
    constant values from nicira-ext.h.

  - The "flow_mod_table_id" feature setting is maintained in ofproto as
    part of an OpenFlow connection's (ofconn's) state.

There's no way to easily communicate this state among components.  It's
not much of a problem yet, but as more protocol support is added it seems
better to have an abstract, uniform way to represent protocol versions and
variants.  This commit implements that by introducing a new type
"enum ofputil_protocol".  Each ofputil_protocol value represents a variant
of a protocol version.  Each value is a separate bit, so a single enum
can also represent a set of protocols, which is often useful as well.

Reviewed-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ben Pfaff
2012-02-10 13:30:23 -08:00
parent 032f3fbd85
commit 27527aa09c
22 changed files with 969 additions and 512 deletions

View File

@@ -696,70 +696,49 @@ parse_ofp_actions(const char *s_, struct ofpbuf *actions)
}
/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
* (one of OFPFC_*) and appends the parsed OpenFlow message to 'packets'.
* '*cur_format' should initially contain the flow format currently configured
* on the connection; this function will add a message to change the flow
* format and update '*cur_format', if this is necessary to add the parsed
* flow. */
* (one of OFPFC_*) into 'fm'. */
void
parse_ofp_flow_mod_str(struct list *packets, enum nx_flow_format *cur_format,
bool *flow_mod_table_id, const char *string,
parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string,
uint16_t command, bool verbose)
{
enum nx_flow_format min_format, next_format;
struct cls_rule rule_copy;
struct ofpbuf *ofm;
struct ofputil_flow_mod fm;
parse_ofp_str(&fm, command, string, verbose);
min_format = ofputil_min_flow_format(&fm.cr);
if (command != OFPFC_ADD && fm.cookie_mask != htonll(0)) {
min_format = NXFF_NXM;
}
next_format = MAX(*cur_format, min_format);
if (next_format != *cur_format) {
struct ofpbuf *sff = ofputil_make_set_flow_format(next_format);
list_push_back(packets, &sff->list_node);
*cur_format = next_format;
}
parse_ofp_str(fm, command, string, verbose);
/* Normalize a copy of the rule. This ensures that non-normalized flows
* get logged but doesn't affect what gets sent to the switch, so that the
* switch can do whatever it likes with the flow. */
rule_copy = fm.cr;
ofputil_normalize_rule(&rule_copy, next_format);
if (fm.table_id != 0xff && !*flow_mod_table_id) {
struct ofpbuf *sff = ofputil_make_flow_mod_table_id(true);
list_push_back(packets, &sff->list_node);
*flow_mod_table_id = true;
}
ofm = ofputil_encode_flow_mod(&fm, *cur_format, *flow_mod_table_id);
list_push_back(packets, &ofm->list_node);
rule_copy = fm->cr;
ofputil_normalize_rule(&rule_copy);
}
/* Similar to parse_ofp_flow_mod_str(), except that the string is read from
* 'stream' and the command is always OFPFC_ADD. Returns false if end-of-file
* is reached before reading a flow, otherwise true. */
bool
parse_ofp_flow_mod_file(struct list *packets,
enum nx_flow_format *cur, bool *flow_mod_table_id,
FILE *stream, uint16_t command)
void
parse_ofp_flow_mod_file(const char *file_name, uint16_t command,
struct ofputil_flow_mod **fms, size_t *n_fms)
{
size_t allocated_fms;
FILE *stream;
struct ds s;
bool ok;
stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
if (stream == NULL) {
ovs_fatal(errno, "%s: open", file_name);
}
allocated_fms = *n_fms;
ds_init(&s);
ok = ds_get_preprocessed_line(&s, stream) == 0;
if (ok) {
parse_ofp_flow_mod_str(packets, cur, flow_mod_table_id,
ds_cstr(&s), command, true);
while (!ds_get_preprocessed_line(&s, stream)) {
if (*n_fms >= allocated_fms) {
*fms = x2nrealloc(*fms, &allocated_fms, sizeof **fms);
}
parse_ofp_flow_mod_str(&(*fms)[*n_fms], ds_cstr(&s), command, false);
*n_fms += 1;
}
ds_destroy(&s);
return ok;
if (stream != stdin) {
fclose(stream);
}
}
void