uint8_t reason; /* One of OFPRR_*. */
uint8_t pad[1]; /* Align to 32-bits. */
- uint32_t duration; /* Time flow was alive in seconds. */
+ uint32_t duration_sec; /* Time flow was alive in seconds. */
+ uint32_t duration_nsec; /* Time flow was alive in nanoseconds beyond
+ duration_sec. */
uint16_t idle_timeout; /* Idle timeout from original flow mod. */
- uint8_t pad2[6]; /* Align to 64-bits. */
+ uint8_t pad2[2]; /* Align to 64-bits. */
uint64_t packet_count;
uint64_t byte_count;
};
uint8_t table_id; /* ID of table flow came from. */
uint8_t pad;
struct ofp_match match; /* Description of fields. */
- uint32_t duration; /* Time flow has been alive in seconds. */
+ uint32_t duration_sec; /* Time flow has been alive in seconds. */
+ uint32_t duration_nsec; /* Time flow has been alive in nanoseconds
+ beyond duration_sec. */
uint16_t priority; /* Priority of the entry. Only meaningful
when this is not an exact-match entry. */
uint16_t idle_timeout; /* Number of seconds idle before expiration. */
uint16_t hard_timeout; /* Number of seconds before expiration. */
- uint8_t pad2[2]; /* Align to 64 bits. */
+ uint8_t pad2[6]; /* Align to 64 bits. */
uint64_t cookie; /* Opaque controller-issued identifier. */
uint64_t packet_count; /* Number of packets in flow. */
uint64_t byte_count; /* Number of bytes in flow. */
struct ofp_action_header actions[0]; /* Actions. */
};
-OFP_ASSERT(sizeof(struct ofp_flow_stats) == 80);
+OFP_ASSERT(sizeof(struct ofp_flow_stats) == 88);
/* Body for ofp_stats_request of type OFPST_AGGREGATE. */
struct ofp_aggregate_stats_request {
break;
}
ds_put_format(string,
- " cookie%"PRIx64" pri%"PRIu16" secs%"PRIu32" idle%"PRIu16
- " pkts%"PRIu64" bytes%"PRIu64"\n", ntohll(ofr->cookie),
+ " cookie%"PRIx64" pri%"PRIu16" secs%"PRIu32" nsecs%"PRIu32
+ " idle%"PRIu16" pkts%"PRIu64" bytes%"PRIu64"\n",
+ ntohll(ofr->cookie),
ofr->match.wildcards ? ntohs(ofr->priority) : (uint16_t)-1,
- ntohl(ofr->duration), ntohs(ofr->idle_timeout),
- ntohll(ofr->packet_count), ntohll(ofr->byte_count));
+ ntohl(ofr->duration_sec), ntohl(ofr->duration_nsec),
+ ntohs(ofr->idle_timeout), ntohll(ofr->packet_count),
+ ntohll(ofr->byte_count));
}
static void
}
ds_put_format(string, " cookie=%"PRIu64"s, ", ntohll(fs->cookie));
- ds_put_format(string, "duration=%"PRIu32"s, ", ntohl(fs->duration));
+ ds_put_format(string, "duration_sec=%"PRIu32"s, ",
+ ntohl(fs->duration_sec));
+ ds_put_format(string, "duration_nsec=%"PRIu32"s, ",
+ ntohl(fs->duration_nsec));
ds_put_format(string, "table_id=%"PRIu8", ", fs->table_id);
ds_put_format(string, "priority=%"PRIu16", ",
fs->match.wildcards ? ntohs(fs->priority) : (uint16_t)-1);
struct ofp_flow_stats *ofs;
uint64_t packet_count, byte_count;
size_t act_len, len;
+ long long int tdiff = time_msec() - rule->created;
+ uint32_t sec = tdiff / 1000;
+ uint32_t msec = tdiff - (sec * 1000);
if (rule_is_hidden(rule) || !rule_has_out_port(rule, cbdata->out_port)) {
return;
ofs->table_id = rule->cr.wc.wildcards ? TABLEID_CLASSIFIER : TABLEID_HASH;
ofs->pad = 0;
flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, &ofs->match);
- ofs->duration = htonl((time_msec() - rule->created) / 1000);
+ ofs->duration_sec = htonl(sec);
+ ofs->duration_nsec = htonl(msec * 1000000);
ofs->cookie = rule->flow_cookie;
ofs->priority = htons(rule->cr.priority);
ofs->idle_timeout = htons(rule->idle_timeout);
{
struct ofp_flow_removed *ofr;
struct ofpbuf *buf;
+ long long int tdiff = time_msec() - rule->created;
+ uint32_t sec = tdiff / 1000;
+ uint32_t msec = tdiff - (sec * 1000);
ofr = make_openflow(sizeof *ofr, OFPT_FLOW_REMOVED, &buf);
flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, &ofr->match);
ofr->cookie = rule->flow_cookie;
ofr->priority = htons(rule->cr.priority);
ofr->reason = reason;
- ofr->duration = htonl((now - rule->created) / 1000);
+ ofr->duration_sec = htonl(sec);
+ ofr->duration_nsec = htonl(msec * 1000000);
ofr->idle_timeout = htons(rule->idle_timeout);
ofr->packet_count = htonll(rule->packet_count);
ofr->byte_count = htonll(rule->byte_count);