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 <[email protected]>
---
 lib/stp.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

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);
+}
-- 
1.8.3.1



_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to