{ OFPUTIL_NXT_FLOW_MOD_TABLE_ID, OFP10_VERSION,
NXT_FLOW_MOD_TABLE_ID, "NXT_FLOW_MOD_TABLE_ID",
sizeof(struct nx_flow_mod_table_id), 0 },
+
+ { OFPUTIL_NXT_FLOW_AGE, OFP10_VERSION,
+ NXT_FLOW_AGE, "NXT_FLOW_AGE",
+ sizeof(struct nicira_header), 0 },
};
static const struct ofputil_msg_category nxt_category = {
* iterates through the replies. The caller must initially leave 'msg''s layer
* pointers null and not modify them between calls.
*
+ * Most switches don't send the values needed to populate fs->idle_age and
+ * fs->hard_age, so those members will usually be set to 0. If the switch from
+ * which 'msg' originated is known to implement NXT_FLOW_AGE, then pass
+ * 'flow_age_extension' as true so that the contents of 'msg' determine the
+ * 'idle_age' and 'hard_age' members in 'fs'.
+ *
* Returns 0 if successful, EOF if no replies were left in this 'msg',
* otherwise a positive errno value. */
int
ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
- struct ofpbuf *msg)
+ struct ofpbuf *msg,
+ bool flow_age_extension)
{
const struct ofputil_msg_type *type;
int code;
fs->duration_nsec = ntohl(ofs->duration_nsec);
fs->idle_timeout = ntohs(ofs->idle_timeout);
fs->hard_timeout = ntohs(ofs->hard_timeout);
+ fs->idle_age = -1;
+ fs->hard_age = -1;
fs->packet_count = ntohll(get_32aligned_be64(&ofs->packet_count));
fs->byte_count = ntohll(get_32aligned_be64(&ofs->byte_count));
} else if (code == OFPUTIL_NXST_FLOW_REPLY) {
fs->duration_nsec = ntohl(nfs->duration_nsec);
fs->idle_timeout = ntohs(nfs->idle_timeout);
fs->hard_timeout = ntohs(nfs->hard_timeout);
+ fs->idle_age = -1;
+ fs->hard_age = -1;
+ if (flow_age_extension) {
+ if (nfs->idle_age) {
+ fs->idle_age = ntohs(nfs->idle_age) - 1;
+ }
+ if (nfs->hard_age) {
+ fs->hard_age = ntohs(nfs->hard_age) - 1;
+ }
+ }
fs->packet_count = ntohll(nfs->packet_count);
fs->byte_count = ntohll(nfs->byte_count);
} else {
nfs->priority = htons(fs->rule.priority);
nfs->idle_timeout = htons(fs->idle_timeout);
nfs->hard_timeout = htons(fs->hard_timeout);
+ nfs->idle_age = htons(fs->idle_age < 0 ? 0
+ : fs->idle_age < UINT16_MAX ? fs->idle_age + 1
+ : UINT16_MAX);
+ nfs->hard_age = htons(fs->hard_age < 0 ? 0
+ : fs->hard_age < UINT16_MAX ? fs->hard_age + 1
+ : UINT16_MAX);
nfs->match_len = htons(nx_put_match(msg, &fs->rule, 0, 0));
- memset(nfs->pad2, 0, sizeof nfs->pad2);
nfs->cookie = fs->cookie;
nfs->packet_count = htonll(fs->packet_count);
nfs->byte_count = htonll(fs->byte_count);