loci: support bsn_gentable
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index fbd9826..78a809e 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -449,6 +449,7 @@
of_object_id_t of_oxm_to_object_id(uint32_t type_len, of_version_t version);
of_object_id_t of_message_experimenter_to_object_id(of_message_t msg, of_version_t version);
of_object_id_t of_message_to_object_id(of_message_t msg, int length);
+of_object_id_t of_bsn_tlv_to_object_id(int tlv_type, of_version_t version);
int of_object_wire_init(of_object_t *obj, of_object_id_t base_object_id, int max_len);
@@ -1549,7 +1550,7 @@
m_type = "octets_data"
return "of_wire_buffer_%s_%s" % (m_type, a_type)
-def get_len_macro(cls, m_type, version):
+def get_len_macro(cls, m_name, m_type, version):
"""
Get the length macro for m_type in cls
"""
@@ -1561,6 +1562,12 @@
return "_TLV16_LEN(obj, offset)"
if cls == "of_packet_out" and m_type == "of_list_action_t":
return "_PACKET_OUT_ACTION_LEN(obj)"
+ if cls == "of_bsn_gentable_entry_add" and m_name == "key":
+ return "of_object_u16_get(obj, 18)"
+ if cls == "of_bsn_gentable_entry_desc_stats_entry" and m_name == "key":
+ return "of_object_u16_get(obj, 2)"
+ if cls == "of_bsn_gentable_entry_stats_entry" and m_name == "key":
+ return "of_object_u16_get(obj, 2)"
# Default is everything to the end of the object
return "_END_LEN(obj, offset)"
@@ -1587,6 +1594,12 @@
pass
elif (cls == "of_packet_out" and m_name == "data"):
pass
+ elif (cls == "of_bsn_gentable_entry_add" and m_name == "value"):
+ pass
+ elif (cls == "of_bsn_gentable_entry_desc_stats_entry" and m_name == "value"):
+ pass
+ elif (cls == "of_bsn_gentable_entry_stats_entry" and m_name == "stats"):
+ pass
else:
debug("Error: Unknown member with offset == -1")
debug(" cls %s, m_name %s, version %d" % (cls, m_name, version))
@@ -1601,7 +1614,7 @@
if not loxi_utils.type_is_scalar(m_type):
if loxi_utils.class_is_var_len(m_type[:-2], version) or \
m_type == "of_match_t":
- len_macro = get_len_macro(cls, m_type, version)
+ len_macro = get_len_macro(cls, m_name, m_type, version)
else:
len_macro = "%d" % of_g.base_length[(m_type[:-2], version)]
out.write(" cur_len = %s;\n" % len_macro)
@@ -1717,6 +1730,16 @@
/* Special case for setting action lengths */
_PACKET_OUT_ACTION_LEN_SET(obj, %(m_name)s->length);
""" % dict(m_name=m_name))
+ elif cls == "of_bsn_gentable_entry_add" and m_name == "key":
+ out.write("""
+ /* Special case for setting key length */
+ of_object_u16_set(obj, 18, %(m_name)s->length);
+""" % dict(m_name=m_name))
+ elif cls in ["of_bsn_gentable_entry_desc_stats_entry", "of_bsn_gentable_entry_stats_entry"] and m_name == "key":
+ out.write("""
+ /* Special case for setting key length */
+ of_object_u16_set(obj, 2, %(m_name)s->length);
+""" % dict(m_name=m_name))
elif m_type not in ["of_match_t", "of_octets_t"]:
out.write("""
/* @fixme Shouldn't this precede copying value's data to buffer? */
@@ -2357,6 +2380,10 @@
out.write("""
obj->wire_type_get = of_hello_elem_wire_object_id_get;
""")
+ if loxi_utils.class_is_bsn_tlv(cls):
+ out.write("""
+ obj->wire_type_get = of_bsn_tlv_wire_object_id_get;
+""")
if loxi_utils.class_is_oxm(cls):
out.write("""
obj->wire_length_get = of_oxm_wire_length_get;
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 4c531be..637819c 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -137,7 +137,17 @@
"of_bsn_port_counter_stats_request",
"of_bsn_port_counter_stats_reply",
"of_bsn_vlan_counter_stats_request",
- "of_bsn_vlan_counter_stats_reply"]
+ "of_bsn_vlan_counter_stats_reply",
+ "of_bsn_gentable_entry_desc_stats_request",
+ "of_bsn_gentable_entry_desc_stats_reply",
+ "of_bsn_gentable_entry_stats_request",
+ "of_bsn_gentable_entry_stats_reply",
+ "of_bsn_gentable_desc_stats_request",
+ "of_bsn_gentable_desc_stats_reply",
+ "of_bsn_gentable_stats_request",
+ "of_bsn_gentable_stats_reply",
+ "of_bsn_gentable_bucket_stats_request",
+ "of_bsn_gentable_bucket_stats_reply"]
if (cls in classes and (
m_name == "experimenter" or
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index 06161ec..d4525ba 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -151,6 +151,10 @@
gen_type_to_object_id(out, "message_type_to_id", "OF_MESSAGE",
"OF_%s", type_maps.message_types, max_type_value)
+ gen_type_to_object_id(out, "bsn_tlv_type_to_id", "OF_BSN_TLV",
+ "OF_BSN_TLV_%s", type_maps.bsn_tlv_types,
+ max_type_value)
+
def gen_type_to_obj_map_functions(out):
"""
Generate the templated type map functions
@@ -588,6 +592,12 @@
out.write(msg_template %
dict(name="message", u_name="MESSAGE", ar_len=ar_len))
+ # BSN TLV elem types array gen
+ ar_len = type_maps.type_array_len(type_maps.bsn_tlv_types,
+ max_type_value)
+ out.write(map_template %
+ dict(name="bsn_tlv", u_name="BSN_TLV", ar_len=ar_len))
+
def gen_type_data_header(out):
out.write("""
@@ -678,6 +688,8 @@
of_object_id_t *id);
extern void of_hello_elem_wire_object_id_get(of_object_t *obj,
of_object_id_t *id);
+extern void of_bsn_tlv_wire_object_id_get(of_object_t *obj,
+ of_object_id_t *id);
#define OF_OXM_LENGTH_GET(hdr) (((hdr) & 0xff) + 4)
#define OF_OXM_LENGTH_SET(hdr, val) \\
diff --git a/c_gen/c_validator_gen.py b/c_gen/c_validator_gen.py
index 126530a..9bb0407 100644
--- a/c_gen/c_validator_gen.py
+++ b/c_gen/c_validator_gen.py
@@ -222,6 +222,12 @@
%(m_name)s_offset = %(match_offset)s + OF_MATCH_BYTES(match_len);
%(m_name)s_len = len - %(m_name)s_offset;
""" % dict(m_name=m_name, cls=cls, match_offset=match_offset))
+ elif cls == "of_bsn_gentable_entry_add" and m_name == "value":
+ continue;
+ elif cls == "of_bsn_gentable_entry_desc_stats_entry" and m_name == "value":
+ continue;
+ elif cls == "of_bsn_gentable_entry_stats_entry" and m_name == "stats":
+ continue;
else:
out.write("""
diff --git a/c_gen/loxi_utils_legacy.py b/c_gen/loxi_utils_legacy.py
index 6a0fb2e..4092d4f 100644
--- a/c_gen/loxi_utils_legacy.py
+++ b/c_gen/loxi_utils_legacy.py
@@ -118,6 +118,8 @@
return True
if cls == "of_match_v4":
return True
+ if cls.find("of_bsn_tlv") == 0:
+ return True
return False
def class_is_u16_len(cls):
@@ -126,7 +128,9 @@
"""
return cls in ["of_group_desc_stats_entry", "of_group_stats_entry",
"of_flow_stats_entry", "of_bucket", "of_table_features",
- "of_bsn_port_counter_stats_entry", "of_bsn_vlan_counter_stats_entry"]
+ "of_bsn_port_counter_stats_entry", "of_bsn_vlan_counter_stats_entry",
+ "of_bsn_gentable_entry_desc_stats_entry", "of_bsn_gentable_entry_stats_entry",
+ "of_bsn_gentable_desc_stats_entry"]
def class_is_oxm(cls):
"""
@@ -246,6 +250,14 @@
"""
return (cls.find("of_list_") == 0)
+def class_is_bsn_tlv(cls):
+ """
+ Return True if cls_name is a BSN TLV object
+ """
+ if cls.find("of_bsn_tlv") == 0:
+ return True
+ return False
+
def type_is_of_object(m_type):
"""
Return True if m_type is an OF object type
diff --git a/c_gen/of_g_legacy.py b/c_gen/of_g_legacy.py
index 08f13ef..1fadba0 100644
--- a/c_gen/of_g_legacy.py
+++ b/c_gen/of_g_legacy.py
@@ -77,7 +77,7 @@
## These members do not get normal accessors
skip_members = ["version", "type", "length", "err_type", "stats_type", "len",
- "type_len", "actions_len", "_command", "command"]
+ "type_len", "actions_len", "_command", "command", "key_length"]
## Some OpenFlow string length constants
#
diff --git a/c_gen/templates/loci_int.h b/c_gen/templates/loci_int.h
index 241cf7b..01ad4a8 100644
--- a/c_gen/templates/loci_int.h
+++ b/c_gen/templates/loci_int.h
@@ -277,4 +277,21 @@
((object_id) == OF_FLOW_DELETE_STRICT) || \
((object_id) == OF_FLOW_ADD))
+/**
+ * Macro to calculate variable offset of value member in of_bsn_gentable_entry_add
+ * @param obj An object of type of_bsn_gentable_entry_add_t
+ */
+
+#define _BSN_GENTABLE_ENTRY_ADD_VALUE_OFFSET(obj) \
+ (of_object_u16_get(obj, 18) + \
+ of_object_fixed_len[(obj)->version][OF_BSN_GENTABLE_ENTRY_ADD])
+
+#define _BSN_GENTABLE_ENTRY_DESC_STATS_ENTRY_VALUE_OFFSET(obj) \
+ (of_object_u16_get(obj, 2) + \
+ of_object_fixed_len[(obj)->version][OF_BSN_GENTABLE_ENTRY_DESC_STATS_ENTRY])
+
+#define _BSN_GENTABLE_ENTRY_STATS_ENTRY_STATS_OFFSET(obj) \
+ (of_object_u16_get(obj, 2) + \
+ of_object_fixed_len[(obj)->version][OF_BSN_GENTABLE_ENTRY_STATS_ENTRY])
+
#endif /* __LOCI_INT_H__ */
diff --git a/c_gen/templates/loci_show.h b/c_gen/templates/loci_show.h
index 8241f3e..1856ae5 100644
--- a/c_gen/templates/loci_show.h
+++ b/c_gen/templates/loci_show.h
@@ -375,5 +375,12 @@
#define LOCI_SHOW_u64_time_ms(writer, cookie, val) LOCI_SHOW_u64(writer, cookie, val)
#define LOCI_SHOW_desc_str_uri(writer, cookie, val) LOCI_SHOW_desc_str(writer, cookie, val)
#define LOCI_SHOW_u8_state(writer, cookie, val) LOCI_SHOW_u8(writer, cookie, val)
+#define LOCI_SHOW_u16_table_id(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
+#define LOCI_SHOW_u32_deleted_count(writer, cookie, val) LOCI_SHOW_u32(writer, cookie, val)
+#define LOCI_SHOW_u32_error_count(writer, cookie, val) LOCI_SHOW_u32(writer, cookie, val)
+#define LOCI_SHOW_checksum_128_checksum(writer, cookie, val) LOCI_SHOW_checksum_128(writer, cookie, val)
+#define LOCI_SHOW_checksum_128_checksum_mask(writer, cookie, val) LOCI_SHOW_checksum_128(writer, cookie, val)
+#define LOCI_SHOW_u32_buckets_size(writer, cookie, val) LOCI_SHOW_u32(writer, cookie, val)
+#define LOCI_SHOW_u32_entry_count(writer, cookie, val) LOCI_SHOW_u32(writer, cookie, val)
#endif /* _LOCI_SHOW_H_ */
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index 7310988..15b3816 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -446,6 +446,23 @@
ASSERT(*id != OF_OBJECT_INVALID);
}
+/**
+ * Get the object ID based on the wire buffer for a bsn_tlv object
+ * @param obj The object being referenced
+ * @param id Where to store the object ID
+ */
+
+void
+of_bsn_tlv_wire_object_id_get(of_object_t *obj, of_object_id_t *id)
+{
+ int wire_type;
+
+ of_tlv16_wire_type_get(obj, &wire_type);
+ ASSERT(wire_type >= 0 && wire_type < OF_BSN_TLV_ITEM_COUNT);
+ *id = of_bsn_tlv_type_to_id[obj->version][wire_type];
+ ASSERT(*id != OF_OBJECT_INVALID);
+}
+
/****************************************************************
* OXM type/length functions.
****************************************************************/
@@ -715,7 +732,12 @@
case OF_EXPERIMENTER_ID_BSN:
switch (subtype) {
case 1: return OF_BSN_LACP_STATS_REQUEST;
+ case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REQUEST;
+ case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REQUEST;
+ case 4: return OF_BSN_GENTABLE_DESC_STATS_REQUEST;
+ case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REQUEST;
case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REQUEST;
+ case 7: return OF_BSN_GENTABLE_STATS_REQUEST;
case 8: return OF_BSN_PORT_COUNTER_STATS_REQUEST;
case 9: return OF_BSN_VLAN_COUNTER_STATS_REQUEST;
}
@@ -730,7 +752,12 @@
case OF_EXPERIMENTER_ID_BSN:
switch (subtype) {
case 1: return OF_BSN_LACP_STATS_REPLY;
+ case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REPLY;
+ case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REPLY;
+ case 4: return OF_BSN_GENTABLE_DESC_STATS_REPLY;
+ case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REPLY;
case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REPLY;
+ case 7: return OF_BSN_GENTABLE_STATS_REPLY;
case 8: return OF_BSN_PORT_COUNTER_STATS_REPLY;
case 9: return OF_BSN_VLAN_COUNTER_STATS_REPLY;
}
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index f285a33..2a53519 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -136,6 +136,13 @@
of_g.VERSION_1_3:dict(),
}
+bsn_tlv_types = {
+ of_g.VERSION_1_0:dict(),
+ of_g.VERSION_1_1:dict(),
+ of_g.VERSION_1_2:dict(),
+ of_g.VERSION_1_3:dict(),
+ }
+
# All inheritance data for non-messages
inheritance_data = dict(
of_instruction = instruction_types,
@@ -148,7 +155,8 @@
of_table_feature_prop = table_feature_prop_types,
of_meter_band = meter_band_types,
# BSN specific inheritance extensions
- of_bsn_vport = bsn_vport_types
+ of_bsn_vport = bsn_vport_types,
+ of_bsn_tlv = bsn_tlv_types,
)
def class_is_virtual(cls):