[ovs-dev] [of1.5 7/9] Add skeleton for OF1.5 support.

Ben Pfaff blp at nicira.com
Thu May 8 06:56:46 UTC 2014


This allows OF1.5 prototyping to take place in a natural way.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 FAQ                                |  5 +++
 build-aux/extract-ofp-errors       |  3 +-
 build-aux/extract-ofp-msgs         | 53 ++++++++++++------------
 include/openflow/openflow-common.h |  8 +---
 lib/ofp-errors.c                   |  2 +
 lib/ofp-msgs.c                     |  7 +++-
 lib/ofp-print.c                    |  5 +++
 lib/ofp-util.c                     | 83 +++++++++++++++++++++++++++++++-------
 lib/ofp-util.h                     |  9 ++++-
 tests/ofp-errors.at                |  2 +
 tests/ofproto-macros.at            |  4 +-
 utilities/ovs-ofctl.c              |  1 +
 vswitchd/bridge.c                  | 18 +++++++--
 vswitchd/bridge.h                  |  1 +
 vswitchd/ovs-vswitchd.c            |  7 ++++
 vswitchd/vswitch.ovsschema         |  7 ++--
 vswitchd/vswitch.xml               |  8 ++++
 17 files changed, 162 insertions(+), 61 deletions(-)

diff --git a/FAQ b/FAQ
index d3632f9..93e34c4 100644
--- a/FAQ
+++ b/FAQ
@@ -1187,6 +1187,11 @@ A: The following table lists the versions of OpenFlow supported by
    (which must be done in the same way described above) when it is
    invoked with a special --enable-of14 command line option.
 
+   OpenFlow 1.5 has the same risks as OpenFlow 1.4, but it is even
+   more experimental because the OpenFlow 1.5 specification is still
+   under development and thus subject to change.  Use --enable-of15 to
+   allow OpenFlow 1.5 to be enabled.
+
    OPENFLOW-1.1+ in the Open vSwitch source tree tracks support for
    OpenFlow 1.1 and later features.  When support for OpenFlow 1.4 is
    solidly implemented, Open vSwitch will enable that version by
diff --git a/build-aux/extract-ofp-errors b/build-aux/extract-ofp-errors
index ee8dd0f..89dd31a 100755
--- a/build-aux/extract-ofp-errors
+++ b/build-aux/extract-ofp-errors
@@ -11,7 +11,8 @@ version_map = {"1.0": 0x01,
                "1.1": 0x02,
                "1.2": 0x03,
                "1.3": 0x04,
-               "1.4": 0x05}
+               "1.4": 0x05,
+               "1.5": 0x06}
 version_reverse_map = dict((v, k) for (k, v) in version_map.iteritems())
 
 token = None
diff --git a/build-aux/extract-ofp-msgs b/build-aux/extract-ofp-msgs
index 3cefb2b..9e82977 100755
--- a/build-aux/extract-ofp-msgs
+++ b/build-aux/extract-ofp-msgs
@@ -6,11 +6,13 @@ import re
 
 line = ""
 
-OFP10_VERSION = 0x01
-OFP11_VERSION = 0x02
-OFP12_VERSION = 0x03
-OFP13_VERSION = 0x04
-OFP14_VERSION = 0x05
+# Maps from user-friendly version number to its protocol encoding.
+VERSION = {"1.0": 0x01,
+           "1.1": 0x02,
+           "1.2": 0x03,
+           "1.3": 0x04,
+           "1.4": 0x05,
+           "1.5": 0x06}
 
 NX_VENDOR_ID = 0x00002320
 
@@ -21,21 +23,16 @@ OFPT11_STATS_REQUEST = 18
 OFPT11_STATS_REPLY = 19
 OFPST_VENDOR = 0xffff
 
-version_map = {"1.0":     (OFP10_VERSION, OFP10_VERSION),
-               "1.1":     (OFP11_VERSION, OFP11_VERSION),
-               "1.2":     (OFP12_VERSION, OFP12_VERSION),
-               "1.3":     (OFP13_VERSION, OFP13_VERSION),
-               "1.4":     (OFP14_VERSION, OFP14_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),
-               "1.1-1.2": (OFP11_VERSION, OFP12_VERSION),
-               "1.1-1.3": (OFP11_VERSION, OFP13_VERSION),
-               "<all>":   (0x01, 0xff)}
+def decode_version_range(range):
+    if range in VERSION:
+        return (VERSION[range], VERSION[range])
+    elif range.endswith('+'):
+        return (VERSION[range[:-1]], max(VERSION.values()))
+    elif range == '<all>':
+        return (0x01, 0xff)
+    else:
+        a, b = re.match(r'^([^-]+)-([^-]+)$', range).groups()
+        return (VERSION[a], VERSION[b])
 
 def get_line():
     global line
