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);