ovsdb-server: Fix a reference count leak bug
[cascardo/ovs.git] / build-aux / extract-ofp-fields
index b0e905c..8d43e4b 100755 (executable)
@@ -14,23 +14,25 @@ VERSION = {"1.0": 0x01,
            "1.4": 0x05,
            "1.5": 0x06}
 
-TYPES = {"u8": 1,
-         "be16": 2,
-         "be32": 4,
-         "MAC": 6,
-         "be64": 8,
-         "IPv6": 16}
-
-FORMATTING = {"decimal":            ("MFS_DECIMAL",      1,  8),
-              "hexadecimal":        ("MFS_HEXADECIMAL",  1,  8),
-              "Ethernet":           ("MFS_ETHERNET",     6,  6),
-              "IPv4":               ("MFS_IPV4",         4,  4),
-              "IPv6":               ("MFS_IPV6",        16, 16),
-              "OpenFlow 1.0 port":  ("MFS_OFP_PORT",     2,  2),
-              "OpenFlow 1.1+ port": ("MFS_OFP_PORT_OXM", 4,  4),
-              "frag":               ("MFS_FRAG",         1,  1),
-              "tunnel flags":       ("MFS_TNL_FLAGS",    2,  2),
-              "TCP flags":          ("MFS_TCP_FLAGS",    2,  2)}
+TYPES = {"u8":       (1,   False),
+         "be16":     (2,   False),
+         "be32":     (4,   False),
+         "MAC":      (6,   False),
+         "be64":     (8,   False),
+         "be128":    (16,  False),
+         "tunnelMD": (124, True)}
+
+FORMATTING = {"decimal":            ("MFS_DECIMAL",      1,   8),
+              "hexadecimal":        ("MFS_HEXADECIMAL",  1, 127),
+              "ct state":           ("MFS_CT_STATE",     4,   4),
+              "Ethernet":           ("MFS_ETHERNET",     6,   6),
+              "IPv4":               ("MFS_IPV4",         4,   4),
+              "IPv6":               ("MFS_IPV6",        16,  16),
+              "OpenFlow 1.0 port":  ("MFS_OFP_PORT",     2,   2),
+              "OpenFlow 1.1+ port": ("MFS_OFP_PORT_OXM", 4,   4),
+              "frag":               ("MFS_FRAG",         1,   1),
+              "tunnel flags":       ("MFS_TNL_FLAGS",    2,   2),
+              "TCP flags":          ("MFS_TCP_FLAGS",    2,   2)}
 
 PREREQS = {"none": "MFP_NONE",
            "ARP": "MFP_ARP",
@@ -72,7 +74,7 @@ OXM_CLASSES = {"NXM_OF_":        (0,          0x0000),
 def oxm_name_to_class(name):
     prefix = ''
     class_ = None
-    for p, c in OXM_CLASSES.iteritems():
+    for p, c in OXM_CLASSES.items():
         if name.startswith(p) and len(p) > len(prefix):
             prefix = p
             class_ = c
@@ -114,14 +116,14 @@ def fatal(msg):
 
 def usage():
     argv0 = os.path.basename(sys.argv[0])
-    print '''\
+    print('''\
 %(argv0)s, for extracting OpenFlow field properties from meta-flow.h
 usage: %(argv0)s INPUT [--meta-flow | --nx-match]
   where INPUT points to lib/meta-flow.h in the source directory.
 Depending on the option given, the output written to stdout is intended to be
 saved either as lib/meta-flow.inc or lib/nx-match.inc for the respective C
 file to #include.\
-''' % {"argv0": argv0}
+''' % {"argv0": argv0})
     sys.exit(0)
 
 
@@ -141,7 +143,12 @@ def parse_oxms(s, prefix, n_bytes):
     return tuple(parse_oxm(s2.strip(), prefix, n_bytes) for s2 in s.split(','))
 
 
+match_types = dict()
+
+
 def parse_oxm(s, prefix, n_bytes):
+    global match_types
+
     m = re.match('([A-Z0-9_]+)\(([0-9]+)\) since(?: OF(1\.[0-9]+) and)? v([12]\.[0-9]+)$', s)
     if not m:
         fatal("%s: syntax error parsing %s" % (s, prefix))
@@ -153,6 +160,14 @@ def parse_oxm(s, prefix, n_bytes):
         fatal("unknown OXM class for %s" % name)
     oxm_vendor, oxm_class = class_
 
+    if class_ in match_types:
+        if oxm_type in match_types[class_]:
+            fatal("duplicate match type for %s (conflicts with %s)" %
+                  (name, match_types[class_][oxm_type]))
+    else:
+        match_types[class_] = dict()
+    match_types[class_][oxm_type] = name
+
     # Normally the oxm_length is the size of the field, but for experimenter
     # OXMs oxm_length also includes the 4-byte experimenter ID.
     oxm_length = n_bytes
@@ -210,7 +225,7 @@ def parse_field(mff, comment):
         elif d[key] is not None:
             fatal("%s: duplicate key" % key)
         d[key] = value
-    for key, value in d.iteritems():
+    for key, value in d.items():
         if not value and key not in ("OF1.0", "OF1.1",
                                      "Prefix lookup member", "Notes"):
             fatal("%s: missing %s" % (mff, key))
@@ -221,7 +236,8 @@ def parse_field(mff, comment):
     type_ = m.group(1)
     if type_ not in TYPES:
         fatal("%s: unknown type %s" % (mff, d['Type']))
-    f['n_bytes'] = TYPES[type_]
+
+    f['n_bytes'] = TYPES[type_][0]
     if m.group(2):
         f['n_bits'] = int(m.group(2))
         if f['n_bits'] > f['n_bytes'] * 8:
@@ -229,6 +245,7 @@ def parse_field(mff, comment):
                   % (mff, f['n_bits'], 8 * f['n_bytes']))
     else:
         f['n_bits'] = 8 * f['n_bytes']
