ofproto-dpif: Don't count misses in OpenFlow table stats.
authorJesse Gross <jesse@nicira.com>
Sat, 25 May 2013 00:01:34 +0000 (17:01 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 5 Jun 2013 17:37:16 +0000 (10:37 -0700)
Originally no rule existed for packets that did not match an
OpenFlow flow and therefore every packet with a rule could be
counted as a hit. However, newer versions of OVS have hidden
miss rules so this is no longer true. To return the correct
table stats, this subtracts packets that hit the miss rule
from the total and removes the separate counter.

Reported-by: love you <thunder.love07@gmail.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
ofproto/ofproto-dpif.c

index a3b1153..86f4f20 100644 (file)
@@ -118,6 +118,7 @@ static struct rule_dpif *rule_dpif_lookup__(struct ofproto_dpif *,
 static struct rule_dpif *rule_dpif_miss_rule(struct ofproto_dpif *ofproto,
                                              const struct flow *flow);
 
+static void rule_get_stats(struct rule *, uint64_t *packets, uint64_t *bytes);
 static void rule_credit_stats(struct rule_dpif *,
                               const struct dpif_flow_stats *);
 static void flow_push_stats(struct facet *, const struct dpif_flow_stats *);
@@ -683,9 +684,6 @@ struct ofproto_dpif {
     struct rule_dpif *miss_rule; /* Sends flow table misses to controller. */
     struct rule_dpif *no_packet_in_rule; /* Drops flow table misses. */
 
-    /* Statistics. */
-    uint64_t n_matches;
-
     /* Bridging. */
     struct netflow *netflow;
     struct dpif_sflow *sflow;
@@ -1339,8 +1337,6 @@ construct(struct ofproto *ofproto_)
     max_ports = dpif_get_max_ports(ofproto->backer->dpif);
     ofproto_init_max_ports(ofproto_, MIN(max_ports, OFPP_MAX));
 
-    ofproto->n_matches = 0;
-
     ofproto->netflow = NULL;
     ofproto->sflow = NULL;
     ofproto->stp = NULL;
@@ -1730,13 +1726,18 @@ get_tables(struct ofproto *ofproto_, struct ofp12_table_stats *ots)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
     struct dpif_dp_stats s;
+    uint64_t n_miss, n_no_pkt_in, n_bytes;
+    uint64_t n_lookup;
 
     strcpy(ots->name, "classifier");
 
     dpif_get_dp_stats(ofproto->backer->dpif, &s);
+    rule_get_stats(&ofproto->miss_rule->up, &n_miss, &n_bytes);
+    rule_get_stats(&ofproto->no_packet_in_rule->up, &n_no_pkt_in, &n_bytes);
 
-    ots->lookup_count = htonll(s.n_hit + s.n_missed);
-    ots->matched_count = htonll(s.n_hit + ofproto->n_matches);
+    n_lookup = s.n_hit + s.n_missed;
+    ots->lookup_count = htonll(n_lookup);
+    ots->matched_count = htonll(n_lookup - n_miss - n_no_pkt_in);
 }
 
 static struct ofport *
@@ -3562,8 +3563,6 @@ handle_flow_miss_common(struct rule_dpif *rule,
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto);
 
-    ofproto->n_matches++;
-
     if (rule->up.cr.priority == FAIL_OPEN_PRIORITY) {
         /*
          * Extra-special case for fail-open mode.