The table for 1.3 is the same as the one shown above for 1.2.
+OpenFlow 1.4
+------------
+
+OpenFlow 1.4 does not change flow_mod semantics.
+
+
OFPT_PACKET_IN
==============
Q: What versions of OpenFlow does Open vSwitch support?
-A: Open vSwitch 1.9 and earlier support only OpenFlow 1.0 (plus
- extensions that bring in many of the features from later versions
- of OpenFlow).
+A: The following table lists the versions of OpenFlow supported by
+ each version of Open vSwitch:
- Open vSwitch 1.10 and later have experimental support for OpenFlow
- 1.2 and 1.3. On these versions of Open vSwitch, the following
- command enables OpenFlow 1.0, 1.2, and 1.3 on bridge br0:
+ Open vSwitch OF1.0 OF1.1 OF1.2 OF1.3 OF1.4
+ =============== ===== ===== ===== ===== =====
+ 1.9 and earlier yes --- --- --- ---
+ 1.10 yes --- [*] [*] ---
+ 1.11 yes --- [*] [*] ---
+ 2.0 yes [*] [*] [*] ---
+ 2.1 yes [*] [*] [*] ---
+ 2.2 yes [*] [*] [*] [*]
- ovs-vsctl set bridge br0 protocols=OpenFlow10,OpenFlow12,OpenFlow13
+ [*] Supported, with one or more missing features.
- Open vSwitch version 2.0 and later will have experimental support
- for OpenFlow 1.1, 1.2, and 1.3. On these versions of Open vSwitch,
- the following command enables OpenFlow 1.0, 1.1, 1.2, and 1.3 on
- bridge br0:
+ Because of missing features, OpenFlow 1.1, 1.2, 1.3, and 1.4 must
+ be enabled manually. The following command enables OpenFlow 1.0,
+ 1.1, 1.2, and 1.3 on bridge br0:
ovs-vsctl set bridge br0 protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13
ovs-ofctl -O OpenFlow13 dump-flows br0
- Support for OpenFlow 1.1, 1.2, and 1.3 is still incomplete. Work
- to be done is tracked in OPENFLOW-1.1+ in the Open vSwitch sources
- (also via http://openvswitch.org/development/openflow-1-x-plan/).
- When support for a given OpenFlow version is solidly implemented,
- Open vSwitch will enable that version by default.
+ OPENFLOW-1.1+ in the Open vSwitch source tree tracks support for
+ OpenFlow 1.1 and later features. When support for a given OpenFlow
+ version is solidly implemented, Open vSwitch will enable that
+ version by default.
Q: Does Open vSwitch support MPLS?
OpenFlow 1.1+ support in Open vSwitch
=====================================
-Open vSwitch support for OpenFlow 1.1, 1.2, and 1.3 is a work in
+Open vSwitch support for OpenFlow 1.1 and beyond is a work in
progress. This file describes the work still to be done.
The Plan
version_map = {"1.0": 0x01,
"1.1": 0x02,
"1.2": 0x03,
- "1.3": 0x04}
+ "1.3": 0x04,
+ "1.4": 0x05}
version_reverse_map = dict((v, k) for (k, v) in version_map.iteritems())
token = None
"1.2": (OFP12_VERSION, OFP12_VERSION),
"1.3": (OFP13_VERSION, OFP13_VERSION),
"1.4": (OFP14_VERSION, OFP14_VERSION),
- "1.0+": (OFP10_VERSION, OFP13_VERSION),
- "1.1+": (OFP11_VERSION, OFP13_VERSION),
- "1.2+": (OFP12_VERSION, OFP13_VERSION),
- "1.3+": (OFP13_VERSION, OFP13_VERSION),
+ "1.0+": (OFP10_VERSION, OFP14_VERSION),
+ "1.1+": (OFP11_VERSION, OFP14_VERSION),
+ "1.2+": (OFP12_VERSION, OFP14_VERSION),
+ "1.3+": (OFP13_VERSION, OFP14_VERSION),
"1.4+": (OFP14_VERSION, OFP14_VERSION),
"1.0-1.1": (OFP10_VERSION, OFP11_VERSION),
"1.0-1.2": (OFP10_VERSION, OFP12_VERSION),
OFP10_VERSION = 0x01,
OFP11_VERSION = 0x02,
OFP12_VERSION = 0x03,
- OFP13_VERSION = 0x04
+ OFP13_VERSION = 0x04,
+ OFP14_VERSION = 0x05
/* When we add real support for these versions, add them to the enum so
* that we get compiler warnings everywhere we might forget to provide
* support. Until then, keep them as macros to avoid those warnings. */
-#define OFP14_VERSION 0x05
#define OFP15_VERSION 0x06
};
return &ofperr_of12;
case OFP13_VERSION:
return &ofperr_of13;
+ case OFP14_VERSION:
+ return &ofperr_of14;
default:
return NULL;
}
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
return type == OFPT11_STATS_REQUEST;
}
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
return type == OFPT11_STATS_REPLY;
}
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
if (hdrs->type == OFPT11_STATS_REQUEST ||
hdrs->type == OFPT11_STATS_REPLY) {
return (hdrs->stat == OFPST_VENDOR
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
ovs_assert(hdrs.type == OFPT11_STATS_REQUEST);
hdrs.type = OFPT11_STATS_REPLY;
break;
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
return &((struct ofp11_stats_msg *) oh)->flags;
default:
OVS_NOT_REACHED();
OFPRAW_OFPST11_TABLE_REPLY,
/* OFPST 1.2 (3): struct ofp12_table_stats[]. */
OFPRAW_OFPST12_TABLE_REPLY,
- /* OFPST 1.3 (3): struct ofp13_table_stats[]. */
+ /* OFPST 1.3+ (3): struct ofp13_table_stats[]. */
OFPRAW_OFPST13_TABLE_REPLY,
/* OFPST 1.0 (4): struct ofp10_port_stats_request. */
/* OFPST 1.1-1.2 (6): uint8_t[8][]. */
OFPRAW_OFPST11_GROUP_REPLY,
- /* OFPST 1.3 (6): uint8_t[8][]. */
+ /* OFPST 1.3+ (6): uint8_t[8][]. */
OFPRAW_OFPST13_GROUP_REPLY,
/* OFPST 1.1+ (7): void. */
case OFP12_VERSION:
break;
case OFP13_VERSION:
+ case OFP14_VERSION:
return; /* no ports in ofp13_switch_features */
default:
OVS_NOT_REACHED();
int verbosity)
{
switch ((enum ofp_version)oh->version) {
+ case OFP14_VERSION:
case OFP13_VERSION:
ofp_print_ofpst_table_reply13(string, oh, verbosity);
break;
/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
case OFPUTIL_P_OF12_OXM:
case OFPUTIL_P_OF13_OXM:
+ case OFPUTIL_P_OF14_OXM:
return NXM_TYPICAL_LEN;
default:
case OFPUTIL_P_OF12_OXM:
case OFPUTIL_P_OF13_OXM:
+ case OFPUTIL_P_OF14_OXM:
return oxm_put_match(b, match);
}
#define N_PROTO_ABBREVS ARRAY_SIZE(proto_abbrevs)
enum ofputil_protocol ofputil_flow_dump_protocols[] = {
+ OFPUTIL_P_OF14_OXM,
OFPUTIL_P_OF13_OXM,
OFPUTIL_P_OF12_OXM,
OFPUTIL_P_OF11_STD,
return OFPUTIL_P_OF12_OXM;
case OFP13_VERSION:
return OFPUTIL_P_OF13_OXM;
+ case OFP14_VERSION:
+ return OFPUTIL_P_OF14_OXM;
default:
return 0;
}
return OFP12_VERSION;
case OFPUTIL_P_OF13_OXM:
return OFP13_VERSION;
+ case OFPUTIL_P_OF14_OXM:
+ return OFP14_VERSION;
}
OVS_NOT_REACHED();
case OFPUTIL_P_OF13_OXM:
return OFPUTIL_P_OF13_OXM;
+ case OFPUTIL_P_OF14_OXM:
+ return OFPUTIL_P_OF14_OXM;
+
default:
OVS_NOT_REACHED();
}
case OFPUTIL_P_OF13_OXM:
return ofputil_protocol_set_tid(OFPUTIL_P_OF13_OXM, tid);
+ case OFPUTIL_P_OF14_OXM:
+ return ofputil_protocol_set_tid(OFPUTIL_P_OF14_OXM, tid);
+
default:
OVS_NOT_REACHED();
}
case OFPUTIL_P_OF13_OXM:
return "OXM-OpenFlow13";
+
+ case OFPUTIL_P_OF14_OXM:
+ return "OXM-OpenFlow14";
}
/* Check abbreviations. */
if (!strcasecmp(s, "OpenFlow13")) {
return OFP13_VERSION;
}
+ if (!strcasecmp(s, "OpenFlow14")) {
+ return OFP14_VERSION;
+ }
return 0;
}
return "OpenFlow12";
case OFP13_VERSION:
return "OpenFlow13";
+ case OFP14_VERSION:
+ return "OpenFlow14";
default:
OVS_NOT_REACHED();
}
case OFPUTIL_P_OF11_STD:
case OFPUTIL_P_OF12_OXM:
case OFPUTIL_P_OF13_OXM:
+ case OFPUTIL_P_OF14_OXM:
/* There is only one variant of each OpenFlow 1.1+ protocol, and we
* verified above that we're not trying to change versions. */
OVS_NOT_REACHED();
switch (protocol) {
case OFPUTIL_P_OF11_STD:
case OFPUTIL_P_OF12_OXM:
- case OFPUTIL_P_OF13_OXM: {
+ case OFPUTIL_P_OF13_OXM:
+ case OFPUTIL_P_OF14_OXM: {
struct ofp11_flow_mod *ofm;
int tailroom;
switch (protocol) {
case OFPUTIL_P_OF11_STD:
case OFPUTIL_P_OF12_OXM:
- case OFPUTIL_P_OF13_OXM: {
+ case OFPUTIL_P_OF13_OXM:
+ case OFPUTIL_P_OF14_OXM: {
struct ofp11_flow_stats_request *ofsr;
raw = (fsr->aggregate
switch (protocol) {
case OFPUTIL_P_OF11_STD:
case OFPUTIL_P_OF12_OXM:
- case OFPUTIL_P_OF13_OXM: {
+ case OFPUTIL_P_OF13_OXM:
+ case OFPUTIL_P_OF14_OXM: {
struct ofp12_flow_removed *ofr;
msg = ofpraw_alloc_xid(OFPRAW_OFPT11_FLOW_REMOVED,
case OFPUTIL_P_OF12_OXM:
case OFPUTIL_P_OF13_OXM:
+ case OFPUTIL_P_OF14_OXM:
packet = ofputil_encode_ofp12_packet_in(pin, protocol);
break;
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
return sizeof(struct ofp11_port);
default:
OVS_NOT_REACHED();
break;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
+
default:
OVS_NOT_REACHED();
}
break;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
+
default:
OVS_NOT_REACHED();
}
case OFP12_VERSION:
case OFP13_VERSION:
return OFPC_COMMON | OFPC12_PORT_BLOCKED;
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
default:
/* Caller needs to check osf->header.version itself */
return 0;
raw = OFPRAW_OFPT11_FEATURES_REPLY;
break;
case OFP13_VERSION:
+ case OFP14_VERSION:
raw = OFPRAW_OFPT13_FEATURES_REPLY;
break;
default:
osf->actions = encode_action_bits(features->actions, of10_action_bits);
break;
case OFP13_VERSION:
+ case OFP14_VERSION:
osf->auxiliary_id = features->auxiliary_id;
/* fall through */
case OFP11_VERSION:
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
raw = OFPRAW_OFPT11_PORT_STATUS;
break;
opm->advertise = netdev_port_features_to_ofp11(pm->advertise);
break;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
default:
OVS_NOT_REACHED();
}
otm->config = htonl(pm->config);
break;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
default:
OVS_NOT_REACHED();
}
break;
case OFP13_VERSION:
+ case OFP14_VERSION:
ofputil_put_ofp13_table_stats(&stats[i], reply);
break;
case OFP11_VERSION:
case OFP12_VERSION:
- case OFP13_VERSION: {
+ case OFP13_VERSION:
+ case OFP14_VERSION:{
struct ofp11_packet_out *opo;
size_t len;
enum ofpraw type;
switch (ofp_version) {
+ case OFP14_VERSION:
case OFP13_VERSION:
case OFP12_VERSION:
case OFP11_VERSION:
const struct ofp11_port *op = ofpbuf_try_pull(b, sizeof *op);
return op ? ofputil_decode_ofp11_port(pp, op) : EOF;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
default:
OVS_NOT_REACHED();
}
}
case OFP11_VERSION:
case OFP12_VERSION:
- case OFP13_VERSION: {
+ case OFP13_VERSION:
+ case OFP14_VERSION:{
struct ofp11_port_stats_request *req;
request = ofpraw_alloc(OFPRAW_OFPST11_PORT_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
break;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
+
default:
OVS_NOT_REACHED();
}
return sizeof(struct ofp11_port_stats);
case OFP13_VERSION:
return sizeof(struct ofp13_port_stats);
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ return 0;
default:
OVS_NOT_REACHED();
}
return 0;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
+
default:
OVS_NOT_REACHED();
}
"(\'-O OpenFlow11\')");
case OFP11_VERSION:
case OFP12_VERSION:
- case OFP13_VERSION: {
+ case OFP13_VERSION:
+ case OFP14_VERSION: {
struct ofp11_group_stats_request *req;
request = ofpraw_alloc(OFPRAW_OFPST11_GROUP_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
"(\'-O OpenFlow11\')");
case OFP11_VERSION:
case OFP12_VERSION:
- case OFP13_VERSION: {
+ case OFP13_VERSION:
+ case OFP14_VERSION:
request = ofpraw_alloc(OFPRAW_OFPST11_GROUP_DESC_REQUEST, ofp_version, 0);
break;
- }
default:
OVS_NOT_REACHED();
}
ofputil_append_of13_group_stats(ogs, replies);
break;
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
+
case OFP10_VERSION:
default:
OVS_NOT_REACHED();
ovs_fatal(0, "dump-group-features needs OpenFlow 1.2 or later "
"(\'-O OpenFlow12\')");
case OFP12_VERSION:
- case OFP13_VERSION: {
+ case OFP13_VERSION:
+ case OFP14_VERSION:
request = ofpraw_alloc(OFPRAW_OFPST12_GROUP_FEATURES_REQUEST,
- ofp_version, 0);
+ ofp_version, 0);
break;
- }
default:
OVS_NOT_REACHED();
}
case OFP11_VERSION:
case OFP12_VERSION:
- case OFP13_VERSION: {
+ case OFP13_VERSION:
+ case OFP14_VERSION:
b = ofpraw_alloc(OFPRAW_OFPT11_GROUP_MOD, ofp_version, 0);
start_ogm = b->size;
ofpbuf_put_zeros(b, sizeof *ogm);
ogm->group_id = htonl(gm->group_id);
break;
- }
default:
OVS_NOT_REACHED();
struct ofputil_queue_stats_request *oqsr)
{
switch ((enum ofp_version)request->version) {
+ case OFP14_VERSION:
case OFP13_VERSION:
case OFP12_VERSION:
case OFP11_VERSION: {
switch (ofp_version) {
case OFP11_VERSION:
case OFP12_VERSION:
- case OFP13_VERSION: {
+ case OFP13_VERSION:
+ case OFP14_VERSION: {
struct ofp11_queue_stats_request *req;
request = ofpraw_alloc(OFPRAW_OFPST11_QUEUE_REQUEST, ofp_version, 0);
req = ofpbuf_put_zeros(request, sizeof *req);
return sizeof(struct ofp11_queue_stats);
case OFP13_VERSION:
return sizeof(struct ofp13_queue_stats);
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ return 0;
default:
OVS_NOT_REACHED();
}
break;
}
+ case OFP14_VERSION:
+ OVS_NOT_REACHED();
+ break;
+
default:
OVS_NOT_REACHED();
}
* variant. */
OFPUTIL_P_OF12_OXM = 1 << 5,
OFPUTIL_P_OF13_OXM = 1 << 6,
-#define OFPUTIL_P_ANY_OXM (OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM)
+ OFPUTIL_P_OF14_OXM = 1 << 7,
+#define OFPUTIL_P_ANY_OXM (OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM | OFPUTIL_P_OF14_OXM)
#define OFPUTIL_P_NXM_OF11_UP (OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF11_STD | \
OFPUTIL_P_ANY_OXM)
#define OFPUTIL_P_OF13_UP (OFPUTIL_P_OF13_OXM)
+#define OFPUTIL_P_OF14_UP (OFPUTIL_P_OF14_OXM)
+
/* All protocols. */
-#define OFPUTIL_P_ANY ((1 << 7) - 1)
+#define OFPUTIL_P_ANY ((1 << 8) - 1)
/* Protocols in which a specific table may be specified in flow_mods. */
#define OFPUTIL_P_TID (OFPUTIL_P_OF10_STD_TID | \
OpenFlow 1.1: vendor 0, type 3, code 5
OpenFlow 1.2: vendor 0, type 3, code 5
OpenFlow 1.3: vendor 0, type 3, code 5
+OpenFlow 1.4: vendor 0, type 3, code 5
])
AT_CHECK([ovs-ofctl print-error OFPBIC_BAD_EXP_TYPE], [0], [dnl
OpenFlow 1.1: vendor 0, type 3, code 5
OpenFlow 1.2: vendor 0, type 3, code 6
OpenFlow 1.3: vendor 0, type 3, code 6
+OpenFlow 1.4: vendor 0, type 3, code 6
])
AT_CLEANUP
.
.IP "\fBOXM-OpenFlow12\fR"
.IQ "\fBOXM-OpenFlow13\fR"
+.IQ "\fBOXM-OpenFlow14\fR"
These are the standard OXM (OpenFlow Extensible Match) flow format in
-OpenFlow 1.2 and 1.3, respectively.
+OpenFlow 1.2, 1.3, and 1.4, respectively.
.RE
.
.IP
.IP "\fBNXM\fR"
\fBNXM\-table_id\fR or \fBNXM+table_id\fR.
.IP "\fBOXM\fR"
-\fBOXM-OpenFlow12\fR or \fBOXM-OpenFlow13\fR.
+\fBOXM-OpenFlow12\fR, \fBOXM-OpenFlow13\fR, or \fBOXM-OpenFlow14\fR.
.RE
.
.IP
case OFP11_VERSION:
case OFP12_VERSION:
case OFP13_VERSION:
+ case OFP14_VERSION:
break;
default:
OVS_NOT_REACHED();
{"name": "Open_vSwitch",
"version": "7.4.0",
- "cksum": "951746691 20389",
+ "cksum": "2387737815 20431",
"tables": {
"Open_vSwitch": {
"columns": {
"enum": ["set", ["OpenFlow10",
"OpenFlow11",
"OpenFlow12",
- "OpenFlow13"]]},
+ "OpenFlow13",
+ "OpenFlow14"]]},
"min": 0, "max": "unlimited"}},
"fail_mode": {
"type": {"key": {"type": "string",