+    f['variable'] = TYPES[type_][1]
 
     if d['Maskable'] == 'no':
         f['mask'] = 'MFM_NONE'
@@ -294,7 +311,12 @@ def make_meta_flow(fields):
             output += ["    \"%s\", \"%s\"," % (f['name'], f['extra_name'])]
         else:
             output += ["    \"%s\", NULL," % f['name']]
-        output += ["    %d, %d," % (f['n_bytes'], f['n_bits'])]
+
+        if f['variable']:
+            variable = 'true'
+        else:
+            variable = 'false'
+        output += ["    %d, %d, %s," % (f['n_bytes'], f['n_bits'], variable)]
 
         if f['writable']:
             rw = 'true'
@@ -358,13 +380,13 @@ def make_meta_flow(fields):
 
 def make_nx_match(fields):
     output = []
-    print "static struct nxm_field_index all_nxm_fields[] = {"
+    print("static struct nxm_field_index all_nxm_fields[] = {")
     for f in fields:
         # Sort by OpenFlow version number (nx-match.c depends on this).
         for oxm in sorted(f['OXM'], key=lambda x: x[2]):
-            print """{ .nf = { %s, %d, "%s", %s } },""" % (
-                oxm[0], oxm[2], oxm[1], f['mff'])
-    print "};"
+            print("""{ .nf = { %s, %d, "%s", %s } },""" % (
+                oxm[0], oxm[2], oxm[1], f['mff']))
+    print("};")
     return output
 
 
@@ -473,9 +495,9 @@ def extract_ofp_fields(mode):
     if n_errors:
         sys.exit(1)
 
-    print """\
+    print("""\
 /* Generated automatically; do not modify!    "-*- buffer-read-only: t -*- */
-"""
+""")
 
     if mode == '--meta-flow':
         output = make_meta_flow(fields)
@@ -503,7 +525,7 @@ if __name__ == '__main__':
         line_number = 0
 
         for oline in extract_ofp_fields(sys.argv[2]):
-            print oline
+            print(oline)
     else:
         sys.stderr.write("invalid arguments; use --help for help\n")
         sys.exit(1)