]> git.ipfire.org Git - people/ms/rstp.git/commitdiff
rstpctl: Add dump funtionality.
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 27 Jul 2010 11:26:59 +0000 (13:26 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 27 Jul 2010 11:26:59 +0000 (13:26 +0200)
The new commands will output all parameters in a machine
parseable format:

  rstpctl dumpbridge [<bridge1> ...]

  rstpctl dumpbridgeports bridge1 [<port1> ...]

ctl_main.c

index dd041d789978d2fac834da3a03c453945800f707..49dfaf9378d19da2ab6b2c5e6a500b281915ad13 100644 (file)
@@ -443,6 +443,236 @@ static int cmd_debuglevel(int argc, char *const *argv)
        return CTL_set_debug_level(getuint(argv[1]));
 }
 
+#define DUMP_FMT(br_name, key) "%-8s %-26s ", br_name, key
+
+static int do_dumpbridge(const char *br_name) {
+       STP_BridgeStatus s;
+
+       int br_index = get_index_die(br_name, "bridge", 0);
+       if (br_index < 0)
+               return -1;
+
+       int r = CTL_get_bridge_status(br_index, &s);
+       if (r)
+               return -1;
+
+       /* bridge forward delay */
+       printf(DUMP_FMT(br_name, "bridge_forward_delay"));
+       printf("%u\n", s.bridge_forward_delay);
+
+       /* bridge hello time */
+       printf(DUMP_FMT(br_name, "bridge_hello_time"));
+       printf("%u\n", s.bridge_hello_time);
+
+       /* bridge max age */
+       printf(DUMP_FMT(br_name, "bridge_max_age"));
+       printf("%u\n", s.bridge_max_age);
+
+       /* designated root */
+       printf(DUMP_FMT(br_name, "designated_root"));
+       printf(BR_ID_FMT "\n", BR_ID_ARGS(s.designated_root));
+
+       /* enabled */
+       printf(DUMP_FMT(br_name, "enabled"));
+       printf("%s\n", BOOL_STR(s.enabled));
+
+       /* forward delay */
+       printf(DUMP_FMT(br_name, "forward_delay"));
+       printf("%u\n", s.forward_delay);
+
+       /* hello time */
+       printf(DUMP_FMT(br_name, "hello_time"));
+       printf("%u\n", s.hello_time);
+
+       /* id */
+       printf(DUMP_FMT(br_name, "id"));
+       printf(BR_ID_FMT "\n", BR_ID_ARGS(s.bridge_id));
+
+       /* max age */
+       printf(DUMP_FMT(br_name, "max_age"));
+       printf("%u\n", s.max_age);
+
+       /* root path cost */
+       printf(DUMP_FMT(br_name, "root_path_cost"));
+       printf("%u\n", s.root_path_cost);
+
+       /* root port */
+       printf(DUMP_FMT(br_name, "root_port"));
+       printf("%u\n", s.root_port);
+
+       /* time since topology change */
+       printf(DUMP_FMT(br_name, "time_since_topology_change"));
+       printf("%u\n", s.time_since_topology_change);
+
+       /* topology change */
+       printf(DUMP_FMT(br_name, "topology_change"));
+       printf("%u\n", s.topology_change);
+
+       /* topology change count */
+       printf(DUMP_FMT(br_name, "topology_change_count"));
+       printf("%u\n", s.topology_change_count);
+
+       /* tx hold count */
+       printf(DUMP_FMT(br_name, "tx_hold_count"));
+       printf("%u\n", s.tx_hold_count);
+
+       return 0;
+}
+
+static int do_dumpbridgeport(int br_index, const char *pt_name) {
+       STP_PortStatus p;
+       int r = 0;
+       int port_index = get_index_die(pt_name, "port", 0);
+       if (port_index < 0)
+               return -1;
+
+       r = CTL_get_port_status(br_index, port_index, &p);
+       if (r) {
+               fprintf(stderr, "Failed to get port state for port %d\n", port_index);
+               return -1;
+       }
+
+       /* admin edge port */
+       printf(DUMP_FMT(pt_name, "admin_edge_port"));
+       printf("%s\n", BOOL_STR(p.admin_edge_port));
+
+       /* admin point to point */
+       printf(DUMP_FMT(pt_name, "admin_point_to_point"));
+       printf("%s\n", BOOL_STR(p.admin_p2p));
+
+       /* auto edge port */
+       printf(DUMP_FMT(pt_name, "auto_edge_port"));
+       printf("%s\n", BOOL_STR(p.auto_edge_port));
+
+       /* path cost */
+       printf(DUMP_FMT(pt_name, "admin_path_cost"));
+       printf("%d\n", p.admin_path_cost);
+
+       /* designated bridge */
+       printf(DUMP_FMT(pt_name, "designated_bridge"));
+       printf(BR_ID_FMT "\n", BR_ID_ARGS(p.designated_bridge));
+
+       /* designated cost */
+       printf(DUMP_FMT(pt_name, "designated_cost"));
+       printf("%d\n", p.designated_cost);
+
+       /* designated port */
+       printf(DUMP_FMT(pt_name, "designated_port"));
+       printf("%0x\n", p.designated_port);
+
+       /* designated root */
+       printf(DUMP_FMT(pt_name, "designated_root"));
+       printf(BR_ID_FMT "\n", BR_ID_ARGS(p.designated_root));
+
+       /* enabled */
+       printf(DUMP_FMT(pt_name, "enabled"));
+       printf("%s\n", BOOL_STR(p.enabled));
+
+       /* id */
+       printf(DUMP_FMT(pt_name, "id"));
+       printf("%u\n", p.id & 0xfff);
+
+       /* oper edge port */
+       printf(DUMP_FMT(pt_name, "oper_edge_port"));
+       printf("%s\n", BOOL_STR(p.oper_edge_port));
+
+       /* path cost */
+       printf(DUMP_FMT(pt_name, "path_cost"));
+       printf("%d\n", p.path_cost);
+
+       /* point to point */
+       printf(DUMP_FMT(pt_name, "point_to_point"));
+       printf("%s\n", BOOL_STR(p.oper_p2p));
+
+       /* state */
+       printf(DUMP_FMT(pt_name, "state"));
+       printf(STATE_STR(p.state));
+       printf("\n");
+
+       /* topology change ack */
+       printf(DUMP_FMT(pt_name, "topology_change_ack"));
+       printf("%s\n", BOOL_STR(p.tc_ack));
+
+       return 0;
+}
+
+static int cmd_dumpbridge(int argc, char *const *argv)
+{
+       int i, count = 0;
+       int r = 0;
+       struct dirent **namelist;
+
+       if (argc > 1) {
+               count = argc - 1;
+       } else {
+               count =
+                   scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort);
+               if (count < 0) {
+                       fprintf(stderr, "Error getting list of all bridges\n");
+                       return -1;
+               }
+       }
+
+       for (i = 0; i < count; i++) {
+               const char *name;
+               if (argc > 1)
+                       name = argv[i + 1];
+               else
+                       name = namelist[i]->d_name;
+
+               int err = do_dumpbridge(name);
+               if (err)
+                       r = err;
+       }
+
+       if (argc <= 1) {
+               for (i = 0; i < count; i++)
+                       free(namelist[i]);
+               free(namelist);
+       }
+
+       return r;
+}
+
+static int cmd_dumpbridgeports(int argc, char *const *argv)
+{
+       int r = 0;
+
+       int br_index = get_index(argv[1], "bridge");
+
+       int i, count = 0;
+       struct dirent **namelist;
+
+       if (argc > 2) {
+               count = argc - 2;
+       } else {
+               char buf[SYSFS_PATH_MAX];
+               snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", argv[1]);
+               count = scandir(buf, &namelist, not_dot_dotdot, alphasort);
+               if (count < 0) {
+                       fprintf(stderr,
+                               "Error getting list of all ports of bridge %s\n",
+                               argv[1]);
+                       return -1;
+               }
+       }
+
+       for (i = 0; i < count; i++) {
+               const char *name;
+               name = namelist[i]->d_name;
+
+               int err = do_dumpbridgeport(br_index, name);
+               if (err)
+                       r = err;
+       }
+
+       for (i = 0; i < count; i++)
+               free(namelist[i]);
+       free(namelist);
+
+       return r;
+}
+
 struct command {
        int nargs;
        int optargs;
@@ -483,6 +713,10 @@ static const struct command commands[] = {
        {2, 0, "portmcheck", cmd_portmcheck,
         "<bridge> <port>\ttry to get back from STP to RSTP mode"},
        {1, 0, "debuglevel", cmd_debuglevel, "<level>\t\tLevel of verbosity"},
+       {0, 32, "dumpbridge", cmd_dumpbridge,
+        "Dump all information about a bridge in machine parseable format"},
+       {1, 0, "dumpports", cmd_dumpbridgeports,
+        "Dump all port information in machine parseable format"},
 };
 
 const struct command *command_lookup(const char *cmd)