Skip to content

Commit

Permalink
ovs-ofctl: Add bundle support and unit testing.
Browse files Browse the repository at this point in the history
All existing ovs-ofctl flow mod commands now take an optional
'--bundle' argument, which executes the flow mods as a single
transaction.  OpenFlow 1.4+ is implicitly assumed when '--bundle' is
specified.

ovs-ofctl 'add-flow' and 'add-flows' commands now accept flow
specifications that start with an optional 'add', 'modify', 'delete',
'modify_strict', or 'delete_strict' keyword, so that arbitrary flow
table modifications may be specified.  For backwards compatibility, a
missing keyword is treated as an 'add'.  With the new '--bundle'
option all the modifications are executed as a single transaction
using an OpenFlow 1.4 bundle.

OpenFlow 1.4 requires bundles to support at least flow and port mods.
This implementation does not yet support port mods in bundles.

Another restriction is that the atomic transactions are not yet
supported.

Signed-off-by: Jarno Rajahalme <[email protected]>
Acked-by: Ben Pfaff <[email protected]>
  • Loading branch information
Jarno Rajahalme committed Jun 10, 2015
1 parent 4fcb208 commit db5076e
Show file tree
Hide file tree
Showing 14 changed files with 807 additions and 49 deletions.
19 changes: 18 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Post-v2.3.0
---------------------
- Added support for SFQ, FQ_CoDel and CoDel qdiscs.
- Added support for SFQ, FQ_CoDel and CoDel qdiscs.
- Add bash command-line completion support for ovs-vsctl Please check
utilities/ovs-command-compgen.INSTALL.md for how to use.
- The MAC learning feature now includes per-port fairness to mitigate
Expand All @@ -27,6 +27,11 @@ Post-v2.3.0
commands are now redundant and will be removed in a future
release. See ovs-vswitchd(8) for details.
- OpenFlow:
* OpenFlow 1.4 bundles are now supported, but for flow mod
messages only. 'atomic' bundles are not yet supported, and
'ordered' bundles are trivially supported, as all bundled
messages are executed in the order they were added to the
bundle regardless of the presence of the 'ordered' flag.
* IPv6 flow label and neighbor discovery fields are now modifiable.
* OpenFlow 1.5 extended registers are now supported.
* The OpenFlow 1.5 actset_output field is now supported.
Expand All @@ -41,6 +46,18 @@ Post-v2.3.0
* A new Netronome extension to OpenFlow 1.5+ allows control over the
fields hashed for OpenFlow select groups. See "selection_method" and
related options in ovs-ofctl(8) for details.
- ovs-ofctl has a new '--bundle' option that makes the flow mod commands
('add-flow', 'add-flows', 'mod-flows', 'del-flows', and 'replace-flows')
use an OpenFlow 1.4 bundle to operate the modifications as a single
transaction. If any of the flow mods in a transaction fail, none of
them are executed.
- ovs-ofctl 'add-flow' and 'add-flows' commands now accept arbitrary flow
mods as an input by allowing the flow specification to start with an
explicit 'add', 'modify', 'modify_strict', 'delete', or 'delete_strict'
keyword. A missing keyword is treated as 'add', so this is fully
backwards compatible. With the new '--bundle' option all the flow mods
are executed as a single transaction using the new OpenFlow 1.4 bundles
support.
- ovs-pki: Changed message digest algorithm from MD5 to SHA-1 because
MD5 is no longer secure and some operating systems have started to disable
it in OpenSSL.
Expand Down
3 changes: 3 additions & 0 deletions include/openvswitch/vconn.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ int vconn_transact(struct vconn *, struct ofpbuf *, struct ofpbuf **);
int vconn_transact_noreply(struct vconn *, struct ofpbuf *, struct ofpbuf **);
int vconn_transact_multiple_noreply(struct vconn *, struct ovs_list *requests,
struct ofpbuf **replyp);
int vconn_bundle_transact(struct vconn *, struct ovs_list *requests,
uint16_t bundle_flags,
void (*error_reporter)(const struct ofp_header *));

void vconn_run(struct vconn *);
void vconn_run_wait(struct vconn *);
Expand Down
40 changes: 38 additions & 2 deletions lib/ofp-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,29 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,

*usable_protocols = OFPUTIL_P_ANY;

if (command == -2) {
size_t len;

string += strspn(string, " \t\r\n"); /* Skip white space. */
len = strcspn(string, ", \t\r\n"); /* Get length of the first token. */

if (!strncmp(string, "add", len)) {
command = OFPFC_ADD;
} else if (!strncmp(string, "delete", len)) {
command = OFPFC_DELETE;
} else if (!strncmp(string, "delete_strict", len)) {
command = OFPFC_DELETE_STRICT;
} else if (!strncmp(string, "modify", len)) {
command = OFPFC_MODIFY;
} else if (!strncmp(string, "modify_strict", len)) {
command = OFPFC_MODIFY_STRICT;
} else {
len = 0;
command = OFPFC_ADD;
}
string += len;
}

switch (command) {
case -1:
fields = F_OUT_PORT;
Expand Down Expand Up @@ -486,6 +509,10 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,
* constant for 'command'. To parse syntax for an OFPST_FLOW or
* OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'.
*
* If 'command' is given as -2, 'str_' may begin with a command name ("add",
* "modify", "delete", "modify_strict", or "delete_strict"). A missing command
* name is treated as "add".
*
* Returns NULL if successful, otherwise a malloc()'d string describing the
* error. The caller is responsible for freeing the returned string. */
char * OVS_WARN_UNUSED_RESULT
Expand Down Expand Up @@ -818,14 +845,19 @@ parse_flow_monitor_request(struct ofputil_flow_monitor_request *fmr,
/* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
* (one of OFPFC_*) into 'fm'.
*
* If 'command' is given as -2, 'string' may begin with a command name ("add",
* "modify", "delete", "modify_strict", or "delete_strict"). A missing command
* name is treated as "add".
*
* Returns NULL if successful, otherwise a malloc()'d string describing the
* error. The caller is responsible for freeing the returned string. */
char * OVS_WARN_UNUSED_RESULT
parse_ofp_flow_mod_str(struct ofputil_flow_mod *fm, const char *string,
uint16_t command,
int command,
enum ofputil_protocol *usable_protocols)
{
char *error = parse_ofp_str(fm, command, string, usable_protocols);

if (!error) {
/* Normalize a copy of the match. This ensures that non-normalized
* flows get logged but doesn't affect what gets sent to the switch, so
Expand Down Expand Up @@ -883,10 +915,14 @@ parse_ofp_table_mod(struct ofputil_table_mod *tm, const char *table_id,
* type (one of OFPFC_*). Stores each flow_mod in '*fm', an array allocated
* on the caller's behalf, and the number of flow_mods in '*n_fms'.
*
* If 'command' is given as -2, each line may start with a command name
* ("add", "modify", "delete", "modify_strict", or "delete_strict"). A missing
* command name is treated as "add".
*
* Returns NULL if successful, otherwise a malloc()'d string describing the
* error. The caller is responsible for freeing the returned string. */
char * OVS_WARN_UNUSED_RESULT
parse_ofp_flow_mod_file(const char *file_name, uint16_t command,
parse_ofp_flow_mod_file(const char *file_name, int command,
struct ofputil_flow_mod **fms, size_t *n_fms,
enum ofputil_protocol *usable_protocols)
{
Expand Down
6 changes: 3 additions & 3 deletions lib/ofp-parse.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
* Copyright (c) 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -42,7 +42,7 @@ char *parse_ofp_str(struct ofputil_flow_mod *, int command, const char *str_,
OVS_WARN_UNUSED_RESULT;

char *parse_ofp_flow_mod_str(struct ofputil_flow_mod *, const char *string,
uint16_t command,
int command,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;

Expand All @@ -51,7 +51,7 @@ char *parse_ofp_table_mod(struct ofputil_table_mod *,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;

char *parse_ofp_flow_mod_file(const char *file_name, uint16_t command,
char *parse_ofp_flow_mod_file(const char *file_name, int command,
struct ofputil_flow_mod **fms, size_t *n_fms,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
Expand Down
30 changes: 30 additions & 0 deletions lib/ofp-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -8695,6 +8695,36 @@ ofputil_decode_bundle_ctrl(const struct ofp_header *oh,
return 0;
}

struct ofpbuf *
ofputil_encode_bundle_ctrl_request(enum ofp_version ofp_version,
struct ofputil_bundle_ctrl_msg *bc)
{
struct ofpbuf *request;
struct ofp14_bundle_ctrl_msg *m;

switch (ofp_version) {
case OFP10_VERSION:
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
ovs_fatal(0, "bundles need OpenFlow 1.4 or later "
"(\'-O OpenFlow14\')");
case OFP14_VERSION:
case OFP15_VERSION:
request = ofpraw_alloc(OFPRAW_OFPT14_BUNDLE_CONTROL, ofp_version, 0);
m = ofpbuf_put_zeros(request, sizeof *m);

m->bundle_id = htonl(bc->bundle_id);
m->type = htons(bc->type);
m->flags = htons(bc->flags);
break;
default:
OVS_NOT_REACHED();
}

return request;
}

struct ofpbuf *
ofputil_encode_bundle_ctrl_reply(const struct ofp_header *oh,
struct ofputil_bundle_ctrl_msg *msg)
Expand Down
2 changes: 2 additions & 0 deletions lib/ofp-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,8 @@ enum ofptype;
enum ofperr ofputil_decode_bundle_ctrl(const struct ofp_header *,
struct ofputil_bundle_ctrl_msg *);

struct ofpbuf *ofputil_encode_bundle_ctrl_request(enum ofp_version,
struct ofputil_bundle_ctrl_msg *);
struct ofpbuf *ofputil_encode_bundle_ctrl_reply(const struct ofp_header *,
struct ofputil_bundle_ctrl_msg *);

Expand Down
7 changes: 7 additions & 0 deletions lib/ofp-version-opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ mask_allowed_ofp_versions(uint32_t bitmap)
allowed_versions &= bitmap;
}

void
add_allowed_ofp_versions(uint32_t bitmap)
{
assert_single_threaded();
allowed_versions |= bitmap;
}

void
ofp_version_usage(void)
{
Expand Down
1 change: 1 addition & 0 deletions lib/ofp-version-opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
uint32_t get_allowed_ofp_versions(void);
void set_allowed_ofp_versions(const char *string);
void mask_allowed_ofp_versions(uint32_t);
void add_allowed_ofp_versions(uint32_t);
void ofp_version_usage(void);

#endif
Loading

0 comments on commit db5076e

Please sign in to comment.