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
