brctl: add support for showstp command
function old new delta brctl_main 974 2339 +1365 show_bridge_timer - 93 +93 static.state_names - 48 +48 printf_xstrtou - 26 +26 packed_usage 33243 33253 +10 show_bridge 333 323 -10 ------------------------------------------------------------------------------ (add/remove: 3/0 grow/shrink: 2/1 up/down: 1542/-10) Total: 1532 bytes text data bss dec hex filename 999868 551 5612 1006031 f59cf busybox_old 1002309 551 5612 1008472 f6358 busybox_unstripped Signed-off-by: Martin Lewis <martin.lewis.x84@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
42f454b13b
commit
6dcf563633
@ -54,6 +54,7 @@
|
|||||||
//usage: "\n delif BRIDGE IFACE Delete IFACE from BRIDGE"
|
//usage: "\n delif BRIDGE IFACE Delete IFACE from BRIDGE"
|
||||||
//usage: IF_FEATURE_BRCTL_FANCY(
|
//usage: IF_FEATURE_BRCTL_FANCY(
|
||||||
//usage: "\n stp BRIDGE 1/yes/on|0/no/off STP on/off"
|
//usage: "\n stp BRIDGE 1/yes/on|0/no/off STP on/off"
|
||||||
|
//usage: "\n showstp BRIDGE Show stp info"
|
||||||
//usage: "\n setageing BRIDGE SECONDS Set ageing time"
|
//usage: "\n setageing BRIDGE SECONDS Set ageing time"
|
||||||
//usage: "\n setfd BRIDGE SECONDS Set bridge forward delay"
|
//usage: "\n setfd BRIDGE SECONDS Set bridge forward delay"
|
||||||
//usage: "\n sethello BRIDGE SECONDS Set hello time"
|
//usage: "\n sethello BRIDGE SECONDS Set hello time"
|
||||||
@ -65,7 +66,7 @@
|
|||||||
//usage: )
|
//usage: )
|
||||||
// Not yet implemented:
|
// Not yet implemented:
|
||||||
// hairpin BRIDGE IFACE on|off Hairpin on/off
|
// hairpin BRIDGE IFACE on|off Hairpin on/off
|
||||||
// showstp BRIDGE Show stp info
|
|
||||||
|
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
#include "common_bufsiz.h"
|
#include "common_bufsiz.h"
|
||||||
@ -146,8 +147,7 @@ static int show_bridge(const char *name, int need_hdr)
|
|||||||
|
|
||||||
if (need_hdr)
|
if (need_hdr)
|
||||||
puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces");
|
puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces");
|
||||||
printf("%s\t\t", name);
|
printf("%s\t\t%s\t", name, filedata);
|
||||||
printf("%s\t", filedata);
|
|
||||||
|
|
||||||
strcpy(sfx, "stp_state");
|
strcpy(sfx, "stp_state");
|
||||||
read_file(pathbuf);
|
read_file(pathbuf);
|
||||||
@ -279,6 +279,212 @@ static void show_bridge_macs(const char *name)
|
|||||||
|
|
||||||
free(fdb);
|
free(fdb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void show_bridge_timer(const char *msg)
|
||||||
|
{
|
||||||
|
unsigned long long tvmsec = 10 * xstrtoull(filedata, 0);
|
||||||
|
unsigned tv_sec = tvmsec / 1000;
|
||||||
|
unsigned tv_msec = tvmsec % 1000;
|
||||||
|
printf("%s%4u.%.2u", msg, tv_sec, tv_msec / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *show_bridge_state(unsigned state)
|
||||||
|
{
|
||||||
|
/* See linux/if_bridge.h, BR_STATE_ constants */
|
||||||
|
static const char state_names[] =
|
||||||
|
"disabled\0" //BR_STATE_DISABLED 0
|
||||||
|
"listening\0" //BR_STATE_LISTENING 1
|
||||||
|
"learning\0" //BR_STATE_LEARNING 2
|
||||||
|
"forwarding\0" //BR_STATE_FORWARDING 3
|
||||||
|
"blocking" //BR_STATE_BLOCKING 4
|
||||||
|
;
|
||||||
|
if (state < 5)
|
||||||
|
return nth_string(state_names, state);
|
||||||
|
return utoa(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printf_xstrtou(const char *fmt)
|
||||||
|
{
|
||||||
|
printf(fmt, xstrtou(filedata, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_bridge_port(const char *name)
|
||||||
|
{
|
||||||
|
char pathbuf[IFNAMSIZ + sizeof("/brport/forward_delay_timer") + 32];
|
||||||
|
char *sfx;
|
||||||
|
|
||||||
|
#if IFNAMSIZ == 16
|
||||||
|
sfx = pathbuf + sprintf(pathbuf, "%.16s/brport/", name);
|
||||||
|
#else
|
||||||
|
sfx = pathbuf + sprintf(pathbuf, "%.*s/brport/", (int)IFNAMSIZ, name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strcpy(sfx, "port_no");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf("%s (%u)\n", name, xstrtou(filedata, 0));
|
||||||
|
|
||||||
|
strcpy(sfx + 5, "id"); // "port_id"
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf_xstrtou(" port id\t\t%.4x");
|
||||||
|
|
||||||
|
strcpy(sfx, "state");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf("\t\t\tstate\t\t%15s\n", show_bridge_state(xstrtou(filedata, 0)));
|
||||||
|
|
||||||
|
strcpy(sfx, "designated_root");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf(" designated root\t%s", filedata);
|
||||||
|
|
||||||
|
strcpy(sfx, "path_cost");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf_xstrtou("\tpath cost\t\t%4u\n");
|
||||||
|
|
||||||
|
strcpy(sfx, "designated_bridge");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf(" designated bridge\t%s", filedata);
|
||||||
|
|
||||||
|
strcpy(sfx, "message_age_timer");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\tmessage age timer\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "designated_port");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf_xstrtou("\n designated port\t%.4x");
|
||||||
|
|
||||||
|
strcpy(sfx, "forward_delay_timer");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\t\t\tforward delay timer\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "designated_cost");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf_xstrtou("\n designated cost\t%4u");
|
||||||
|
|
||||||
|
strcpy(sfx, "hold_timer");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\t\t\thold timer\t\t");
|
||||||
|
|
||||||
|
printf("\n flags\t\t\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "config_pending");
|
||||||
|
read_file(pathbuf);
|
||||||
|
if (!LONE_CHAR(filedata, '0'))
|
||||||
|
printf("CONFIG_PENDING ");
|
||||||
|
|
||||||
|
strcpy(sfx, "change_ack");
|
||||||
|
read_file(pathbuf);
|
||||||
|
if (!LONE_CHAR(filedata, '0'))
|
||||||
|
printf("TOPOLOGY_CHANGE_ACK ");
|
||||||
|
|
||||||
|
strcpy(sfx, "hairpin_mode");
|
||||||
|
read_file(pathbuf);
|
||||||
|
if (!LONE_CHAR(filedata, '0'))
|
||||||
|
printf_xstrtou("\n hairpin mode\t\t%4u");
|
||||||
|
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_bridge_ports(const char *name)
|
||||||
|
{
|
||||||
|
DIR *ifaces;
|
||||||
|
struct dirent *ent;
|
||||||
|
char pathbuf[IFNAMSIZ + sizeof("/brif") + 8];
|
||||||
|
|
||||||
|
#if IFNAMSIZ == 16
|
||||||
|
sprintf(pathbuf, "%.16s/brif", name);
|
||||||
|
#else
|
||||||
|
sprintf(pathbuf, "%.*s/brif", (int)IFNAMSIZ, name);
|
||||||
|
#endif
|
||||||
|
ifaces = opendir(pathbuf);
|
||||||
|
if (ifaces) {
|
||||||
|
while ((ent = readdir(ifaces)) != NULL) {
|
||||||
|
if (DOT_OR_DOTDOT(ent->d_name))
|
||||||
|
continue; /* . or .. */
|
||||||
|
show_bridge_port(ent->d_name);
|
||||||
|
}
|
||||||
|
closedir(ifaces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_bridge_stp(const char *name)
|
||||||
|
{
|
||||||
|
char pathbuf[IFNAMSIZ + sizeof("/bridge/topology_change_timer") + 32];
|
||||||
|
char *sfx;
|
||||||
|
|
||||||
|
#if IFNAMSIZ == 16
|
||||||
|
sfx = pathbuf + sprintf(pathbuf, "%.16s/bridge/", name);
|
||||||
|
#else
|
||||||
|
sfx = pathbuf + sprintf(pathbuf, "%.*s/bridge/", (int)IFNAMSIZ, name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strcpy(sfx, "bridge_id");
|
||||||
|
if (read_file(pathbuf) < 0)
|
||||||
|
bb_error_msg_and_die("bridge %s does not exist", name);
|
||||||
|
|
||||||
|
printf("%s\n"
|
||||||
|
" bridge id\t\t%s", name, filedata);
|
||||||
|
|
||||||
|
strcpy(sfx, "root_id");
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf("\n designated root\t%s", filedata);
|
||||||
|
|
||||||
|
strcpy(sfx + 5, "port"); // "root_port"
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf_xstrtou("\n root port\t\t%4u\t\t\t");
|
||||||
|
|
||||||
|
strcpy(sfx + 6, "ath_cost"); // "root_path_cost"
|
||||||
|
read_file(pathbuf);
|
||||||
|
printf_xstrtou("path cost\t\t%4u\n");
|
||||||
|
|
||||||
|
strcpy(sfx, "max_age");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer(" max age\t\t");
|
||||||
|
show_bridge_timer("\t\t\tbridge max age\t\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "hello_time");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\n hello time\t\t");
|
||||||
|
show_bridge_timer("\t\t\tbridge hello time\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "forward_delay");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\n forward delay\t\t");
|
||||||
|
show_bridge_timer("\t\t\tbridge forward delay\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "ageing_time");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\n ageing time\t\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "hello_timer");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\n hello timer\t\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "tcn_timer");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\t\t\ttcn timer\t\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "topology_change_timer");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\n topology change timer\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "gc_timer");
|
||||||
|
read_file(pathbuf);
|
||||||
|
show_bridge_timer("\t\t\tgc timer\t\t");
|
||||||
|
|
||||||
|
printf("\n flags\t\t\t");
|
||||||
|
|
||||||
|
strcpy(sfx, "topology_change");
|
||||||
|
read_file(pathbuf);
|
||||||
|
if (!LONE_CHAR(filedata, '0'))
|
||||||
|
printf("TOPOLOGY_CHANGE ");
|
||||||
|
|
||||||
|
strcpy(sfx, "topology_change_detected");
|
||||||
|
read_file(pathbuf);
|
||||||
|
if (!LONE_CHAR(filedata, '0'))
|
||||||
|
printf("TOPOLOGY_CHANGE_DETECTED ");
|
||||||
|
printf("\n\n\n");
|
||||||
|
|
||||||
|
show_bridge_ports(name);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
@ -288,6 +494,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
"addbr\0" "delbr\0" "addif\0" "delif\0"
|
"addbr\0" "delbr\0" "addif\0" "delif\0"
|
||||||
IF_FEATURE_BRCTL_FANCY(
|
IF_FEATURE_BRCTL_FANCY(
|
||||||
"stp\0"
|
"stp\0"
|
||||||
|
"showstp\0"
|
||||||
"setageing\0" "setfd\0" "sethello\0" "setmaxage\0"
|
"setageing\0" "setfd\0" "sethello\0" "setmaxage\0"
|
||||||
"setpathcost\0" "setportprio\0"
|
"setpathcost\0" "setportprio\0"
|
||||||
"setbridgeprio\0"
|
"setbridgeprio\0"
|
||||||
@ -297,6 +504,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif
|
enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif
|
||||||
IF_FEATURE_BRCTL_FANCY(,
|
IF_FEATURE_BRCTL_FANCY(,
|
||||||
ARG_stp,
|
ARG_stp,
|
||||||
|
ARG_showstp,
|
||||||
ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage,
|
ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage,
|
||||||
ARG_setpathcost, ARG_setportprio,
|
ARG_setpathcost, ARG_setportprio,
|
||||||
ARG_setbridgeprio,
|
ARG_setbridgeprio,
|
||||||
@ -388,6 +596,10 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
show_bridge_macs(br);
|
show_bridge_macs(br);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
if (key == ARG_showstp) {
|
||||||
|
show_bridge_stp(br);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (!*argv) /* all but 'addbr/delbr' need at least two arguments */
|
if (!*argv) /* all but 'addbr/delbr' need at least two arguments */
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
|
Loading…
Reference in New Issue
Block a user