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