In some cases, when a facet's actions change because it resubmits
into a different rule.  It will account all packets it as accrued
in the datapath to the new rule.  Due to the algorithm we are
using, it is acceptable for a facet to miscount at most 1 second
worth of packets in this manor.  This patch implements the proper
behavior.
---
 ofproto/ofproto.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 445f0d2..7bd060d 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1640,19 +1640,33 @@ facet_put__(struct ofproto *ofproto, struct facet 
*facet,
     struct odputil_keybuf keybuf;
     enum dpif_flow_put_flags flags;
     struct ofpbuf key;
+    int ret;
 
     flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
     if (stats) {
         flags |= DPIF_FP_ZERO_STATS;
-        facet->dp_packet_count = 0;
-        facet->dp_byte_count = 0;
     }
 
     ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
     odp_flow_key_from_flow(&key, &facet->flow);
 
-    return dpif_flow_put(ofproto->dpif, flags, key.data, key.size,
-                         actions, actions_len, stats);
+    ret = dpif_flow_put(ofproto->dpif, flags, key.data, key.size,
+                        actions, actions_len, stats);
+
+    if (stats) {
+        if (facet->dp_packet_count <= stats->n_packets
+            && facet->dp_byte_count <= stats->n_bytes) {
+            stats->n_packets -= facet->dp_packet_count;
+            stats->n_bytes -= facet->dp_byte_count;
+        } else {
+            VLOG_WARN_RL(&rl, "inconsistent statistics from datapath"
+                         " during flow put");
+        }
+        facet->dp_packet_count = 0;
+        facet->dp_byte_count = 0;
+    }
+
+    return ret;
 }
 
 /* If 'facet' is installable, inserts or re-inserts it into 'p''s datapath.  If
-- 
1.7.4.4

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to