ofproto: Improve resolution of flow stats and removed messages (OpenFlow 1.0)
[sliver-openvswitch.git] / ofproto / ofproto.c
index 325a11d..5d61b70 100644 (file)
@@ -1853,7 +1853,8 @@ handle_features_request(struct ofproto *p, struct ofconn *ofconn,
     osf->n_buffers = htonl(pktbuf_capacity());
     osf->n_tables = 2;
     osf->capabilities = htonl(OFPC_FLOW_STATS | OFPC_TABLE_STATS |
-                              OFPC_PORT_STATS | OFPC_MULTI_PHY_TX);
+                              OFPC_PORT_STATS | OFPC_MULTI_PHY_TX |
+                              OFPC_ARP_MATCH_IP);
     osf->actions = htonl((1u << OFPAT_OUTPUT) |
                          (1u << OFPAT_SET_VLAN_VID) |
                          (1u << OFPAT_SET_VLAN_PCP) |
@@ -2545,6 +2546,9 @@ flow_stats_cb(struct cls_rule *rule_, void *cbdata_)
     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;
@@ -2560,7 +2564,8 @@ flow_stats_cb(struct cls_rule *rule_, void *cbdata_)
     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);
@@ -2628,7 +2633,7 @@ flow_stats_ds_cb(struct cls_rule *rule_, void *cbdata_)
     }
 
     query_stats(cbdata->ofproto, rule, &packet_count, &byte_count);
-    flow_to_ovs_match(&rule->cr.flow, rule->cr.wc.wildcards, &match);
+    flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, &match);
 
     ds_put_format(results, "duration=%llds, ",
                   (time_msec() - rule->created) / 1000);
@@ -3299,13 +3304,17 @@ compose_flow_removed(const struct rule *rule, long long int now, uint8_t reason)
     struct ofp_flow_removed *ofr;
     struct ofpbuf *buf;
     long long int last_used = rule->used ? now - rule->used : 0;
+    long long int tdiff = time_msec() - rule->created - last_used;
+    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 - last_used) / 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);