loci: wire length get/set functions for new special cases
Most of these special cases have a u16 length member, but not at offset 0. A
couple gained the length member in OF 1.4 so we have to check the version
before accessing the length.
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index 6c45d4d..c7a175f 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -64,6 +64,15 @@
extern void of_meter_stats_wire_length_get(of_object_t *obj, int *bytes);
extern void of_meter_stats_wire_length_set(of_object_t *obj, int bytes);
+extern void of_port_desc_wire_length_get(of_object_t *obj, int *bytes);
+extern void of_port_desc_wire_length_set(of_object_t *obj, int bytes);
+
+extern void of_port_stats_entry_wire_length_get(of_object_t *obj, int *bytes);
+extern void of_port_stats_entry_wire_length_set(of_object_t *obj, int bytes);
+
+extern void of_queue_stats_entry_wire_length_get(of_object_t *obj, int *bytes);
+extern void of_queue_stats_entry_wire_length_set(of_object_t *obj, int bytes);
+
""")
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
index c1b00ad..fa3a79b 100644
--- a/c_gen/codegen.py
+++ b/c_gen/codegen.py
@@ -197,6 +197,13 @@
class_metadata = []
class_metadata_dict = {}
+# These classes have handwritten C code to get/set their length fields
+# See templates/of_type_maps.c
+special_length_classes = set([
+ 'of_packet_queue', 'of_meter_stats', 'of_port_desc',
+ 'of_port_stats_entry', 'of_queue_stats_entry',
+])
+
def build_class_metadata():
for uclass in loxi_globals.unified.classes:
wire_length_get = 'NULL'
@@ -216,14 +223,9 @@
wire_length_set = 'of_object_message_wire_length_set'
elif uclass.is_oxm:
wire_length_get = 'of_oxm_wire_length_get'
- elif uclass.name == "of_packet_queue":
- # u16 len, but at offset 4
- wire_length_get = 'of_packet_queue_wire_length_get'
- wire_length_set = 'of_packet_queue_wire_length_set'
- elif uclass.name == "of_meter_stats":
- # u16 len, but at offset 4
- wire_length_get = 'of_meter_stats_wire_length_get'
- wire_length_set = 'of_meter_stats_wire_length_set'
+ elif uclass.name in special_length_classes:
+ wire_length_get = '%s_wire_length_get' % uclass.name
+ wire_length_set = '%s_wire_length_set' % uclass.name
elif loxi_utils_legacy.class_is_tlv16(uclass.name):
wire_length_set = 'of_tlv16_wire_length_set'
wire_length_get = 'of_tlv16_wire_length_get'
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index 9fa59e0..8847515 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -305,3 +305,141 @@
of_wire_buffer_u16_set(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET), bytes);
}
+
+/**
+ * Get the wire length for a port desc object
+ * @param obj The object being referenced
+ * @param bytes Pointer to location to store length
+ *
+ * The length is only present for OF 1.4+.
+ */
+void
+of_port_desc_wire_length_get(of_object_t *obj, int *bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ uint16_t u16;
+
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
+ &u16);
+ *bytes = u16;
+ } else {
+ *bytes = OF_OBJECT_FIXED_LENGTH(obj);
+ }
+}
+
+/**
+ * Set the wire length for a port desc object
+ * @param obj The object being referenced
+ * @param bytes The length of the object
+ *
+ * The length is only present for OF 1.4+.
+ */
+
+void
+of_port_desc_wire_length_set(of_object_t *obj, int bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
+ bytes);
+ } else {
+ LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
+ }
+}
+
+/**
+ * Get the wire length for a port stats_entry object
+ * @param obj The object being referenced
+ * @param bytes Pointer to location to store length
+ *
+ * The length is only present for OF 1.4+.
+ */
+void
+of_port_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ uint16_t u16;
+
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ &u16);
+ *bytes = u16;
+ } else {
+ *bytes = OF_OBJECT_FIXED_LENGTH(obj);
+ }
+}
+
+/**
+ * Set the wire length for a port stats_entry object
+ * @param obj The object being referenced
+ * @param bytes The length of the object
+ *
+ * The length is only present for OF 1.4+.
+ */
+
+void
+of_port_stats_entry_wire_length_set(of_object_t *obj, int bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ bytes);
+ } else {
+ LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
+ }
+}
+
+/**
+ * Get the wire length for a queue stats_entry object
+ * @param obj The object being referenced
+ * @param bytes Pointer to location to store length
+ *
+ * The length is only present for OF 1.4+.
+ */
+void
+of_queue_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ uint16_t u16;
+
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ &u16);
+ *bytes = u16;
+ } else {
+ *bytes = OF_OBJECT_FIXED_LENGTH(obj);
+ }
+}
+
+/**
+ * Set the wire length for a queue stats_entry object
+ * @param obj The object being referenced
+ * @param bytes The length of the object
+ *
+ * The length is only present for OF 1.4+.
+ */
+
+void
+of_queue_stats_entry_wire_length_set(of_object_t *obj, int bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ bytes);
+ } else {
+ LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
+ }
+}