1 diff --git a/ctl_main.c b/ctl_main.c
2 index dd041d7..7382d97 100644
5 @@ -443,6 +443,240 @@ static int cmd_debuglevel(int argc, char *const *argv)
6 return CTL_set_debug_level(getuint(argv[1]));
9 +#define DUMP_FMT(br_name, key) "%-8s %-26s ", br_name, key
11 +static int do_dumpbridge(const char *br_name) {
14 + int br_index = get_index_die(br_name, "bridge", 0);
18 + int r = CTL_get_bridge_status(br_index, &s);
22 + /* bridge forward delay */
23 + printf(DUMP_FMT(br_name, "bridge_forward_delay"));
24 + printf("%u\n", s.bridge_forward_delay);
26 + /* bridge hello time */
27 + printf(DUMP_FMT(br_name, "bridge_hello_time"));
28 + printf("%u\n", s.bridge_hello_time);
30 + /* bridge max age */
31 + printf(DUMP_FMT(br_name, "bridge_max_age"));
32 + printf("%u\n", s.bridge_max_age);
34 + /* designated root */
35 + printf(DUMP_FMT(br_name, "designated_root"));
36 + printf(BR_ID_FMT "\n", BR_ID_ARGS(s.designated_root));
39 + printf(DUMP_FMT(br_name, "enabled"));
40 + printf("%s\n", BOOL_STR(s.enabled));
43 + printf(DUMP_FMT(br_name, "forward_delay"));
44 + printf("%u\n", s.forward_delay);
47 + printf(DUMP_FMT(br_name, "hello_time"));
48 + printf("%u\n", s.hello_time);
51 + printf(DUMP_FMT(br_name, "id"));
52 + printf(BR_ID_FMT "\n", BR_ID_ARGS(s.bridge_id));
55 + printf(DUMP_FMT(br_name, "max_age"));
56 + printf("%u\n", s.max_age);
58 + /* protocol version */
59 + printf(DUMP_FMT(br_name, "protocol_version"));
60 + printf("%d\n", s.protocol_version);
62 + /* root path cost */
63 + printf(DUMP_FMT(br_name, "root_path_cost"));
64 + printf("%u\n", s.root_path_cost);
67 + printf(DUMP_FMT(br_name, "root_port"));
68 + printf("%u\n", s.root_port);
70 + /* time since topology change */
71 + printf(DUMP_FMT(br_name, "time_since_topology_change"));
72 + printf("%u\n", s.time_since_topology_change);
74 + /* topology change */
75 + printf(DUMP_FMT(br_name, "topology_change"));
76 + printf("%u\n", s.topology_change);
78 + /* topology change count */
79 + printf(DUMP_FMT(br_name, "topology_change_count"));
80 + printf("%u\n", s.topology_change_count);
83 + printf(DUMP_FMT(br_name, "tx_hold_count"));
84 + printf("%u\n", s.tx_hold_count);
89 +static int do_dumpbridgeport(int br_index, const char *pt_name) {
92 + int port_index = get_index_die(pt_name, "port", 0);
96 + r = CTL_get_port_status(br_index, port_index, &p);
98 + fprintf(stderr, "Failed to get port state for port %d\n", port_index);
102 + /* admin edge port */
103 + printf(DUMP_FMT(pt_name, "admin_edge_port"));
104 + printf("%s\n", BOOL_STR(p.admin_edge_port));
106 + /* admin point to point */
107 + printf(DUMP_FMT(pt_name, "admin_point_to_point"));
108 + printf("%s\n", BOOL_STR(p.admin_p2p));
110 + /* auto edge port */
111 + printf(DUMP_FMT(pt_name, "auto_edge_port"));
112 + printf("%s\n", BOOL_STR(p.auto_edge_port));
115 + printf(DUMP_FMT(pt_name, "admin_path_cost"));
116 + printf("%d\n", p.admin_path_cost);
118 + /* designated bridge */
119 + printf(DUMP_FMT(pt_name, "designated_bridge"));
120 + printf(BR_ID_FMT "\n", BR_ID_ARGS(p.designated_bridge));
122 + /* designated cost */
123 + printf(DUMP_FMT(pt_name, "designated_cost"));
124 + printf("%d\n", p.designated_cost);
126 + /* designated port */
127 + printf(DUMP_FMT(pt_name, "designated_port"));
128 + printf("%0x\n", p.designated_port);
130 + /* designated root */
131 + printf(DUMP_FMT(pt_name, "designated_root"));
132 + printf(BR_ID_FMT "\n", BR_ID_ARGS(p.designated_root));
135 + printf(DUMP_FMT(pt_name, "enabled"));
136 + printf("%s\n", BOOL_STR(p.enabled));
139 + printf(DUMP_FMT(pt_name, "id"));
140 + printf("%u\n", p.id & 0xfff);
142 + /* oper edge port */
143 + printf(DUMP_FMT(pt_name, "oper_edge_port"));
144 + printf("%s\n", BOOL_STR(p.oper_edge_port));
147 + printf(DUMP_FMT(pt_name, "path_cost"));
148 + printf("%d\n", p.path_cost);
150 + /* point to point */
151 + printf(DUMP_FMT(pt_name, "point_to_point"));
152 + printf("%s\n", BOOL_STR(p.oper_p2p));
155 + printf(DUMP_FMT(pt_name, "state"));
156 + printf(STATE_STR(p.state));
159 + /* topology change ack */
160 + printf(DUMP_FMT(pt_name, "topology_change_ack"));
161 + printf("%s\n", BOOL_STR(p.tc_ack));
166 +static int cmd_dumpbridge(int argc, char *const *argv)
170 + struct dirent **namelist;
176 + scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort);
178 + fprintf(stderr, "Error getting list of all bridges\n");
183 + for (i = 0; i < count; i++) {
186 + name = argv[i + 1];
188 + name = namelist[i]->d_name;
190 + int err = do_dumpbridge(name);
196 + for (i = 0; i < count; i++)
204 +static int cmd_dumpbridgeports(int argc, char *const *argv)
208 + int br_index = get_index(argv[1], "bridge");
211 + struct dirent **namelist;
216 + char buf[SYSFS_PATH_MAX];
217 + snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", argv[1]);
218 + count = scandir(buf, &namelist, not_dot_dotdot, alphasort);
221 + "Error getting list of all ports of bridge %s\n",
227 + for (i = 0; i < count; i++) {
229 + name = namelist[i]->d_name;
231 + int err = do_dumpbridgeport(br_index, name);
236 + for (i = 0; i < count; i++)
246 @@ -483,6 +717,10 @@ static const struct command commands[] = {
247 {2, 0, "portmcheck", cmd_portmcheck,
248 "<bridge> <port>\ttry to get back from STP to RSTP mode"},
249 {1, 0, "debuglevel", cmd_debuglevel, "<level>\t\tLevel of verbosity"},
250 + {0, 32, "dumpbridge", cmd_dumpbridge,
251 + "Dump all information about a bridge in machine parseable format"},
252 + {1, 0, "dumpports", cmd_dumpbridgeports,
253 + "Dump all port information in machine parseable format"},
256 const struct command *command_lookup(const char *cmd)
257 diff --git a/rstpctl.8 b/rstpctl.8
258 index ca72eaf..f827c85 100644
261 @@ -115,6 +115,13 @@ switch back to RSTP mode.
262 .B rstpctl debuglevel <level>
263 sets the level of verbosity of rstpd's logging.
265 +.B rstpctl dumpbridge [<bridge> ...]
266 +dumps all informational parameters to the console. This is needed to
267 +parse the output in shell scripts for example.
269 +.B rstpctl dumpports <bridge> [<port> ...]
270 +like dumpbridge but prints information about the ports of a bridge.
273 TODO: Indicate lack of persistence of configuration across restarts of