Merge remote-tracking branch 'origin/master' into loci-parser

Conflicts:
	c_gen/c_type_maps.py
	c_gen/templates/of_type_maps.c
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index cbbcfba..ff9a654 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -437,6 +437,7 @@
 of_object_id_t of_action_to_object_id(int action, of_version_t version);
 of_object_id_t of_action_id_to_object_id(int action_id, of_version_t version);
 of_object_id_t of_instruction_to_object_id(int instruction, of_version_t version);
+of_object_id_t of_instruction_id_to_object_id(int instruction, of_version_t version);
 of_object_id_t of_queue_prop_to_object_id(int queue_prop, of_version_t version);
 of_object_id_t of_table_feature_prop_to_object_id(int table_feature_prop, of_version_t version);
 of_object_id_t of_meter_band_to_object_id(int meter_band, of_version_t version);
@@ -738,7 +739,7 @@
 
 #define OF_MATCH_BYTES(length) (((length) + 7) & 0xfff8)
 
-#if __BYTE_ORDER == __BIG_ENDIAN
+#if __BYTE_ORDER == __ORDER_BIG_ENDIAN
 #define U16_NTOH(val) (val)
 #define U32_NTOH(val) (val)
 #define U64_NTOH(val) (val)
@@ -748,7 +749,7 @@
 #define U64_HTON(val) (val)
 #define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
 #else /* Little Endian */
-#define U16_NTOH(val) (((val) >> 8) | ((val) << 8))
+#define U16_NTOH(val) (((val) >> 8) | (((val) & 0xff) << 8))
 #define U32_NTOH(val) ((((val) & 0xff000000) >> 24) |                   \\
                        (((val) & 0x00ff0000) >>  8) |                   \\
                        (((val) & 0x0000ff00) <<  8) |                   \\
@@ -2371,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 a791601..19d7587 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_ID",
+                          "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)
diff --git a/c_gen/loxi_utils_legacy.py b/c_gen/loxi_utils_legacy.py
index 4092d4f..df93c2b 100644
--- a/c_gen/loxi_utils_legacy.py
+++ b/c_gen/loxi_utils_legacy.py
@@ -191,7 +191,26 @@
 
     # For each vendor, check for vendor specific action
     for exp in of_g.experimenter_name_to_id:
-        if cls.find("of_instruction_" + exp) == 0:
+        if cls.find("of_instruction" + exp) == 0:
+            return True
+
+    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
diff --git a/c_gen/templates/_push_wire_types.c b/c_gen/templates/_push_wire_types.c
index 5b16e24..fd2536c 100644
--- a/c_gen/templates/_push_wire_types.c
+++ b/c_gen/templates/_push_wire_types.c
@@ -38,11 +38,11 @@
 :: if m.length == 1:
         *(uint8_t *)(buf + ${m.offset}) = ${m.value}; /* ${m.name} */
 :: elif m.length == 2:
-        *(uint16_t *)(buf + ${m.offset}) = htobe16(${m.value}); /* ${m.name} */
+        *(uint16_t *)(buf + ${m.offset}) = U16_HTON(${m.value}); /* ${m.name} */
 :: elif m.length == 4:
-        *(uint32_t *)(buf + ${m.offset}) = htobe32(${m.value}); /* ${m.name} */
+        *(uint32_t *)(buf + ${m.offset}) = U32_HTON(${m.value}); /* ${m.name} */
 :: elif m.length == 8:
-        *(uint64_t *)(buf + ${m.offset}) = htobe64(${m.value}); /* ${m.name} */
+        *(uint64_t *)(buf + ${m.offset}) = U64_HTON(${m.value}); /* ${m.name} */
 :: else:
 :: raise("unsupported push_wire_types length %d" % m.length)
 :: #endif
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index 875a34e..ee452fc 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -584,6 +584,20 @@
 }
 
 # Set to empty dict if no extension instructions defined
+extension_instruction_id_subtype = {
+    # version 1.0
+    of_g.VERSION_1_0:dict(),
+    of_g.VERSION_1_1:dict(),
+    of_g.VERSION_1_2:dict(),
+    of_g.VERSION_1_3:dict(
+        bsn = {   # of_instruction_bsn_
+            },
+        nicira = {   # of_instruction_nicira_
+            }
+        ),
+}
+
+# Set to empty dict if no extension instructions defined
 extension_queue_prop_subtype = {}
 
 # Set to empty dict if no extension instructions defined
@@ -594,6 +608,7 @@
     extension_action_subtype,
     extension_action_id_subtype,
     extension_instruction_subtype,
+    extension_instruction_id_subtype,
     extension_queue_prop_subtype,
     extension_table_feature_prop_subtype
 ]
@@ -768,6 +783,17 @@
     return cls_is_ext_obj(cls, version, extension_instruction_subtype)
 
 ################################################################
+# These are extension instruction specific
+################################################################
+
+def instruction_id_is_extension(cls, version):
+    """
+    Return True if cls, version is recognized as an instruction ID extension
+    This is brute force, searching records for a match
+    """
+    return cls_is_ext_obj(cls, version, extension_instruction_id_subtype)
+
+################################################################
 # These are extension queue_prop specific
 ################################################################
 
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index a91c859..6010880 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -877,6 +877,11 @@
     pad(4);
 };
 
+struct of_instruction_id {
+    uint16_t type;
+    uint16_t len;
+};
+
 struct of_instruction {
     uint16_t type == ?;
     uint16_t len;
@@ -1610,13 +1615,13 @@
     uint16_t         type == 0;
     uint16_t         length;
     // FIXME Check if instruction_t is right for ids here
-    list(of_instruction_t)   instruction_ids;
+    list(of_instruction_id_t)   instruction_ids;
 };
 
 struct of_table_feature_prop_instructions_miss : of_table_feature_prop {
     uint16_t         type == 1;
     uint16_t         length;
-    list(of_instruction_t)   instruction_ids;
+    list(of_instruction_id_t)   instruction_ids;
 };
 
 struct of_table_feature_prop_next_tables : of_table_feature_prop {
diff --git a/test_data/of13/instruction_id_goto_table.data b/test_data/of13/instruction_id_goto_table.data
new file mode 100644
index 0000000..e52d9c9
--- /dev/null
+++ b/test_data/of13/instruction_id_goto_table.data
@@ -0,0 +1,8 @@
+-- binary
+00 01 # type
+00 04 # length
+-- python
+ofp.instruction_id.goto_table()
+-- c
+obj = of_instruction_id_goto_table_new(OF_VERSION_1_3);
+-- java