wdp: Add new wdp_class member function 'get_table_stats'.
authorBen Pfaff <blp@nicira.com>
Tue, 29 Jun 2010 23:12:02 +0000 (16:12 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 29 Jun 2010 23:14:22 +0000 (16:14 -0700)
The wdp_stats structure is really a relic from the "master" branch.  Many
of its members do not make sense in a switch that might have an arbitrary
number of tables.  There are only a few users of this structure.  This
commit gets rid of one of these users by adding a new member function in
place of building generic functionality on top of wdp_stats information.

ofproto/ofproto.c
ofproto/wdp-provider.h
ofproto/wdp-xflow.c
ofproto/wdp.c
ofproto/wdp.h

index ebb24d1..7bb8a50 100644 (file)
 
 #include "sflow_api.h"
 
-enum {
-    TABLEID_HASH = 0,
-    TABLEID_CLASSIFIER = 1
-};
-
 struct ofproto_rule {
     uint64_t flow_cookie;       /* Controller-issued identifier. 
                                    (Kept in network-byte order.) */
@@ -1568,39 +1563,17 @@ static int
 handle_table_stats_request(struct ofproto *p, struct ofconn *ofconn,
                            struct ofp_stats_request *request)
 {
-    struct ofp_table_stats *ots;
     struct ofpbuf *msg;
-    struct wdp_stats dpstats;
-
-    msg = start_stats_reply(request, sizeof *ots * 2);
-
-    wdp_get_wdp_stats(p->wdp, &dpstats);
-
-    /* Hash table. */
-    ots = append_stats_reply(sizeof *ots, ofconn, &msg);
-    memset(ots, 0, sizeof *ots);
-    ots->table_id = TABLEID_HASH;
-    strcpy(ots->name, "hash");
-    ots->wildcards = htonl(0);
-    ots->max_entries = htonl(dpstats.exact.max_capacity);
-    ots->active_count = htonl(dpstats.exact.n_flows);
-    ots->lookup_count = htonll(dpstats.exact.n_hit + dpstats.exact.n_missed);
-    ots->matched_count = htonll(dpstats.exact.n_hit);
-
-    /* Classifier table. */
-    ots = append_stats_reply(sizeof *ots, ofconn, &msg);
-    memset(ots, 0, sizeof *ots);
-    ots->table_id = TABLEID_CLASSIFIER;
-    strcpy(ots->name, "classifier");
-    ots->wildcards = p->tun_id_from_cookie ? htonl(OVSFW_ALL)
-                                           : htonl(OFPFW_ALL);
-    ots->max_entries = htonl(dpstats.wild.max_capacity);
-    ots->active_count = htonl(dpstats.wild.n_flows);
-    ots->lookup_count = htonll(dpstats.wild.n_hit + dpstats.wild.n_missed);
-    ots->matched_count = htonll(dpstats.wild.n_hit);
+    int error;
 
-    queue_tx(msg, ofconn, ofconn->reply_counter);
-    return 0;
+    msg = start_stats_reply(request, sizeof(struct ofp_table_stats) * 3);
+    error = wdp_get_table_stats(p->wdp, msg);
+    if (!error) {
+        queue_tx(msg, ofconn, ofconn->reply_counter);
+    } else {
+        ofpbuf_delete(msg);
+    }
+    return error;
 }
 
 static void
index 40ae3fe..df49230 100644 (file)
@@ -136,6 +136,11 @@ struct wdp_class {
     /* Retrieves statistics for 'wdp' into 'stats'. */
     int (*get_stats)(const struct wdp *wdp, struct wdp_stats *stats);
 
+    /* Appends to 'stats' one or more 'struct ofp_table_stats' structures that
+     * represent the tables maintained by 'wdp'.  Returns 0 if successful,
+     * otherwise an OpenFlow error code constructed with ofp_mkerr(). */
+    int (*get_table_stats)(const struct wdp *wdp, struct ofpbuf *stats);
+
     /* Retrieves 'wdp''s current treatment of IP fragments into '*drop_frags':
      * true indicates that fragments are dropped, false indicates that
      * fragments are treated in the same way as other IP packets (except that
index d3db770..0328c5f 100644 (file)
@@ -1307,38 +1307,47 @@ wx_get_stats(const struct wdp *wdp, struct wdp_stats *stats)
 {
     struct wx *wx = wx_cast(wdp);
     struct xflow_stats xflow_stats;
-    int n_subrules;
     int error;
 
     error = xfif_get_xf_stats(wx->xfif, &xflow_stats);
+    stats->max_ports = xflow_stats.max_ports;
+    return error;
+}
 
-    n_subrules = 0;
-    classifier_for_each(&wx->cls, CLS_INC_EXACT, count_subrules, &n_subrules);
+static int
+wx_get_table_stats(const struct wdp *wdp, struct ofpbuf *stats)
+{
+    struct wx *wx = wx_cast(wdp);
+    struct xflow_stats xflow_stats;
+    struct ofp_table_stats *exact, *wild;
+    int n_subrules;
 
-    stats->exact.n_flows = classifier_count_exact(&wx->cls) - n_subrules;
-    stats->exact.cur_capacity = xflow_stats.cur_capacity;
-    stats->exact.max_capacity = MIN(WX_MAX_EXACT, xflow_stats.max_capacity);
-    stats->exact.n_hit = xflow_stats.n_hit;
-    stats->exact.n_missed = xflow_stats.n_missed;
-    stats->exact.n_lost = xflow_stats.n_lost;
-
-    stats->wild.n_flows = classifier_count_wild(&wx->cls);
-    stats->wild.cur_capacity = WX_MAX_WILD;
-    stats->wild.max_capacity = WX_MAX_WILD;
-    stats->wild.n_hit = 0;      /* XXX */
-    stats->wild.n_missed = 0;   /* XXX */
-    stats->wild.n_lost = 0;     /* XXX */
-
-    stats->n_ports = xflow_stats.n_ports;
-    stats->max_ports = xflow_stats.max_ports;
+    xfif_get_xf_stats(wx->xfif, &xflow_stats);
+    /* XXX should pass up errors, but there are no appropriate OpenFlow error
+     * codes. */
 
-    stats->n_frags = xflow_stats.n_frags;
+    n_subrules = 0;
+    classifier_for_each(&wx->cls, CLS_INC_EXACT, count_subrules, &n_subrules);
 
-    stats->max_miss_queue = xflow_stats.max_miss_queue;
-    stats->max_action_queue = xflow_stats.max_action_queue;
-    stats->max_sflow_queue = xflow_stats.max_sflow_queue;
+    exact = ofpbuf_put_zeros(stats, sizeof *exact);
+    exact->table_id = TABLEID_HASH;
+    strcpy(exact->name, "exact");
+    exact->wildcards = htonl(0);
+    exact->max_entries = htonl(MIN(WX_MAX_EXACT, xflow_stats.max_capacity));
+    exact->active_count = htonl(classifier_count_exact(&wx->cls) - n_subrules);
+    exact->lookup_count = htonll(xflow_stats.n_hit + xflow_stats.n_missed);
+    exact->matched_count = htonll(xflow_stats.n_hit);
+
+    wild = ofpbuf_put_zeros(stats, sizeof *exact);
+    wild->table_id = TABLEID_CLASSIFIER;
+    strcpy(wild->name, "classifier");
+    wild->wildcards = htonl(OVSFW_ALL);
+    wild->max_entries = htonl(WX_MAX_WILD);
+    wild->active_count = htonl(classifier_count_wild(&wx->cls));
+    wild->lookup_count = htonll(0);  /* XXX */
+    wild->matched_count = htonll(0); /* XXX */
 
-    return error;
+    return 0;
 }
 
 static int
@@ -2327,6 +2336,7 @@ wdp_xflow_register(void)
         wx_destroy,
         wx_get_features,
         wx_get_stats,
+        wx_get_table_stats,
         wx_get_drop_frags,
         wx_set_drop_frags,
         wx_port_add,
index ae5c953..771df96 100644 (file)
@@ -448,6 +448,22 @@ wdp_get_wdp_stats(const struct wdp *wdp, struct wdp_stats *stats)
     return error;
 }
 
+/* Appends to 'stats' one or more 'struct ofp_table_stats' structures that
+ * represent the tables maintained by 'wdp'.  Returns 0 if successful,
+ * otherwise an OpenFlow error code constructed with ofp_mkerr(). */
+int
+wdp_get_table_stats(const struct wdp *wdp, struct ofpbuf *stats)
+{
+    int error = wdp->wdp_class->get_table_stats(wdp, stats);
+    if (!error) {
+        assert(stats->size > sizeof(struct ofp_stats_reply));
+        assert(((stats->size - sizeof(struct ofp_stats_reply))
+                % sizeof(struct ofp_table_stats)) == 0);
+    }
+    log_operation(wdp, "get_table_stats", error);
+    return error;
+}
+
 /* Retrieves the current IP fragment handling policy for 'wdp' into
  * '*drop_frags': true indicates that fragments are dropped, false indicates
  * that fragments are treated in the same way as other IP packets (except that
index 724377b..f2dddc3 100644 (file)
 extern "C" {
 #endif
 
+enum {
+    TABLEID_HASH = 0,
+    TABLEID_CLASSIFIER = 1
+};
+
 struct ofpbuf;
 struct svec;
 struct wdp;
@@ -108,6 +113,7 @@ int wdp_delete(struct wdp *);
 
 int wdp_get_features(const struct wdp *, struct ofpbuf **featuresp);
 int wdp_get_wdp_stats(const struct wdp *, struct wdp_stats *);
+int wdp_get_table_stats(const struct wdp *, struct ofpbuf *stats);
 
 int wdp_get_drop_frags(const struct wdp *, bool *drop_frags);
 int wdp_set_drop_frags(struct wdp *, bool drop_frags);