]> git.ipfire.org Git - ipfire-3.x.git/commitdiff
rstp: Add dump functionality.
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 27 Jul 2010 11:48:07 +0000 (13:48 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 27 Jul 2010 11:48:07 +0000 (13:48 +0200)
pkgs/core/rstp/patches/rstp-0.21-dump-commands.patch [new file with mode: 0644]

diff --git a/pkgs/core/rstp/patches/rstp-0.21-dump-commands.patch b/pkgs/core/rstp/patches/rstp-0.21-dump-commands.patch
new file mode 100644 (file)
index 0000000..1897e83
--- /dev/null
@@ -0,0 +1,270 @@
+diff --git a/ctl_main.c b/ctl_main.c
+index dd041d7..49dfaf9 100644
+--- a/ctl_main.c
++++ b/ctl_main.c
+@@ -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)
+diff --git a/rstpctl.8 b/rstpctl.8
+index ca72eaf..f827c85 100644
+--- a/rstpctl.8
++++ b/rstpctl.8
+@@ -115,6 +115,13 @@ switch back to RSTP mode.
+ .B rstpctl debuglevel <level>
+ sets the level of verbosity of rstpd's logging.
++.B rstpctl dumpbridge [<bridge> ...]
++dumps all informational parameters to the console. This is needed to
++parse the output in shell scripts for example.
++
++.B rstpctl dumpports <bridge> [<port> ...]
++like dumpbridge but prints information about the ports of a bridge.
++
+ .SH NOTES
+ TODO: Indicate lack of persistence of configuration across restarts of
+ daemon.