#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.) */
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
/* 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
{
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
wx_destroy,
wx_get_features,
wx_get_stats,
+ wx_get_table_stats,
wx_get_drop_frags,
wx_set_drop_frags,
wx_port_add,
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
extern "C" {
#endif
+enum {
+ TABLEID_HASH = 0,
+ TABLEID_CLASSIFIER = 1
+};
+
struct ofpbuf;
struct svec;
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);