dpif-netlink: add GENEVE creation support
[cascardo/ovs.git] / build-aux / extract-ofp-msgs
index 9571192..1813638 100755 (executable)
@@ -6,13 +6,17 @@ 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,
+           "1.6": 0x07}
 
 NX_VENDOR_ID = 0x00002320
+ONF_VENDOR_ID = 0x4f4e4600
 
 OFPT_VENDOR = 4
 OFPT10_STATS_REQUEST = 16
@@ -21,20 +25,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),
-               "<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
@@ -105,7 +105,7 @@ def extract_ofp_msgs(output_file_name):
         while not comment.endswith('*/'):
             get_line()
             if line.startswith('/*') or not line or line.isspace():
-                fatal("unexpected syntax within error")
+                fatal("unexpected syntax within message")
             comment += ' %s' % line.lstrip('* \t').rstrip(' \t\r\n')
         comment = comment[:-2].rstrip()
 
@@ -123,7 +123,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'):
@@ -141,38 +141,54 @@ 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_ == 'ONFT':
+                hdrs = (version, OFPT_VENDOR, 0, ONF_VENDOR_ID, number)
+            elif type_ == 'ONFST' and name.endswith('_REQUEST'):
+                if version == VERSION["1.0"]:
+                    hdrs = (version, OFPT10_STATS_REQUEST, OFPST_VENDOR,
+                            ONF_VENDOR_ID, number)
+                else:
+                    hdrs = (version, OFPT11_STATS_REQUEST, OFPST_VENDOR,
+                            ONF_VENDOR_ID, number)
+            elif type_ == 'ONFST' and name.endswith('_REPLY'):
+                if version == VERSION["1.0"]:
+                    hdrs = (version, OFPT10_STATS_REPLY, OFPST_VENDOR,
+                            ONF_VENDOR_ID, number)
+                else:
+                    hdrs = (version, OFPT11_STATS_REPLY, OFPST_VENDOR,
+                            ONF_VENDOR_ID, number)
             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:
@@ -231,6 +247,7 @@ def extract_ofp_msgs(output_file_name):
         if re.match('enum ofptype', line):
             break
 
+    all_types = []
     while True:
         get_line()
         if re.match(r'\s*/?\*', line) or line.isspace():
@@ -265,6 +282,8 @@ def extract_ofp_msgs(output_file_name):
                       % (raw, all_raws[raw]["ofptype"]))
             all_raws[raw]["ofptype"] = ofptype
 
+        all_types.append(all_raws[raws[0]]["human_name"])
+
     input_file.close()
 
     if n_errors:
@@ -308,7 +327,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:
@@ -331,6 +350,12 @@ def extract_ofp_msgs(output_file_name):
                               % r["human_name"])
     output.append("};")
 
+    output.append("");
+    output.append("static const char *type_names[] = {");
+    for t in all_types:
+        output.append("    \"%s\"," % t)
+    output.append("};")
+
     if n_errors:
         sys.exit(1)
 
@@ -341,7 +366,7 @@ if __name__ == '__main__':
     if '--help' in sys.argv:
         usage()
     elif len(sys.argv) != 3:
-        sys.stderr.write("exactly one non-option arguments required; "
+        sys.stderr.write("exactly two non-option arguments required; "
                          "use --help for help\n")
         sys.exit(1)
     else: