Add a command to dump statistics per exporter. Signed-off-by: Adrian Moreno <amore...@redhat.com> --- NEWS | 2 + ofproto/ofproto-dpif-lsample.c | 111 +++++++++++++++++++++++++++++++++ ofproto/ofproto-dpif-lsample.h | 2 + ofproto/ofproto-dpif.c | 1 + 4 files changed, 116 insertions(+)
diff --git a/NEWS b/NEWS index 5f5871ef0..096ff4d7d 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ Post-v3.3.0 allows samples to be emitted locally (instead of via IPFIX) in a datapath-specific manner. The Linux kernel datapath is the first to support this feature by using the new datapath "psample" action. + - A new unixctl command 'lsample/show' shows packet and bytes statistics + per local sample exporter. v3.3.0 - 16 Feb 2024 diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c index f4bf49a7a..926f88c4e 100644 --- a/ofproto/ofproto-dpif-lsample.c +++ b/ofproto/ofproto-dpif-lsample.c @@ -21,7 +21,10 @@ #include "dpif.h" #include "hash.h" #include "ofproto.h" +#include "ofproto-dpif.h" +#include "openvswitch/dynamic-string.h" #include "openvswitch/thread.h" +#include "unixctl.h" /* Dpif local sampling. * @@ -219,3 +222,111 @@ dpif_lsample_unref(struct dpif_lsample *lsample) dpif_lsample_destroy(lsample); } } + +static int +comp_exporter_collector_id(const void *a_, const void *b_) +{ + const struct lsample_exporter_node *a, *b; + + a = *(struct lsample_exporter_node **) a_; + b = *(struct lsample_exporter_node **) b_; + + if (a->exporter.options.collector_set_id > + b->exporter.options.collector_set_id) { + return 1; + } + if (a->exporter.options.collector_set_id < + b->exporter.options.collector_set_id) { + return -1; + } + return 0; +} + +static void +lsample_exporter_list(struct dpif_lsample *lsample, + struct lsample_exporter_node ***list, + size_t *num_exporters) +{ + struct lsample_exporter_node **exporter_list; + struct lsample_exporter_node *node; + size_t k = 0, n; + + n = cmap_count(&lsample->exporters); + + exporter_list = xcalloc(n, sizeof *exporter_list); + + CMAP_FOR_EACH (node, node, &lsample->exporters) { + if (k >= n) { + break; + } + exporter_list[k++] = node; + } + + qsort(exporter_list, k, sizeof *exporter_list, comp_exporter_collector_id); + + *list = exporter_list; + *num_exporters = k; +} + +static void +lsample_unixctl_show(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + struct lsample_exporter_node **node_list = NULL; + struct ds ds = DS_EMPTY_INITIALIZER; + const struct ofproto_dpif *ofproto; + size_t i, num; + + ofproto = ofproto_dpif_lookup_by_name(argv[1]); + if (!ofproto) { + unixctl_command_reply_error(conn, "no such bridge"); + return; + } + + if (!ofproto->lsample) { + unixctl_command_reply_error(conn, + "no local sampling exporters configured"); + return; + } + + ds_put_format(&ds, "Local sample statistics for bridge \"%s\":\n", + argv[1]); + + lsample_exporter_list(ofproto->lsample, &node_list, &num); + + for (i = 0; i < num; i++) { + uint64_t n_bytes; + uint64_t n_packets; + + struct lsample_exporter_node *node = node_list[i]; + + atomic_read_relaxed(&node->exporter.n_packets, &n_packets); + atomic_read_relaxed(&node->exporter.n_bytes, &n_bytes); + + if (i) { + ds_put_cstr(&ds, "\n"); + } + + ds_put_format(&ds, "Collector Set ID: %"PRIu32":\n", + node->exporter.options.collector_set_id); + ds_put_format(&ds, " Group ID : %"PRIu32"\n", + node->exporter.options.group_id); + ds_put_format(&ds, " Total packets: %"PRIu64"\n", n_packets); + ds_put_format(&ds, " Total bytes : %"PRIu64"\n", n_bytes); + } + + free(node_list); + unixctl_command_reply(conn, ds_cstr(&ds)); + ds_destroy(&ds); +} + +void dpif_lsample_init(void) +{ + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; + + if (ovsthread_once_start(&once)) { + unixctl_command_register("lsample/show", "bridge", 1, 1, + lsample_unixctl_show, NULL); + ovsthread_once_done(&once); + } +} diff --git a/ofproto/ofproto-dpif-lsample.h b/ofproto/ofproto-dpif-lsample.h index dbf7237bd..6ac7580ac 100644 --- a/ofproto/ofproto-dpif-lsample.h +++ b/ofproto/ofproto-dpif-lsample.h @@ -25,6 +25,8 @@ struct dpif_lsample; struct ofproto_lsample_options; struct dpif_flow_stats; +void dpif_lsample_init(void); + struct dpif_lsample *dpif_lsample_create(void); struct dpif_lsample *dpif_lsample_ref(const struct dpif_lsample *); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 726383e96..b81e59667 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -286,6 +286,7 @@ init(const struct shash *iface_hints) ofproto_unixctl_init(); ofproto_dpif_trace_init(); udpif_init(); + dpif_lsample_init(); } static void -- 2.45.2 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev