loci: support of_bsn_lacp_stats_request/reply
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index d237cfe..e1b6913 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -128,6 +128,11 @@
m_name == "experimenter" or
m_name == "subtype")):
return True
+
+ if (cls in ["of_bsn_lacp_stats_request", "of_bsn_lacp_stats_reply"] and (
+ m_name == "experimenter" or
+ m_name == "subtype")):
+ return True
return loxi_utils.skip_member_name(m_name) or m_type not in scalar_types
def gen_fill_string(out):
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index 8883193..4fc1652 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -503,6 +503,7 @@
uint16_t stats_type;
uint16_t err_type;
uint8_t flow_mod_cmd;
+ uint32_t experimenter, subtype;
if (length < OF_MESSAGE_MIN_LENGTH) {
return OF_OBJECT_INVALID;
@@ -541,10 +542,23 @@
return OF_OBJECT_INVALID;
}
stats_type = of_message_stats_type_get(msg);
- if (obj_id == OF_STATS_REQUEST) {
- obj_id = of_stats_request_to_object_id(stats_type, ver);
+ if (stats_type == OF_STATS_TYPE_EXPERIMENTER) {
+ if (length < OF_MESSAGE_STATS_EXPERIMENTER_MIN_LENGTH) {
+ return OF_OBJECT_INVALID;
+ }
+ experimenter = of_message_stats_experimenter_id_get(msg);
+ subtype = of_message_stats_experimenter_subtype_get(msg);
+ if (obj_id == OF_STATS_REQUEST) {
+ obj_id = of_experimenter_stats_request_to_object_id(experimenter, subtype, ver);
+ } else {
+ obj_id = of_experimenter_stats_reply_to_object_id(experimenter, subtype, ver);
+ }
} else {
- obj_id = of_stats_reply_to_object_id(stats_type, ver);
+ if (obj_id == OF_STATS_REQUEST) {
+ obj_id = of_stats_request_to_object_id(stats_type, ver);
+ } else {
+ obj_id = of_stats_reply_to_object_id(stats_type, ver);
+ }
}
}
@@ -945,6 +959,9 @@
* top level message: Action, instruction, error, stats, queue_props, oxm
*/
#define OF_EXPERIMENTER_TYPE 0xffff
+
+int of_experimenter_stats_request_to_object_id(uint32_t experimenter, uint32_t subtype, int ver);
+int of_experimenter_stats_reply_to_object_id(uint32_t experimenter, uint32_t subtype, int ver);
""")
gen_type_to_obj_map_functions(out)
gen_obj_to_type_map_functions(out)
@@ -1047,6 +1064,17 @@
if ((type = of_object_to_stats_type(id, ver)) >= 0) {
/* It's a stats obj */
of_message_stats_type_set(msg, type);
+ if (type == OF_STATS_TYPE_EXPERIMENTER) {
+ switch (id) {
+ case OF_BSN_LACP_STATS_REQUEST:
+ case OF_BSN_LACP_STATS_REPLY:
+ of_message_stats_experimenter_id_set(msg, OF_EXPERIMENTER_ID_BSN);
+ of_message_stats_experimenter_subtype_set(msg, 1);
+ break;
+ default:
+ break;
+ }
+ }
}
if ((type = of_object_to_error_type(id, ver)) >= 0) {
/* It's an error obj */
diff --git a/c_gen/templates/of_message.h b/c_gen/templates/of_message.h
index 165fe51..c1b6785 100644
--- a/c_gen/templates/of_message.h
+++ b/c_gen/templates/of_message.h
@@ -58,6 +58,10 @@
#define OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET 12
#define OF_MESSAGE_EXPERIMENTER_MIN_LENGTH 16
+#define OF_MESSAGE_STATS_EXPERIMENTER_ID_OFFSET 16
+#define OF_MESSAGE_STATS_EXPERIMENTER_SUBTYPE_OFFSET 20
+#define OF_MESSAGE_STATS_EXPERIMENTER_MIN_LENGTH 24
+
/**
* The "default" free message function; NULL means use nominal malloc/free
*/
@@ -270,4 +274,42 @@
}
}
+/**
+ * @brief Get/set stats request/reply experimenter ID of a message
+ * @param msg Pointer to the message buffer of sufficient length
+ * @param experimenter_id Data for set operation
+ * @returns get returns experimenter id in host order
+ */
+
+static inline uint32_t
+of_message_stats_experimenter_id_get(of_message_t msg) {
+ uint32_t val;
+ buf_u32_get(msg + OF_MESSAGE_STATS_EXPERIMENTER_ID_OFFSET, &val);
+ return val;
+}
+
+static inline void
+of_message_stats_experimenter_id_set(of_message_t msg, uint32_t experimenter_id) {
+ buf_u32_set(msg + OF_MESSAGE_STATS_EXPERIMENTER_ID_OFFSET, experimenter_id);
+}
+
+/**
+ * @brief Get/set stats request/reply experimenter subtype of a message
+ * @param msg Pointer to the message buffer of sufficient length
+ * @param subtype Data for set operation
+ * @returns get returns experimenter subtype in host order
+ */
+
+static inline uint32_t
+of_message_stats_experimenter_subtype_get(of_message_t msg) {
+ uint32_t val;
+ buf_u32_get(msg + OF_MESSAGE_STATS_EXPERIMENTER_SUBTYPE_OFFSET, &val);
+ return val;
+}
+
+static inline void
+of_message_stats_experimenter_subtype_set(of_message_t msg, uint32_t subtype) {
+ buf_u32_set(msg + OF_MESSAGE_STATS_EXPERIMENTER_SUBTYPE_OFFSET, subtype);
+}
+
#endif /* _OF_MESSAGE_H_ */
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index fabd25f..30c73ac 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -840,3 +840,27 @@
return OF_ERROR_NONE;
}
+
+int
+of_experimenter_stats_request_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
+{
+ switch (experimenter) {
+ case OF_EXPERIMENTER_ID_BSN:
+ switch (subtype) {
+ case 1: return OF_BSN_LACP_STATS_REQUEST;
+ }
+ }
+ return OF_OBJECT_INVALID;
+}
+
+int
+of_experimenter_stats_reply_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
+{
+ switch (experimenter) {
+ case OF_EXPERIMENTER_ID_BSN:
+ switch (subtype) {
+ case 1: return OF_BSN_LACP_STATS_REPLY;
+ }
+ }
+ return OF_OBJECT_INVALID;
+}