From 840ee2faf6557892c0ce25d91f79a3ca144e3b70 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 29 Jun 2010 16:12:02 -0700 Subject: [PATCH] wdp: Add new wdp_class member function 'get_table_stats'. 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 | 45 +++++++------------------------- ofproto/wdp-provider.h | 5 ++++ ofproto/wdp-xflow.c | 58 +++++++++++++++++++++++++----------------- ofproto/wdp.c | 16 ++++++++++++ ofproto/wdp.h | 6 +++++ 5 files changed, 70 insertions(+), 60 deletions(-) diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index ebb24d1b0..7bb8a500b 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -64,11 +64,6 @@ #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 diff --git a/ofproto/wdp-provider.h b/ofproto/wdp-provider.h index 40ae3fe39..df492300b 100644 --- a/ofproto/wdp-provider.h +++ b/ofproto/wdp-provider.h @@ -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 diff --git a/ofproto/wdp-xflow.c b/ofproto/wdp-xflow.c index d3db77028..0328c5fdf 100644 --- a/ofproto/wdp-xflow.c +++ b/ofproto/wdp-xflow.c @@ -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, diff --git a/ofproto/wdp.c b/ofproto/wdp.c index ae5c95316..771df9611 100644 --- a/ofproto/wdp.c +++ b/ofproto/wdp.c @@ -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 diff --git a/ofproto/wdp.h b/ofproto/wdp.h index 724377b93..f2dddc369 100644 --- a/ofproto/wdp.h +++ b/ofproto/wdp.h @@ -24,6 +24,11 @@ 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); -- 2.47.0