@@ -1,5 +1,7 @@
Post-v4.0.0
--------------------
+ - ovs-appctl:
+ * Added JSON output support (--format json) for 'fdb/stats-show'.
v4.0.0 - xx xxx xxxx
@@ -6437,43 +6437,89 @@ ofproto_unixctl_fdb_stats_clear(struct unixctl_conn *conn, int argc,
unixctl_command_reply(conn, "statistics successfully cleared");
}
+static struct json *
+ofproto_unixctl_fdb_stats_show_json(const struct ofproto_dpif *ofproto)
+{
+ struct json *entries = json_object_create();
+ struct json *events = json_object_create();
+ struct json *bridge = json_object_create();
+ struct json *json = json_object_create();
+
+ ovs_rwlock_rdlock(&ofproto->ml->rwlock);
+ json_object_put(entries, "current",
+ json_integer_create(hmap_count(&ofproto->ml->table)));
+ json_object_put(entries, "maximum",
+ json_integer_create(ofproto->ml->max_entries));
+ json_object_put(entries, "static",
+ json_integer_create(ofproto->ml->static_entries));
+ json_object_put(bridge, "entries", entries);
+
+ json_object_put(events, "evicted",
+ json_integer_create(ofproto->ml->total_evicted));
+ json_object_put(events, "expired",
+ json_integer_create(ofproto->ml->total_expired));
+ json_object_put(events, "learned",
+ json_integer_create(ofproto->ml->total_learned));
+ json_object_put(events, "moved",
+ json_integer_create(ofproto->ml->total_moved));
+ json_object_put(bridge, "events", events);
+ ovs_rwlock_unlock(&ofproto->ml->rwlock);
+
+ json_object_put(json, ofproto->up.name, bridge);
+ return json;
+}
+
+static void
+ofproto_unixctl_fdb_stats_show_text(const struct ofproto_dpif *ofproto,
+ struct ds *ds)
+{
+ ovs_rwlock_rdlock(&ofproto->ml->rwlock);
+ ds_put_format(ds, "Statistics for bridge \"%s\":\n", ofproto->up.name);
+ ds_put_format(ds, " Current/maximum MAC entries in the table: %"
+ PRIuSIZE"/%"PRIuSIZE"\n",
+ hmap_count(&ofproto->ml->table),
+ ofproto->ml->max_entries);
+ ds_put_format(ds,
+ " Current static MAC entries in the table : %"
+ PRIuSIZE"\n", ofproto->ml->static_entries);
+ ds_put_format(ds,
+ " Total number of learned MAC entries : %"
+ PRIu64"\n", ofproto->ml->total_learned);
+ ds_put_format(ds,
+ " Total number of expired MAC entries : %"
+ PRIu64"\n", ofproto->ml->total_expired);
+ ds_put_format(ds,
+ " Total number of evicted MAC entries : %"
+ PRIu64"\n", ofproto->ml->total_evicted);
+ ds_put_format(ds,
+ " Total number of port moved MAC entries : %"
+ PRIu64"\n", ofproto->ml->total_moved);
+ ovs_rwlock_unlock(&ofproto->ml->rwlock);
+}
+
static void
ofproto_unixctl_fdb_stats_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
const char *argv[], void *aux OVS_UNUSED)
{
- struct ds ds = DS_EMPTY_INITIALIZER;
const struct ofproto_dpif *ofproto;
+
ofproto = ofproto_dpif_lookup_by_name(argv[1]);
if (!ofproto) {
unixctl_command_reply_error(conn, "no such bridge");
return;
}
- ds_put_format(&ds, "Statistics for bridge \"%s\":\n", argv[1]);
- ovs_rwlock_rdlock(&ofproto->ml->rwlock);
+ if (unixctl_command_get_output_format(conn) == UNIXCTL_OUTPUT_FMT_JSON) {
+ struct json *json = ofproto_unixctl_fdb_stats_show_json(ofproto);
- ds_put_format(&ds, " Current/maximum MAC entries in the table: %"
- PRIuSIZE"/%"PRIuSIZE"\n",
- hmap_count(&ofproto->ml->table), ofproto->ml->max_entries);
- ds_put_format(&ds,
- " Current static MAC entries in the table : %"PRIuSIZE"\n",
- ofproto->ml->static_entries);
- ds_put_format(&ds,
- " Total number of learned MAC entries : %"PRIu64"\n",
- ofproto->ml->total_learned);
- ds_put_format(&ds,
- " Total number of expired MAC entries : %"PRIu64"\n",
- ofproto->ml->total_expired);
- ds_put_format(&ds,
- " Total number of evicted MAC entries : %"PRIu64"\n",
- ofproto->ml->total_evicted);
- ds_put_format(&ds,
- " Total number of port moved MAC entries : %"PRIu64"\n",
- ofproto->ml->total_moved);
+ unixctl_command_reply_json(conn, json);
+ } else {
+ struct ds ds = DS_EMPTY_INITIALIZER;
- ovs_rwlock_unlock(&ofproto->ml->rwlock);
- unixctl_command_reply(conn, ds_cstr(&ds));
- ds_destroy(&ds);
+ ofproto_unixctl_fdb_stats_show_text(ofproto, &ds);
+ unixctl_command_reply(conn, ds_cstr(&ds));
+ ds_destroy(&ds);
+ }
}
static void
@@ -8303,6 +8303,21 @@ AT_CHECK_UNQUOTED([ovs-appctl fdb/stats-show br0 | grep static], [0], [dnl
Current static MAC entries in the table : 17
])
+dnl Check JSON output.
+AT_CHECK([ovs-appctl --format json --pretty fdb/stats-show br0], [0], [dnl
+{
+ "br0": {
+ "entries": {
+ "current": 17,
+ "maximum": 8192,
+ "static": 17},
+ "events": {
+ "evicted": 0,
+ "expired": 0,
+ "learned": 18,
+ "moved": 0}}}
+])
+
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -191,6 +191,9 @@ Clear \fIbridge\fR MAC address learning table statistics, or all
statistics if no \fIbridge\fR is given.
.IP "\fBfdb/stats-show\fR \fIbridge\fR"
Show MAC address learning table statistics for the specified \fIbridge\fR.
+JSON output is an object keyed by bridge name, whose value holds an
+"entries" object with the current, maximum and static entry counts and an
+"events" object with the evicted, expired, learned and moved counters.
.IP "\fBmdb/flush\fR [\fIbridge\fR]"
Flushes \fIbridge\fR multicast snooping table, or all snooping tables
if no \fIbridge\fR is given.
When --format json is passed to ovs-appctl, fdb/stats-show returns a JSON object keyed by bridge name. Each bridge contains two sub-objects: "entries" (with "current", "maximum", and "static" counts) and "events" (with "evicted", "expired", "learned", and "moved" counters). The implementation is split into separate text and JSON helper functions to keep the main handler simple. Example output: {"br0": {"entries": {"current": 17, "maximum": 8192, "static": 17}, "events": {"evicted": 0, "expired": 0, "learned": 17, "moved": 0}}} Reported-at: https://issues.redhat.com/browse/FDP-2444 Signed-off-by: Timothy Redaelli <tredaelli@redhat.com> --- NEWS | 2 + ofproto/ofproto-dpif.c | 94 ++++++++++++++++++++++++++++---------- tests/ofproto-dpif.at | 15 ++++++ vswitchd/ovs-vswitchd.8.in | 3 ++ 4 files changed, 90 insertions(+), 24 deletions(-)