adding instruction_id funcs
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index e987874..688578e 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -2372,6 +2372,10 @@
out.write("""
obj->wire_type_get = of_instruction_wire_object_id_get;
""")
+ if loxi_utils.class_is_instruction_id(cls):
+ out.write("""
+ obj->wire_type_get = of_instruction_id_wire_object_id_get;
+""")
if loxi_utils.class_is_queue_prop(cls):
out.write("""
obj->wire_type_get = of_queue_prop_wire_object_id_get;
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index ac4a972..5f4ac6c 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -118,6 +118,9 @@
gen_type_to_object_id(out, "instruction_type_to_id", "OF_INSTRUCTION",
"OF_INSTRUCTION_%s", type_maps.instruction_types,
max_type_value)
+ gen_type_to_object_id(out, "instruction_id_type_to_id", "OF_INSTRUCTION",
+ "OF_INSTRUCTION_ID_%s", type_maps.instruction_id_types,
+ max_type_value)
gen_type_to_object_id(out, "queue_prop_type_to_id", "OF_QUEUE_PROP",
"OF_QUEUE_PROP_%s", type_maps.queue_prop_types,
max_type_value)
@@ -565,6 +568,11 @@
out.write(map_with_experimenter_template %
dict(name="instruction", u_name="INSTRUCTION", ar_len=ar_len))
+ # Instruction ID types array gen
+ ar_len = type_maps.type_array_len(type_maps.instruction_id_types, max_type_value)
+ out.write(map_with_experimenter_template %
+ dict(name="instruction_id", u_name="INSTRUCTION_ID", ar_len=ar_len))
+
# Queue prop types array gen
ar_len = type_maps.type_array_len(type_maps.queue_prop_types,
max_type_value)
@@ -716,6 +724,8 @@
extern void of_action_id_wire_object_id_get(of_object_t *obj, of_object_id_t *id);
extern void of_instruction_wire_object_id_get(of_object_t *obj,
of_object_id_t *id);
+extern void of_instruction_id_wire_object_id_get(of_object_t *obj,
+ of_object_id_t *id);
extern void of_queue_prop_wire_object_id_get(of_object_t *obj,
of_object_id_t *id);
extern void of_table_feature_prop_wire_object_id_get(of_object_t *obj,
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
index 3249747..38c0596 100644
--- a/c_gen/codegen.py
+++ b/c_gen/codegen.py
@@ -105,6 +105,7 @@
c_code_gen.gen_generics(tmp)
with template_utils.open_output(install_dir, "loci/inc/loci/loci_classes.h") as out:
+ print tmp.getvalue()
util.render_template(out, "loci_classes.h",
legacy_code=tmp.getvalue())
diff --git a/c_gen/loxi_utils_legacy.py b/c_gen/loxi_utils_legacy.py
index 4092d4f..2e3347b 100644
--- a/c_gen/loxi_utils_legacy.py
+++ b/c_gen/loxi_utils_legacy.py
@@ -196,6 +196,25 @@
return False
+def class_is_instruction_id(cls):
+ """
+ Return True if cls_name is an action object
+
+ Note that instruction_id is not an instruction object, though it has
+ the same header. It looks like an instruction header, but the type
+ is used to identify a kind of instruction, it does not indicate the
+ type of the object following.
+ """
+ if cls.find("of_instruction_id") == 0:
+ return True
+
+ # For each vendor, check for vendor specific action
+ for exp in of_g.experimenter_name_to_id:
+ if cls.find("of_instruction_id_" + exp) == 0:
+ return True
+
+ return False
+
def class_is_meter_band(cls):
"""
Return True if cls_name is an instruction object
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index c00694c..2d20438 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -313,6 +313,43 @@
return OF_ERROR_NONE;
}
+
+/**
+ * @fixme to do when we have instruction extensions
+ * See extension_action above
+ */
+
+static void
+extension_instruction_id_object_id_get(of_object_t *obj, of_object_id_t *id)
+{
+ uint32_t exp_id;
+ uint8_t *buf;
+
+ *id = OF_INSTRUCTION_ID_EXPERIMENTER;
+
+ buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
+
+ buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET, &exp_id);
+
+ switch (exp_id) {
+ case OF_EXPERIMENTER_ID_BSN: {
+ uint32_t subtype;
+ buf_u32_get(buf + OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET, &subtype);
+ switch (subtype) {
+ case 0: *id = OF_INSTRUCTION_ID_BSN_DISABLE_SRC_MAC_CHECK; break;
+ case 1: *id = OF_INSTRUCTION_ID_BSN_ARP_OFFLOAD; break;
+ case 2: *id = OF_INSTRUCTION_ID_BSN_DHCP_OFFLOAD; break;
+ case 3: *id = OF_INSTRUCTION_ID_BSN_DISABLE_SPLIT_HORIZON_CHECK; break;
+ case 4: *id = OF_INSTRUCTION_ID_BSN_PERMIT; break;
+ case 5: *id = OF_INSTRUCTION_ID_BSN_DENY; break;
+ }
+ break;
+ }
+ }
+
+ //return OF_ERROR_NONE;
+}
+
/**
* Get the object ID based on the wire buffer for an instruction object
* @param obj The object being referenced
@@ -336,6 +373,29 @@
LOCI_ASSERT(*id != OF_OBJECT_INVALID);
}
+/**
+ * Get the object ID based on the wire buffer for an instruction ID object
+ * @param obj The object being referenced
+ * @param id Where to store the object ID
+ */
+
+
+void
+of_instruction_id_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
+{
+ int wire_type;
+
+ of_tlv16_wire_type_get(obj, &wire_type);
+ if (wire_type == OF_EXPERIMENTER_TYPE) {
+ extension_instruction_id_object_id_get(obj, id);
+ return;
+ }
+
+ LOCI_ASSERT(wire_type >= 0 && wire_type < OF_INSTRUCTION_ID_ITEM_COUNT);
+
+ *id = of_instruction_id_type_to_id[obj->version][wire_type];
+ LOCI_ASSERT(*id != OF_OBJECT_INVALID);
+}
/**
* @fixme to do when we have queue_prop extensions