diff mbox

[ovs-dev,2/4] stp: Add the stp/show command.

Message ID 1488892290-106534-2-git-send-email-nic@opencloud.tech
State Changes Requested
Headers show

Commit Message

nickcooper-zhangtonghao March 7, 2017, 1:11 p.m. UTC
The stp/show command will help users and developers get
more details about stp. This patch works together with
the previous patch "stp: Change the api for next patch."

Signed-off-by: nickcooper-zhangtonghao <nic@opencloud.tech>
---
 lib/stp.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

Comments

nickcooper-zhangtonghao March 18, 2017, 7:58 a.m. UTC | #1
Thanks very much, I submitted v2 and added the “Co-authored-by".


Nick

> On Mar 18, 2017, at 2:37 AM, Ben Pfaff <blp@ovn.org> wrote:
> 
> On Tue, Mar 07, 2017 at 05:11:28AM -0800, nickcooper-zhangtonghao wrote:
>> The stp/show command will help users and developers get
>> more details about stp. This patch works together with
>> the previous patch "stp: Change the api for next patch."
>> 
>> Signed-off-by: nickcooper-zhangtonghao <nic@opencloud.tech <mailto:nic@opencloud.tech>>
> 
> Thanks for working on this!
> 
> I noticed that a lot of the printf format specifiers seem to be randomly
> chosen.  I'm appending a patch that fixes these and improves style in a
> couple of ways.
> 
> This patch should also add documentation for the new commands in the
> ovs-vswitchd manpage and probably add a NEWS item too.  Will you send a
> revision?
> 
> Thanks,
> 
> Ben.
diff mbox

Patch

diff --git a/lib/stp.c b/lib/stp.c
index 1444dd7..d90b400 100644
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -236,6 +236,8 @@  static void stp_send_bpdu(struct stp_port *, const void *, size_t)
     OVS_REQUIRES(mutex);
 static void stp_unixctl_tcn(struct unixctl_conn *, int argc,
                             const char *argv[], void *aux);
+static void stp_unixctl_show(struct unixctl_conn *, int argc,
+                             const char *argv[], void *aux);
 
 void
 stp_init(void)
@@ -251,6 +253,8 @@  stp_init(void)
 
         unixctl_command_register("stp/tcn", "[bridge]", 0, 1, stp_unixctl_tcn,
                                  NULL);
+        unixctl_command_register("stp/show", "[bridge]", 0, 1,
+                                 stp_unixctl_show, NULL);
         ovsthread_once_done(&once);
     }
 }
@@ -1634,3 +1638,107 @@  stp_unixctl_tcn(struct unixctl_conn *conn, int argc,
 out:
     ovs_mutex_unlock(&mutex);
 }
+
+static void
+stp_bridge_id_details(struct ds *ds, const stp_identifier bridge_id,
+                      const int hello_time, const int max_age,
+                      const int forward_delay)
+    OVS_REQUIRES(mutex)
+{
+    struct eth_addr mac;
+    const uint64_t mac_bits = (UINT64_C(1) << 48) - 1;
+
+    ds_put_format(ds, "\tstp-priority\t%"PRIu32"\n",
+                  (uint16_t)(bridge_id >> 48));
+
+    eth_addr_from_uint64(bridge_id & mac_bits, &mac);
+    ds_put_format(ds, "\tstp-system-id\t"ETH_ADDR_FMT"\n",
+                  ETH_ADDR_ARGS(mac));
+    ds_put_format(ds, "\tstp-hello-time\t%"PRId32"s\n",
+                  timer_to_ms(hello_time) / 1000);
+    ds_put_format(ds, "\tstp-max-age\t%"PRId32"s\n",
+                  timer_to_ms(max_age) / 1000);
+    ds_put_format(ds, "\tstp-fwd-delay\t%"PRId32"s\n",
+                  timer_to_ms(forward_delay) / 1000);
+}
+
+static void
+stp_print_details(struct ds *ds, const struct stp *stp)
+    OVS_REQUIRES(mutex)
+{
+    const uint16_t port_no_bits = (UINT16_C(1) << 8) - 1;
+
+    ds_put_format(ds, "---- %s ----\n", stp->name);
+    ds_put_cstr(ds, "Root ID:\n");
+
+    stp_bridge_id_details(ds, stp->designated_root,
+                          stp->bridge_hello_time,
+                          stp->bridge_max_age,
+                          stp->bridge_forward_delay);
+
+    if (stp_is_root_bridge(stp)) {
+        ds_put_cstr(ds, "\tThis bridge is the root\n");
+    } else {
+        ds_put_format(ds, "\troot-port\t%s\n",
+                      stp->root_port->port_name);
+        ds_put_format(ds, "\troot-path-cost\t%"PRIu32"\n",
+                      stp->root_path_cost);
+    }
+
+    ds_put_cstr(ds, "\n");
+
+    ds_put_cstr(ds, "Bridge ID:\n");
+    stp_bridge_id_details(ds, stp->bridge_id,
+                          stp->hello_time,
+                          stp->max_age,
+                          stp->forward_delay);
+
+    ds_put_cstr(ds, "\n");
+
+    const struct stp_port *p;
+    ds_put_format(ds, "\t%-11.10s%-11.10s%-11.10s%-6.5s%-8.7s\n",
+                  "Interface", "Role", "State", "Cost", "Pri.Nbr");
+    ds_put_cstr(ds, "\t---------- ---------- ---------- ----- -------\n");
+    FOR_EACH_ENABLED_PORT (p, stp) {
+        ds_put_format(ds, "\t%-11.10s", p->port_name);
+        ds_put_format(ds, "%-11.10s", stp_role_name(stp_port_get_role(p)));
+        ds_put_format(ds, "%-11.10s", stp_state_name(p->state));
+        ds_put_format(ds, "%-6"PRId32, p->path_cost);
+        ds_put_format(ds, "%"PRIu16".%"PRIu16"\n",
+                      p->port_id >> 8,
+                      p->port_id & port_no_bits);
+    }
+
+    ds_put_cstr(ds, "\n");
+}
+
+static void
+stp_unixctl_show(struct unixctl_conn *conn, int argc,
+                const char *argv[], void *aux OVS_UNUSED)
+{
+    struct ds ds = DS_EMPTY_INITIALIZER;
+
+    ovs_mutex_lock(&mutex);
+    if (argc > 1) {
+        struct stp *stp = stp_find(argv[1]);
+
+        if (!stp) {
+            unixctl_command_reply_error(conn, "no such stp object");
+            goto out;
+        }
+
+        stp_print_details(&ds, stp);
+    } else {
+        struct stp *stp;
+
+        LIST_FOR_EACH (stp, node, all_stps) {
+            stp_print_details(&ds, stp);
+        }
+    }
+
+    unixctl_command_reply(conn, ds_cstr(&ds));
+    ds_destroy(&ds);
+
+out:
+    ovs_mutex_unlock(&mutex);
+}