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