@@ -124,7 +121,7 @@ def extract_ofp_msgs(output_file_name):
         vinfix, name = m.groups()
         rawname = 'OFPRAW_%s%s_%s' % (type_, vinfix, name)
 
-        min_version, max_version = version_map[versions]
+        min_version, max_version = decode_version_range(versions)
 
         human_name = '%s_%s' % (type_, name)
         if type_.endswith('ST'):
@@ -142,38 +139,38 @@ def extract_ofp_msgs(output_file_name):
                 if number == OFPT_VENDOR:
                     fatal("OFPT (%d) is used for vendor extensions"
                           % number)
-                elif (version == OFP10_VERSION
+                elif (version == VERSION["1.0"]
                       and (number == OFPT10_STATS_REQUEST
                            or number == OFPT10_STATS_REPLY)):
                     fatal("OFPT 1.0 (%d) is used for stats messages"
                           % number)
-                elif (version != OFP10_VERSION
+                elif (version != VERSION["1.0"]
                       and (number == OFPT11_STATS_REQUEST
                            or number == OFPT11_STATS_REPLY)):
                     fatal("OFPT 1.1+ (%d) is used for stats messages"
                           % number)
                 hdrs = (version, number, 0, 0, 0)
             elif type_ == 'OFPST' and name.endswith('_REQUEST'):
-                if version == OFP10_VERSION:
+                if version == VERSION["1.0"]:
                     hdrs = (version, OFPT10_STATS_REQUEST, number, 0, 0)
                 else:
                     hdrs = (version, OFPT11_STATS_REQUEST, number, 0, 0)
             elif type_ == 'OFPST' and name.endswith('_REPLY'):
-                if version == OFP10_VERSION:
+                if version == VERSION["1.0"]:
                     hdrs = (version, OFPT10_STATS_REPLY, number, 0, 0)
                 else:
                     hdrs = (version, OFPT11_STATS_REPLY, number, 0, 0)
             elif type_ == 'NXT':
                 hdrs = (version, OFPT_VENDOR, 0, NX_VENDOR_ID, number)
             elif type_ == 'NXST' and name.endswith('_REQUEST'):
-                if version == OFP10_VERSION:
+                if version == VERSION["1.0"]:
                     hdrs = (version, OFPT10_STATS_REQUEST, OFPST_VENDOR,
                             NX_VENDOR_ID, number)
                 else:
                     hdrs = (version, OFPT11_STATS_REQUEST, OFPST_VENDOR,
                             NX_VENDOR_ID, number)
             elif type_ == 'NXST' and name.endswith('_REPLY'):
-                if version == OFP10_VERSION:
+                if version == VERSION["1.0"]:
                     hdrs = (version, OFPT10_STATS_REPLY, OFPST_VENDOR,
                             NX_VENDOR_ID, number)
                 else:
@@ -309,7 +306,7 @@ def extract_ofp_msgs(output_file_name):
         if r['type'].endswith("ST"):
             for hdrs in r['hdrs']:
                 op_hdrs = list(hdrs)
-                if hdrs[0] == OFP10_VERSION:
+                if hdrs[0] == VERSION["1.0"]:
                     if hdrs[1] == OFPT10_STATS_REQUEST:
                         op_hdrs[1] = OFPT10_STATS_REPLY
                     elif hdrs[1] == OFPT10_STATS_REPLY:
diff --git a/include/openflow/openflow-common.h b/include/openflow/openflow-common.h
index 76b18f2..75cf413 100644
--- a/include/openflow/openflow-common.h
+++ b/include/openflow/openflow-common.h
@@ -76,12 +76,8 @@ enum ofp_version {
     OFP11_VERSION = 0x02,
     OFP12_VERSION = 0x03,
     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 OFP15_VERSION 0x06
+    OFP14_VERSION = 0x05,
+    OFP15_VERSION = 0x06
 };
 
 /* Vendor (aka experimenter) IDs.
diff --git a/lib/ofp-errors.c b/lib/ofp-errors.c
index bd4e43a..c803494 100644
--- a/lib/ofp-errors.c
+++ b/lib/ofp-errors.c
@@ -52,6 +52,8 @@ ofperr_domain_from_version(enum ofp_version version)
         return &ofperr_of13;
     case OFP14_VERSION:
         return &ofperr_of14;
+    case OFP15_VERSION:
+        return &ofperr_of15;
     default:
         return NULL;
     }
diff --git a/lib/ofp-msgs.c b/lib/ofp-msgs.c
index e54918e..99c7e01 100644
--- a/lib/ofp-msgs.c
+++ b/lib/ofp-msgs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013 Nicira, Inc.
+ * Copyright (c) 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.
@@ -269,6 +269,7 @@ ofp_is_stat_request(enum ofp_version version, uint8_t type)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         return type == OFPT11_STATS_REQUEST;
     }
 
@@ -285,6 +286,7 @@ ofp_is_stat_reply(enum ofp_version version, uint8_t type)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         return type == OFPT11_STATS_REPLY;
     }
 
@@ -325,6 +327,7 @@ ofphdrs_len(const struct ofphdrs *hdrs)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         if (hdrs->type == OFPT11_STATS_REQUEST ||
             hdrs->type == OFPT11_STATS_REPLY) {
             return (hdrs->stat == OFPST_VENDOR
@@ -758,6 +761,7 @@ ofpraw_stats_request_to_reply(enum ofpraw raw, uint8_t version)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         ovs_assert(hdrs.type == OFPT11_STATS_REQUEST);
         hdrs.type = OFPT11_STATS_REPLY;
         break;
@@ -970,6 +974,7 @@ ofpmp_flags__(const struct ofp_header *oh)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         return &((struct ofp11_stats_msg *) oh)->flags;
     default:
         OVS_NOT_REACHED();
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 909a846..3d4b8f81 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -545,6 +545,7 @@ ofp_print_switch_features(struct ds *string, const struct ofp_header *oh)
         break;
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         return; /* no ports in ofp13_switch_features */
     default:
         OVS_NOT_REACHED();
@@ -1802,6 +1803,7 @@ ofp_print_ofpst_table_reply(struct ds *string, const struct ofp_header *oh,
                             int verbosity)
 {
     switch ((enum ofp_version)oh->version) {
+    case OFP15_VERSION:
     case OFP14_VERSION:
     case OFP13_VERSION:
         ofp_print_ofpst_table_reply13(string, oh, verbosity);
@@ -2303,6 +2305,9 @@ ofp_print_version(const struct ofp_header *oh,
     case OFP14_VERSION:
         ds_put_cstr(string, " (OF1.4)");
         break;
+    case OFP15_VERSION:
+        ds_put_cstr(string, " (OF1.5)");
+        break;
     default:
         ds_put_format(string, " (OF 0x%02"PRIx8")", oh->version);
         break;
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 622d02a..4ec323d 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -630,6 +630,7 @@ ofputil_match_typical_len(enum ofputil_protocol protocol)
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM:
     case OFPUTIL_P_OF14_OXM:
+    case OFPUTIL_P_OF15_OXM:
         return NXM_TYPICAL_LEN;
 
     default:
@@ -671,6 +672,7 @@ ofputil_put_ofp11_match(struct ofpbuf *b, const struct match *match,
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM:
     case OFPUTIL_P_OF14_OXM:
+    case OFPUTIL_P_OF15_OXM:
         return oxm_put_match(b, match);
     }
 
@@ -709,18 +711,20 @@ struct proto_abbrev {
 /* Most users really don't care about some of the differences between
  * protocols.  These abbreviations help with that.
  *
- * Until it is safe to use the OpenFlow 1.4 protocol (which currently can
- * cause aborts due to unimplemented features), we omit OpenFlow 1.4 from all
- * abbrevations. */
+ * Until it is safe to use the OpenFlow 1.4 or 1.5 protocol (which currently
+ * can cause aborts due to unimplemented features), we omit these protocols
+ * from all abbrevations. */
+#define OFPUTIL_P_UNSAFE (OFPUTIL_P_OF14_OXM | OFPUTIL_P_OF15_OXM)
 static const struct proto_abbrev proto_abbrevs[] = {
-    { OFPUTIL_P_ANY          & ~OFPUTIL_P_OF14_OXM, "any" },
-    { OFPUTIL_P_OF10_STD_ANY & ~OFPUTIL_P_OF14_OXM, "OpenFlow10" },
-    { OFPUTIL_P_OF10_NXM_ANY & ~OFPUTIL_P_OF14_OXM, "NXM" },
-    { OFPUTIL_P_ANY_OXM      & ~OFPUTIL_P_OF14_OXM, "OXM" },
+    { OFPUTIL_P_ANY          & ~OFPUTIL_P_UNSAFE, "any" },
+    { OFPUTIL_P_OF10_STD_ANY & ~OFPUTIL_P_UNSAFE, "OpenFlow10" },
+    { OFPUTIL_P_OF10_NXM_ANY & ~OFPUTIL_P_UNSAFE, "NXM" },
+    { OFPUTIL_P_ANY_OXM      & ~OFPUTIL_P_UNSAFE, "OXM" },
 };
 #define N_PROTO_ABBREVS ARRAY_SIZE(proto_abbrevs)
 
 enum ofputil_protocol ofputil_flow_dump_protocols[] = {
+    OFPUTIL_P_OF15_OXM,
     OFPUTIL_P_OF14_OXM,
     OFPUTIL_P_OF13_OXM,
     OFPUTIL_P_OF12_OXM,
@@ -748,6 +752,8 @@ ofputil_protocols_from_ofp_version(enum ofp_version version)
         return OFPUTIL_P_OF13_OXM;
     case OFP14_VERSION:
         return OFPUTIL_P_OF14_OXM;
+    case OFP15_VERSION:
+        return OFPUTIL_P_OF15_OXM;
     default:
         return 0;
     }
@@ -783,6 +789,8 @@ ofputil_protocol_to_ofp_version(enum ofputil_protocol protocol)
         return OFP13_VERSION;
     case OFPUTIL_P_OF14_OXM:
         return OFP14_VERSION;
+    case OFPUTIL_P_OF15_OXM:
+        return OFP15_VERSION;
     }
 
     OVS_NOT_REACHED();
@@ -862,6 +870,9 @@ ofputil_protocol_set_tid(enum ofputil_protocol protocol, bool enable)
     case OFPUTIL_P_OF14_OXM:
         return OFPUTIL_P_OF14_OXM;
 
+    case OFPUTIL_P_OF15_OXM:
+        return OFPUTIL_P_OF15_OXM;
+
     default:
         OVS_NOT_REACHED();
     }
@@ -905,6 +916,9 @@ ofputil_protocol_set_base(enum ofputil_protocol cur,
     case OFPUTIL_P_OF14_OXM:
         return ofputil_protocol_set_tid(OFPUTIL_P_OF14_OXM, tid);
 
+    case OFPUTIL_P_OF15_OXM:
+        return ofputil_protocol_set_tid(OFPUTIL_P_OF15_OXM, tid);
+
     default:
         OVS_NOT_REACHED();
     }
@@ -944,6 +958,9 @@ ofputil_protocol_to_string(enum ofputil_protocol protocol)
 
     case OFPUTIL_P_OF14_OXM:
         return "OXM-OpenFlow14";
+
+    case OFPUTIL_P_OF15_OXM:
+        return "OXM-OpenFlow15";
     }
 
     /* Check abbreviations. */
@@ -1082,6 +1099,9 @@ ofputil_version_from_string(const char *s)
     if (!strcasecmp(s, "OpenFlow14")) {
         return OFP14_VERSION;
     }
+    if (!strcasecmp(s, "OpenFlow15")) {
+        return OFP15_VERSION;
+    }
     return 0;
 }
 
@@ -1154,6 +1174,8 @@ ofputil_version_to_string(enum ofp_version ofp_version)
         return "OpenFlow13";
     case OFP14_VERSION:
         return "OpenFlow14";
+    case OFP15_VERSION:
+        return "OpenFlow15";
     default:
         OVS_NOT_REACHED();
     }
@@ -1388,6 +1410,7 @@ ofputil_encode_set_protocol(enum ofputil_protocol current,
         case OFPUTIL_P_OF12_OXM:
         case OFPUTIL_P_OF13_OXM:
         case OFPUTIL_P_OF14_OXM:
+        case OFPUTIL_P_OF15_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();
@@ -2160,7 +2183,8 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
     case OFPUTIL_P_OF11_STD:
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM:
-    case OFPUTIL_P_OF14_OXM: {
+    case OFPUTIL_P_OF14_OXM:
+    case OFPUTIL_P_OF15_OXM: {
         struct ofp11_flow_mod *ofm;
         int tailroom;
 
@@ -2645,7 +2669,8 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
     case OFPUTIL_P_OF11_STD:
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM:
-    case OFPUTIL_P_OF14_OXM: {
+    case OFPUTIL_P_OF14_OXM:
+    case OFPUTIL_P_OF15_OXM: {
         struct ofp11_flow_stats_request *ofsr;
 
         raw = (fsr->aggregate
@@ -3137,7 +3162,8 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
     case OFPUTIL_P_OF11_STD:
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM:
-    case OFPUTIL_P_OF14_OXM: {
+    case OFPUTIL_P_OF14_OXM:
+    case OFPUTIL_P_OF15_OXM: {
         struct ofp12_flow_removed *ofr;
 
         msg = ofpraw_alloc_xid(OFPRAW_OFPT11_FLOW_REMOVED,
@@ -3502,6 +3528,7 @@ ofputil_encode_packet_in(const struct ofputil_packet_in *pin,
     case OFPUTIL_P_OF12_OXM:
     case OFPUTIL_P_OF13_OXM:
     case OFPUTIL_P_OF14_OXM:
+    case OFPUTIL_P_OF15_OXM:
         packet = ofputil_encode_ofp12_packet_in(pin, protocol);
         break;
 
@@ -3826,6 +3853,7 @@ ofputil_get_phy_port_size(enum ofp_version ofp_version)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         return sizeof(struct ofp11_port);
     default:
         OVS_NOT_REACHED();
@@ -3921,6 +3949,7 @@ ofputil_put_phy_port(enum ofp_version ofp_version,
     }
 
     case OFP14_VERSION:
+    case OFP15_VERSION:
         ofputil_put_ofp14_port(pp, b);
         break;
 
@@ -3999,6 +4028,7 @@ ofputil_capabilities_mask(enum ofp_version ofp_version)
     case OFP13_VERSION:
         return OFPC_COMMON | OFPC12_PORT_BLOCKED;
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         break;
     default:
@@ -4128,6 +4158,7 @@ ofputil_encode_switch_features(const struct ofputil_switch_features *features,
         break;
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         raw = OFPRAW_OFPT13_FEATURES_REPLY;
         break;
     default:
@@ -4151,6 +4182,7 @@ ofputil_encode_switch_features(const struct ofputil_switch_features *features,
         break;
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         osf->auxiliary_id = features->auxiliary_id;
         /* fall through */
     case OFP11_VERSION:
@@ -4237,6 +4269,7 @@ ofputil_encode_port_status(const struct ofputil_port_status *ps,
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         raw = OFPRAW_OFPT11_PORT_STATUS;
         break;
 
@@ -4334,6 +4367,7 @@ ofputil_encode_port_mod(const struct ofputil_port_mod *pm,
         break;
     }
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         break;
     default:
@@ -4646,6 +4680,7 @@ ofputil_encode_table_features_request(enum ofp_version ofp_version)
                      "(\'-O OpenFlow13\')");
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         request = ofpraw_alloc(OFPRAW_OFPST13_TABLE_FEATURES_REQUEST,
                                ofp_version, 0);
         break;
@@ -4710,6 +4745,7 @@ ofputil_encode_table_mod(const struct ofputil_table_mod *pm,
         break;
     }
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         break;
     default:
@@ -5019,6 +5055,7 @@ ofputil_encode_table_stats_reply(const struct ofp12_table_stats stats[], int n,
 
         case OFP13_VERSION:
         case OFP14_VERSION:
+        case OFP15_VERSION:
             ofputil_put_ofp13_table_stats(&stats[i], reply);
             break;
 
@@ -5325,7 +5362,8 @@ ofputil_encode_packet_out(const struct ofputil_packet_out *po,
     case OFP11_VERSION:
     case OFP12_VERSION:
     case OFP13_VERSION:
-    case OFP14_VERSION:{
+    case OFP14_VERSION:
+    case OFP15_VERSION: {
         struct ofp11_packet_out *opo;
         size_t len;
 
@@ -5383,6 +5421,7 @@ ofputil_encode_barrier_request(enum ofp_version ofp_version)
     enum ofpraw type;
 
     switch (ofp_version) {
+    case OFP15_VERSION:
     case OFP14_VERSION:
     case OFP13_VERSION:
     case OFP12_VERSION:
@@ -5671,6 +5710,7 @@ ofputil_pull_phy_port(enum ofp_version ofp_version, struct ofpbuf *b,
         return op ? ofputil_decode_ofp11_port(pp, op) : EOF;
     }
     case OFP14_VERSION:
+    case OFP15_VERSION:
         return ofpbuf_size(b) ? ofputil_pull_ofp14_port(pp, b) : EOF;
     default:
         OVS_NOT_REACHED();
@@ -6014,7 +6054,8 @@ ofputil_encode_dump_ports_request(enum ofp_version ofp_version, ofp_port_t port)
     case OFP11_VERSION:
     case OFP12_VERSION:
     case OFP13_VERSION:
-    case OFP14_VERSION:{
+    case OFP14_VERSION:
+    case OFP15_VERSION: {
         struct ofp11_port_stats_request *req;
         request = ofpraw_alloc(OFPRAW_OFPST11_PORT_REQUEST, ofp_version, 0);
         req = ofpbuf_put_zeros(request, sizeof *req);
@@ -6103,6 +6144,7 @@ ofputil_append_port_stat(struct list *replies,
     }
 
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         break;
 
@@ -6189,6 +6231,7 @@ ofputil_get_port_stats_size(enum ofp_version ofp_version)
     case OFP13_VERSION:
         return sizeof(struct ofp13_port_stats);
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         return 0;
     default:
@@ -6290,6 +6333,7 @@ ofputil_decode_port_stats_request(const struct ofp_header *request,
     }
 
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         break;
 
@@ -6329,7 +6373,8 @@ ofputil_encode_group_stats_request(enum ofp_version ofp_version,
     case OFP11_VERSION:
     case OFP12_VERSION:
     case OFP13_VERSION:
-    case OFP14_VERSION: {
+    case OFP14_VERSION:
+    case OFP15_VERSION: {
         struct ofp11_group_stats_request *req;
         request = ofpraw_alloc(OFPRAW_OFPST11_GROUP_REQUEST, ofp_version, 0);
         req = ofpbuf_put_zeros(request, sizeof *req);
@@ -6362,6 +6407,7 @@ ofputil_encode_group_desc_request(enum ofp_version ofp_version)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         request = ofpraw_alloc(OFPRAW_OFPST11_GROUP_DESC_REQUEST, ofp_version, 0);
         break;
     default:
@@ -6429,7 +6475,8 @@ ofputil_append_group_stats(struct list *replies,
         }
 
     case OFP13_VERSION:
-    case OFP14_VERSION:{
+    case OFP14_VERSION:
+    case OFP15_VERSION: {
             struct ofp13_group_stats *reply;
 
             length = gs->n_buckets * sizeof reply->bucket_stats[0]
@@ -6459,6 +6506,7 @@ ofputil_encode_group_features_request(enum ofp_version ofp_version)
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         request = ofpraw_alloc(OFPRAW_OFPST12_GROUP_FEATURES_REQUEST,
                                ofp_version, 0);
         break;
@@ -6790,6 +6838,7 @@ ofputil_encode_group_mod(enum ofp_version ofp_version,
     case OFP12_VERSION:
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         b = ofpraw_alloc(OFPRAW_OFPT11_GROUP_MOD, ofp_version, 0);
         start_ogm = ofpbuf_size(b);
         ofpbuf_put_zeros(b, sizeof *ogm);
@@ -6876,6 +6925,7 @@ ofputil_decode_queue_stats_request(const struct ofp_header *request,
                                    struct ofputil_queue_stats_request *oqsr)
 {
     switch ((enum ofp_version)request->version) {
+    case OFP15_VERSION:
     case OFP14_VERSION:
     case OFP13_VERSION:
     case OFP12_VERSION:
@@ -6914,7 +6964,8 @@ ofputil_encode_queue_stats_request(enum ofp_version ofp_version,
     case OFP11_VERSION:
     case OFP12_VERSION:
     case OFP13_VERSION:
-    case OFP14_VERSION: {
+    case OFP14_VERSION:
+    case OFP15_VERSION: {
         struct ofp11_queue_stats_request *req;
         request = ofpraw_alloc(OFPRAW_OFPST11_QUEUE_REQUEST, ofp_version, 0);
         req = ofpbuf_put_zeros(request, sizeof *req);
@@ -6951,6 +7002,7 @@ ofputil_get_queue_stats_size(enum ofp_version ofp_version)
     case OFP13_VERSION:
         return sizeof(struct ofp13_queue_stats);
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         return 0;
     default:
@@ -7140,6 +7192,7 @@ ofputil_append_queue_stat(struct list *replies,
     }
 
     case OFP14_VERSION:
+    case OFP15_VERSION:
         OVS_NOT_REACHED();
         break;
 
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index c563f78..ce10bfc 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -110,7 +110,11 @@ enum ofputil_protocol {
     OFPUTIL_P_OF12_OXM      = 1 << 5,
     OFPUTIL_P_OF13_OXM      = 1 << 6,
     OFPUTIL_P_OF14_OXM      = 1 << 7,
-#define OFPUTIL_P_ANY_OXM (OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM | OFPUTIL_P_OF14_OXM)
+    OFPUTIL_P_OF15_OXM      = 1 << 8,
+#define OFPUTIL_P_ANY_OXM (OFPUTIL_P_OF12_OXM | \
+                           OFPUTIL_P_OF13_OXM | \
+                           OFPUTIL_P_OF14_OXM | \
+                           OFPUTIL_P_OF15_OXM)
 
 #define OFPUTIL_P_NXM_OF11_UP (OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF11_STD | \
                                OFPUTIL_P_ANY_OXM)
@@ -121,7 +125,8 @@ enum ofputil_protocol {
 
 #define OFPUTIL_P_OF12_UP (OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_UP)
 #define OFPUTIL_P_OF13_UP (OFPUTIL_P_OF13_OXM | OFPUTIL_P_OF14_UP)
-#define OFPUTIL_P_OF14_UP OFPUTIL_P_OF14_OXM
+#define OFPUTIL_P_OF14_UP (OFPUTIL_P_OF14_OXM | OFPUTIL_P_OF15_UP)
+#define OFPUTIL_P_OF15_UP OFPUTIL_P_OF15_OXM
 
     /* All protocols. */
 #define OFPUTIL_P_ANY ((1 << 8) - 1)
diff --git a/tests/ofp-errors.at b/tests/ofp-errors.at
index a8d7cfa..17696b7 100644
--- a/tests/ofp-errors.at
+++ b/tests/ofp-errors.at
@@ -91,12 +91,14 @@ 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
+OpenFlow 1.5: 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
+OpenFlow 1.5: vendor 0, type 3, code 6
 ])
 AT_CLEANUP
 
diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at
index 8a058ae..93aaec8 100644
--- a/tests/ofproto-macros.at
+++ b/tests/ofproto-macros.at
@@ -73,7 +73,7 @@ m4_define([OVS_VSWITCHD_START],
    AT_CHECK([ovs-vsctl --no-wait init])
 
    dnl Start ovs-vswitchd.
-   AT_CHECK([ovs-vswitchd --detach --no-chdir --pidfile --enable-dummy$3 --disable-system --log-file -vvconn -vofproto_dpif --enable-of14], [0], [], [stderr])
+   AT_CHECK([ovs-vswitchd --detach --no-chdir --pidfile --enable-dummy$3 --disable-system --log-file -vvconn -vofproto_dpif --enable-of14 --enable-of15], [0], [], [stderr])
    AT_CAPTURE_FILE([ovs-vswitchd.log])
    AT_CHECK([[sed < stderr '
 /vlog|INFO|opened log file/d
@@ -83,7 +83,7 @@ m4_define([OVS_VSWITCHD_START],
 /ofproto|INFO|datapath ID changed to fedcba9876543210/d']])
 
    dnl Add bridges, ports, etc.
-   AT_CHECK([ovs-vsctl -- add-br br0 -- set bridge br0 datapath-type=dummy other-config:datapath-id=fedcba9876543210 other-config:hwaddr=aa:55:aa:55:00:00 protocols=[[OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14]] fail-mode=secure -- $1 m4_if([$2], [], [], [| ${PERL} $srcdir/uuidfilt.pl])], [0], [$2])
+   AT_CHECK([ovs-vsctl -- add-br br0 -- set bridge br0 datapath-type=dummy other-config:datapath-id=fedcba9876543210 other-config:hwaddr=aa:55:aa:55:00:00 protocols=[[OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15]] fail-mode=secure -- $1 m4_if([$2], [], [], [| ${PERL} $srcdir/uuidfilt.pl])], [0], [$2])
 ])
 
 m4_divert_push([PREPARE_TESTS])
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index deba9dd..2776613 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -1573,6 +1573,7 @@ ofctl_monitor(int argc, char *argv[])
         case OFP12_VERSION:
         case OFP13_VERSION:
         case OFP14_VERSION:
+        case OFP15_VERSION:
             break;
         default:
             OVS_NOT_REACHED();
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 43c109c..f507b52 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -185,10 +185,11 @@ static struct ovsdb_idl_txn *status_txn;
 static int stats_timer_interval;
 static long long int stats_timer = LLONG_MIN;
 
-/* Set to true to allow experimental use of OpenFlow 1.4.
- * This is false initially because OpenFlow 1.4 is not yet safe to use: it can
- * abort due to unimplemented features. */
+/* Set to true to allow experimental use of OpenFlow 1.4 or 1.5.
+ * This is false initially because these versions of OpenFlow are not yet safe
+ * to use: Open vSwitch can abort due to unimplemented features. */
 static bool allow_of14;
+static bool allow_of15;
 
 /* In some datapaths, creating and destroying OpenFlow ports can be extremely
  * expensive.  This can cause bridge_reconfigure() to take a long time during
@@ -460,6 +461,14 @@ bridge_enable_of14(void)
     allow_of14 = true;
 }
 
+/* Enables use of OpenFlow 1.5.  This is off by default because OpenFlow 1.5 is
+ * not yet safe to use: it can abort due to unimplemented features. */
+void
+bridge_enable_of15(void)
+{
+    allow_of15 = true;
+}
+
 /* Looks at the list of managers in 'ovs_cfg' and extracts their remote IP
  * addresses and ports into '*managersp' and '*n_managersp'.  The caller is
  * responsible for freeing '*managersp' (with free()).
@@ -993,6 +1002,9 @@ bridge_get_allowed_versions(struct bridge *br)
     if (!allow_of14) {
         allowed_versions &= ~(1u << OFP14_VERSION);
     }
+    if (!allow_of15) {
+        allowed_versions &= ~(1u << OFP15_VERSION);
+    }
     return allowed_versions;
 }
 
diff --git a/vswitchd/bridge.h b/vswitchd/bridge.h
index d1ca988..21eed57 100644
--- a/vswitchd/bridge.h
+++ b/vswitchd/bridge.h
@@ -22,6 +22,7 @@ void bridge_init(const char *remote);
 void bridge_exit(void);
 
 void bridge_enable_of14(void);
+void bridge_enable_of15(void);
 
 void bridge_run(void);
 void bridge_wait(void);
diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c
index 2f3086d..4d5c5ab 100644
--- a/vswitchd/ovs-vswitchd.c
+++ b/vswitchd/ovs-vswitchd.c
@@ -148,6 +148,7 @@ parse_options(int argc, char *argv[], char **unixctl_pathp)
         OPT_ENABLE_DUMMY,
         OPT_DISABLE_SYSTEM,
         OPT_ENABLE_OF14,
+        OPT_ENABLE_OF15,
         DAEMON_OPTION_ENUMS,
         OPT_DPDK,
     };
@@ -164,6 +165,7 @@ parse_options(int argc, char *argv[], char **unixctl_pathp)
         {"enable-dummy", optional_argument, NULL, OPT_ENABLE_DUMMY},
         {"disable-system", no_argument, NULL, OPT_DISABLE_SYSTEM},
         {"enable-of14", no_argument, NULL, OPT_ENABLE_OF14},
+        {"enable-of15", no_argument, NULL, OPT_ENABLE_OF15},
         {"dpdk", required_argument, NULL, OPT_DPDK},
         {NULL, 0, NULL, 0},
     };
@@ -217,6 +219,10 @@ parse_options(int argc, char *argv[], char **unixctl_pathp)
             bridge_enable_of14();
             break;
 
+        case OPT_ENABLE_OF15:
+            bridge_enable_of15();
+            break;
+
         case '?':
             exit(EXIT_FAILURE);
 
@@ -259,6 +265,7 @@ usage(void)
     printf("\nOther options:\n"
            "  --unixctl=SOCKET        override default control socket name\n"
            "  --enable-of14           allow enabling OF1.4 (unsafely!)\n"
+           "  --enable-of15           allow enabling OF1.5 (unsafely!)\n"
            "  -h, --help              display this help message\n"
            "  -V, --version           display version information\n");
     exit(EXIT_SUCCESS);
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index 3fb45d1..006ed23 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
- "version": "7.5.0",
- "cksum": "1448369194 20560",
+ "version": "7.6.0",
+ "cksum": "1731605290 20602",
  "tables": {
    "Open_vSwitch": {
      "columns": {
@@ -84,7 +84,8 @@
                             "OpenFlow11",
                             "OpenFlow12",
                             "OpenFlow13",
-                            "OpenFlow14"]]},
+                            "OpenFlow14",
+                            "OpenFlow15"]]},
 	   "min": 0, "max": "unlimited"}},
        "fail_mode": {
          "type": {"key": {"type": "string",
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index a351813..520a6b5 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -597,6 +597,14 @@
 	  <code>--enable-of14</code> option.  (When support becomes safe, this
 	  option will be removed.)
 	</p>
+
+        <p>
+          OpenFlow 1.5 has the same risks as OpenFlow 1.4, but it is even more
+          experimental because the OpenFlow 1.5 specification is still under
+          development and thus subject to change.  Pass
+          <code>--enable-of15</code> to <code>ovs-vswitchd</code> to allow
+          OpenFlow 1.5 to be enabled.
+        </p>
       </column>
     </group>
 
-- 
1.9.1




More information about the dev mailing list