loci: add clean API to get OXM from a set-field action
Right now users of loci need to dig into the wire buffer and internal loci
functions to parse the OXM in a set-field action. This is because loci doesn't
have good support for subtyped fields (as opposed to list elements).
This commit doesn't add generic support for subtyped fields, but it does add a
reasonable API over the special case code.
diff --git a/c_gen/build_of_g.py b/c_gen/build_of_g.py
index f117bfd..85be353 100755
--- a/c_gen/build_of_g.py
+++ b/c_gen/build_of_g.py
@@ -153,6 +153,11 @@
# but is variable length
bytes = -1
len_update = 8
+ elif base_type == "of_oxm_header_t":
+ # This is a special case: it has non-zero min length
+ # but is variable length
+ bytes = -1
+ len_update = 4
elif base_type in of_g.of_base_types:
bytes = of_g.of_base_types[base_type]["bytes"]
else:
@@ -330,7 +335,7 @@
else:
# HACK the C backend does not yet support of_oxm_t
if m.oftype == 'of_oxm_t':
- m_type = 'of_octets_t'
+ m_type = 'of_oxm_header_t'
else:
enum = find(lambda e: e.name == m.oftype, protocol.enums)
if enum and "wire_type" in enum.params:
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index b43675a..91bd07f 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1671,6 +1671,17 @@
match_octets.data = OF_OBJECT_BUFFER_INDEX(obj, offset);
OF_TRY(of_match_deserialize(ver, %(m_name)s, &match_octets));
""" % dict(m_name=m_name))
+ elif m_type == "of_oxm_header_t":
+ out.write("""
+ /* Initialize child */
+ %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
+ /* Attach to parent */
+ %(m_name)s->parent = (of_object_t *)obj;
+ %(m_name)s->wbuf = obj->wbuf;
+ %(m_name)s->obj_offset = abs_offset;
+ %(m_name)s->length = cur_len;
+ of_object_wire_init(%(m_name)s, OF_OXM, 0);
+""" % dict(m_type=m_type[:-2], m_name=m_name))
else:
out.write("""
/* Initialize child */
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 2ca743a..a0cdca1 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -99,6 +99,7 @@
of_octets_t="octets",
of_meter_features_t="features",
of_match_t="match",
+ of_oxm_header_t="oxm",
# BSN extensions
of_bsn_vport_q_in_q_t="vport",
of_bitmap_128_t="bitmap_128",