summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNitin Katiyar <nitin.katiyar@ericsson.com>2018-04-18 23:57:43 +0530
committerBen Pfaff <blp@ovn.org>2018-04-18 16:26:54 -0700
commit49b9cad34e8a122e4b2997f0a1a1707f5997737e (patch)
tree510ca4925893a58c3fb89825869a9ad3584b6e92 /lib
parent78bc7b2467a333f06aa480625f86e39839c1eb71 (diff)
downloadopenvswitch-49b9cad34e8a122e4b2997f0a1a1707f5997737e.tar.gz
lacp: New command "lacp/show-stats" fordisplaying LACP counters.
Currently OVS does not provide any command to display stats for LACP without which it is difficult to debug LACP issues. Here we propose to display various statistics about LACP PDUs and slave state change. Sample output: ovs_lacp # ovs-appctl lacp/stats-show ---- bond-prv statistics ---- slave: dpdk0: RX PDUs: 128 RX Bad PDUs: 0 TX PDUs: 5 Link Expired: 2 Link Defaulted: 1 Carrier Status Changed: 0 Signed-off-by: Nitin Katiyar <nitin.katiyar@ericsson.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/lacp.c79
1 files changed, 76 insertions, 3 deletions
diff --git a/lib/lacp.c b/lib/lacp.c
index fdefeda02..8353746be 100644
--- a/lib/lacp.c
+++ b/lib/lacp.c
@@ -127,9 +127,12 @@ struct slave {
struct timer tx; /* Next message transmission timer. */
struct timer rx; /* Expected message receive timer. */
- uint32_t count_rx_pdus; /* dot3adAggPortStatsLACPDUsRx */
- uint32_t count_rx_pdus_bad; /* dot3adAggPortStatsIllegalRx */
- uint32_t count_tx_pdus; /* dot3adAggPortStatsLACPDUsTx */
+ uint32_t count_rx_pdus; /* dot3adAggPortStatsLACPDUsRx */
+ uint32_t count_rx_pdus_bad; /* dot3adAggPortStatsIllegalRx */
+ uint32_t count_tx_pdus; /* dot3adAggPortStatsLACPDUsTx */
+ uint32_t count_link_expired; /* Num of times link expired */
+ uint32_t count_link_defaulted; /* Num of times link defaulted */
+ uint32_t count_carrier_changed; /* Num of times link status changed */
};
static struct ovs_mutex mutex;
@@ -153,6 +156,7 @@ static bool info_tx_equal(struct lacp_info *, struct lacp_info *)
OVS_REQUIRES(mutex);
static unixctl_cb_func lacp_unixctl_show;
+static unixctl_cb_func lacp_unixctl_show_stats;
/* Populates 'pdu' with a LACP PDU comprised of 'actor' and 'partner'. */
static void
@@ -206,6 +210,8 @@ lacp_init(void)
{
unixctl_command_register("lacp/show", "[port]", 0, 1,
lacp_unixctl_show, NULL);
+ unixctl_command_register("lacp/show-stats", "[port]", 0, 1,
+ lacp_unixctl_show_stats, NULL);
}
static void
@@ -459,6 +465,7 @@ lacp_slave_carrier_changed(const struct lacp *lacp, const void *slave_)
if (slave->status == LACP_CURRENT || slave->lacp->active) {
slave_set_expired(slave);
}
+ slave->count_carrier_changed++;
out:
lacp_unlock();
@@ -525,8 +532,10 @@ lacp_run(struct lacp *lacp, lacp_send_pdu *send_pdu) OVS_EXCLUDED(mutex)
if (slave->status == LACP_CURRENT) {
slave_set_expired(slave);
+ slave->count_link_expired++;
} else if (slave->status == LACP_EXPIRED) {
slave_set_defaulted(slave);
+ slave->count_link_defaulted++;
}
if (slave->status != old_status) {
seq_change(connectivity_seq_get());
@@ -994,6 +1003,40 @@ lacp_print_details(struct ds *ds, struct lacp *lacp) OVS_REQUIRES(mutex)
}
static void
+lacp_print_stats(struct ds *ds, struct lacp *lacp) OVS_REQUIRES(mutex)
+{
+ struct shash slave_shash = SHASH_INITIALIZER(&slave_shash);
+ const struct shash_node **sorted_slaves = NULL;
+
+ struct slave *slave;
+ int i;
+
+ ds_put_format(ds, "---- %s statistics ----\n", lacp->name);
+
+ HMAP_FOR_EACH (slave, node, &lacp->slaves) {
+ shash_add(&slave_shash, slave->name, slave);
+ }
+ sorted_slaves = shash_sort(&slave_shash);
+
+ for (i = 0; i < shash_count(&slave_shash); i++) {
+ slave = sorted_slaves[i]->data;
+ ds_put_format(ds, "\nslave: %s:\n", slave->name);
+ ds_put_format(ds, "\tRX PDUs: %u\n", slave->count_rx_pdus);
+ ds_put_format(ds, "\tRX Bad PDUs: %u\n", slave->count_rx_pdus_bad);
+ ds_put_format(ds, "\tTX PDUs: %u\n", slave->count_tx_pdus);
+ ds_put_format(ds, "\tLink Expired: %u\n",
+ slave->count_link_expired);
+ ds_put_format(ds, "\tLink Defaulted: %u\n",
+ slave->count_link_defaulted);
+ ds_put_format(ds, "\tCarrier Status Changed: %u\n",
+ slave->count_carrier_changed);
+ }
+
+ shash_destroy(&slave_shash);
+ free(sorted_slaves);
+}
+
+static void
lacp_unixctl_show(struct unixctl_conn *conn, int argc, const char *argv[],
void *aux OVS_UNUSED) OVS_EXCLUDED(mutex)
{
@@ -1021,6 +1064,36 @@ out:
lacp_unlock();
}
+static void
+lacp_unixctl_show_stats(struct unixctl_conn *conn,
+ int argc,
+ const char *argv[],
+ void *aux OVS_UNUSED) OVS_EXCLUDED(mutex)
+{
+ struct ds ds = DS_EMPTY_INITIALIZER;
+ struct lacp *lacp;
+
+ lacp_lock();
+ if (argc > 1) {
+ lacp = lacp_find(argv[1]);
+ if (!lacp) {
+ unixctl_command_reply_error(conn, "no such lacp object");
+ goto out;
+ }
+ lacp_print_stats(&ds, lacp);
+ } else {
+ LIST_FOR_EACH (lacp, node, all_lacps) {
+ lacp_print_stats(&ds, lacp);
+ }
+ }
+
+ unixctl_command_reply(conn, ds_cstr(&ds));
+ ds_destroy(&ds);
+
+out:
+ lacp_unlock();
+}
+
/* Extract a snapshot of the current state and counters for a slave port.
Return false if the slave is not active. */
bool