mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +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:
@@ -139,18 +139,47 @@ lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg)
|
||||
send_features_request(sw, rconn);
|
||||
|
||||
if (cfg->default_flows) {
|
||||
const struct ofpbuf *b;
|
||||
enum ofputil_protocol usable_protocols;
|
||||
enum ofputil_protocol protocol;
|
||||
struct ofpbuf *msg = NULL;
|
||||
int ofp_version;
|
||||
int error = 0;
|
||||
size_t i;
|
||||
|
||||
LIST_FOR_EACH (b, list_node, cfg->default_flows) {
|
||||
struct ofpbuf *copy = ofpbuf_clone(b);
|
||||
int error = rconn_send(rconn, copy, NULL);
|
||||
if (error) {
|
||||
VLOG_INFO_RL(&rl, "%s: failed to queue default flows (%s)",
|
||||
rconn_get_name(rconn), strerror(error));
|
||||
ofpbuf_delete(copy);
|
||||
break;
|
||||
/* Figure out the initial protocol on the connection. */
|
||||
ofp_version = rconn_get_version(rconn);
|
||||
protocol = ofputil_protocol_from_ofp_version(ofp_version);
|
||||
|
||||
/* If the initial protocol isn't good enough for default_flows, then
|
||||
* pick one that will work and encode messages to set up that
|
||||
* protocol.
|
||||
*
|
||||
* This could be improved by actually negotiating a mutually acceptable
|
||||
* flow format with the switch, but that would require an asynchronous
|
||||
* state machine. This version ought to work fine in practice. */
|
||||
usable_protocols = ofputil_flow_mod_usable_protocols(
|
||||
cfg->default_flows, cfg->n_default_flows);
|
||||
if (!(protocol & usable_protocols)) {
|
||||
enum ofputil_protocol want = rightmost_1bit(usable_protocols);
|
||||
while (!error) {
|
||||
msg = ofputil_encode_set_protocol(protocol, want, &protocol);
|
||||
if (!msg) {
|
||||
break;
|
||||
}
|
||||
error = rconn_send(rconn, msg, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; !error && i < cfg->n_default_flows; i++) {
|
||||
msg = ofputil_encode_flow_mod(&cfg->default_flows[i], protocol);
|
||||
error = rconn_send(rconn, msg, NULL);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
VLOG_INFO_RL(&rl, "%s: failed to queue default flows (%s)",
|
||||
rconn_get_name(rconn), strerror(error));
|
||||
ofpbuf_delete(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return sw;
|
||||
|
Reference in New Issue
Block a user