loci: remove a malloc/free from parsing of_match_t

The code was allocating an of_wire_buffer_t on the heap (through some
indirection) and then immediately freeing it. We can just use the parent
object's wire buffer instead.
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index 3c25807..ee87d0d 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1453,9 +1453,7 @@
     elif m_type == "of_match_t":
         out.write("""
     LOCI_ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
-    match_octets.bytes = cur_len;
-    match_octets.data = OF_OBJECT_BUFFER_INDEX(obj, offset);
-    OF_TRY(of_match_deserialize(ver, %(m_name)s, &match_octets));
+    OF_TRY(of_match_deserialize(ver, %(m_name)s, obj, offset, cur_len));
 """ % dict(m_name=m_name))
     elif m_type == "of_oxm_header_t":
         out.write("""
@@ -1504,13 +1502,16 @@
 
     elif m_type == "of_match_t":
         out.write("""
-    /* Match object */
-    OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
-    new_len = match_octets.bytes;
-    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
-        match_octets.data, new_len);
-    /* Free match serialized octets */
-    FREE(match_octets.data);
+    {
+        /* Match object */
+        of_octets_t match_octets;
+        OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
+        new_len = match_octets.bytes;
+        of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
+            match_octets.data, new_len);
+        /* Free match serialized octets */
+        FREE(match_octets.data);
+    }
 """ % dict(m_name=m_name))
 
     else:  # Other object type
@@ -1630,12 +1631,6 @@
     int new_len, delta; /* For set, need new length and delta */
 """)
 
-    # For match, need octet string for set/get
-    if m_type == "of_match_t":
-        out.write("""\
-    of_octets_t match_octets; /* Serialized string for match */
-""")
-
     out.write("""
     LOCI_ASSERT(%(assert_str)s);
     ver = obj->version;
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index bc05747..3afc99c 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -77,7 +77,7 @@
 extern int of_match_serialize(of_version_t version, of_match_t *match,
                               of_octets_t *octets);
 extern int of_match_deserialize(of_version_t version, of_match_t *match,
-                                of_octets_t *octets);
+                                of_object_t *parent, int offset, int length);
 extern int of_match_v1_to_match(of_match_v1_t *src, of_match_t *dst);
 extern int of_match_v2_to_match(of_match_v2_t *src, of_match_t *dst);
 extern int of_match_v3_to_match(of_match_v3_t *src, of_match_t *dst);
@@ -738,33 +738,18 @@
 
 int
 of_match_deserialize(of_version_t version, of_match_t *match,
-                     of_octets_t *octets)
+                     of_object_t *parent, int offset, int length)
 {
-    if (octets->bytes == 0) { /* No match specified means all wildcards */
-        MEMSET(match, 0, sizeof(*match));
-        match->version = version;
-
-        return OF_ERROR_NONE;
-    }
+    of_object_t obj;
 
     switch (version) {
 """)
     for version in of_g.of_version_range:
         out.write("""
     case %(ver_name)s:
-        { /* FIXME: check init bytes */
-            uint8_t *tmp;
-            of_match_v%(version)d_t wire_match;
-            of_match_v%(version)d_init(&wire_match,
-                   %(ver_name)s, -1, 1);
-            of_object_buffer_bind((of_object_t *)&wire_match,
-                octets->data, octets->bytes, NULL);
-            OF_TRY(of_match_v%(version)d_to_match(&wire_match, match));
-
-            /* Free the wire buffer control block without freeing
-             * octets->bytes. */
-            of_wire_buffer_steal(wire_match.wbuf, &tmp);
-        }
+        of_match_v%(version)d_init(&obj, %(ver_name)s, length, 1);
+        of_object_attach(parent, &obj, offset, length);
+        OF_TRY(of_match_v%(version)d_to_match(&obj, match));
         break;
 """ % dict(version=version, ver_name=of_g.of_version_wire2name[version]))
 
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 5d67bbd..71615e6 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -1027,6 +1027,9 @@
     of_match_t match2;
     int value = 1;
     of_octets_t octets;
+    of_object_storage_t storage;
+    memset(&storage, 0, sizeof(storage));
+    storage.obj.wbuf = &storage.wbuf;
 """)
     for version in of_g.of_version_range:
         out.write("""
@@ -1034,7 +1037,10 @@
     TEST_ASSERT((value = of_match_populate(&match1, %(v_name)s, value)) > 0);
     TEST_ASSERT(of_match_serialize(%(v_name)s, &match1, &octets) ==
         OF_ERROR_NONE);
-    TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &octets) ==
+    storage.obj.wbuf->buf = octets.data;
+    storage.obj.wbuf->alloc_bytes = octets.bytes;
+    storage.obj.wbuf->current_bytes = octets.bytes;
+    TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &storage.obj, 0, octets.bytes) ==
         OF_ERROR_NONE);
     TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
     FREE(octets.data);