brctl: fold show_bridge_ports_ into its caller

function                                             old     new   delta
brctl_main                                          2235    2171     -64

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2019-10-12 19:42:37 +02:00
parent 3398753818
commit b4fa16d5ed

View File

@ -390,28 +390,6 @@ static void show_bridge_port(const char *name)
printf("\n\n"); 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) static void show_bridge_stp(const char *name)
{ {
char pathbuf[IFNAMSIZ + sizeof("/bridge/topology_change_timer") + 8]; char pathbuf[IFNAMSIZ + sizeof("/bridge/topology_change_timer") + 8];
@ -490,7 +468,24 @@ static void show_bridge_stp(const char *name)
printf("TOPOLOGY_CHANGE_DETECTED "); printf("TOPOLOGY_CHANGE_DETECTED ");
printf("\n\n\n"); printf("\n\n\n");
show_bridge_ports(name); /* Show bridge ports */
{
DIR *ifaces;
/* sfx points past "BR/bridge/", turn it to "BR/brif": */
strcpy(sfx - 4, "f");
ifaces = opendir(pathbuf);
if (ifaces) {
struct dirent *ent;
while ((ent = readdir(ifaces)) != NULL) {
if (DOT_OR_DOTDOT(ent->d_name))
continue; /* . or .. */
show_bridge_port(ent->d_name);
}
if (ENABLE_FEATURE_CLEAN_UP)
closedir(ifaces);
}
}
} }
#endif #endif
@ -519,6 +514,8 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
) )
IF_FEATURE_BRCTL_SHOW(, ARG_show) IF_FEATURE_BRCTL_SHOW(, ARG_show)
}; };
int key;
char *br;
argv++; argv++;
if (!*argv) { if (!*argv) {
@ -528,166 +525,157 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
xchdir("/sys/class/net"); xchdir("/sys/class/net");
// while (*argv) key = index_in_strings(keywords, *argv);
{ if (key == -1) /* no match found in keywords array, bail out. */
smallint key; bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
char *br; argv++;
key = index_in_strings(keywords, *argv);
if (key == -1) /* no match found in keywords array, bail out. */
bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
argv++;
#if ENABLE_FEATURE_BRCTL_SHOW #if ENABLE_FEATURE_BRCTL_SHOW
if (key == ARG_show) { /* show [BR]... */ if (key == ARG_show) { /* show [BR]... */
DIR *net; DIR *net;
struct dirent *ent; struct dirent *ent;
int need_hdr = 1; int need_hdr = 1;
int exitcode = EXIT_SUCCESS; int exitcode = EXIT_SUCCESS;
if (*argv) { if (*argv) {
/* "show BR1 BR2 BR3" */ /* "show BR1 BR2 BR3" */
do { do {
if (show_bridge(*argv, need_hdr) >= 0) { if (show_bridge(*argv, need_hdr) >= 0) {
need_hdr = 0; need_hdr = 0;
} else { } else {
bb_error_msg("bridge %s does not exist", *argv); bb_error_msg("bridge %s does not exist", *argv);
//TODO: if device exists, but is not a BR, brctl from bridge-utils 1.6 //TODO: if device exists, but is not a BR, brctl from bridge-utils 1.6
//says this instead: "device eth0 is not a bridge" //says this instead: "device eth0 is not a bridge"
exitcode = EXIT_FAILURE; exitcode = EXIT_FAILURE;
} }
} while (*++argv != NULL); } while (*++argv != NULL);
return exitcode;
}
/* "show" (if no ifaces, shows nothing, not even header) */
net = xopendir(".");
while ((ent = readdir(net)) != NULL) {
if (DOT_OR_DOTDOT(ent->d_name))
continue; /* . or .. */
if (show_bridge(ent->d_name, need_hdr) >= 0)
need_hdr = 0;
}
if (ENABLE_FEATURE_CLEAN_UP)
closedir(net);
return exitcode; return exitcode;
} }
/* "show" (if no ifaces, shows nothing, not even header) */
net = xopendir(".");
while ((ent = readdir(net)) != NULL) {
if (DOT_OR_DOTDOT(ent->d_name))
continue; /* . or .. */
if (show_bridge(ent->d_name, need_hdr) >= 0)
need_hdr = 0;
}
if (ENABLE_FEATURE_CLEAN_UP)
closedir(net);
return exitcode;
}
#endif #endif
if (!*argv) /* all but 'show' need at least one argument */ if (!*argv) /* all but 'show' need at least one argument */
bb_show_usage(); bb_show_usage();
br = *argv++; br = *argv++;
if (key == ARG_addbr || key == ARG_delbr) { if (key == ARG_addbr || key == ARG_delbr) {
/* addbr or delbr */ /* brctl from bridge-utils 1.6 still uses ioctl
/* brctl from bridge-utils 1.6 still uses ioctl * for SIOCBRADDBR / SIOCBRDELBR, not /sys accesses
* for SIOCBRADDBR / SIOCBRDELBR, not /sys accesses */
*/ int fd = xsocket(AF_INET, SOCK_STREAM, 0);
int fd = xsocket(AF_INET, SOCK_STREAM, 0); ioctl_or_perror_and_die(fd,
ioctl_or_perror_and_die(fd, key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR,
key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR, br, "bridge %s", br
br, "bridge %s", br );
); //close(fd);
//close(fd); //goto done;
//goto done; /* bridge-utils 1.6 simply ignores trailing args:
/* bridge-utils 1.6 simply ignores trailing args: * "brctl addbr BR1 ARGS" ignores ARGS
* "brctl addbr BR1 ARGS" ignores ARGS */
*/ if (ENABLE_FEATURE_CLEAN_UP)
if (ENABLE_FEATURE_CLEAN_UP) close(fd);
close(fd); return EXIT_SUCCESS;
return EXIT_SUCCESS; }
}
if (key == ARG_showmacs) { if (key == ARG_showmacs) {
show_bridge_macs(br); show_bridge_macs(br);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if (key == ARG_showstp) { if (key == ARG_showstp) {
show_bridge_stp(br); show_bridge_stp(br);
return EXIT_SUCCESS; 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();
#if ENABLE_FEATURE_BRCTL_FANCY #if ENABLE_FEATURE_BRCTL_FANCY
if (key == ARG_stp) { /* stp */ if (key == ARG_stp) {
static const char no_yes[] ALIGN1 = static const char no_yes[] ALIGN1 =
"0\0" "off\0" "n\0" "no\0" /* 0 .. 3 */ "0\0" "off\0" "n\0" "no\0" /* 0 .. 3 */
"1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */ "1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */
int onoff = index_in_strings(no_yes, *argv); int onoff = index_in_strings(no_yes, *argv);
if (onoff < 0) if (onoff < 0)
bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
onoff = (unsigned)onoff / 4; onoff = (unsigned)onoff / 4;
write_uint(br, "bridge/stp_state", onoff); write_uint(br, "bridge/stp_state", onoff);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if ((unsigned)(key - ARG_setageing) < 4) { /* time related ops */ if ((unsigned)(key - ARG_setageing) < 4) { /* time related ops */
/* setageing BR N: "N*100\n" to /sys/class/net/BR/bridge/ageing_time /* setageing BR N: "N*100\n" to /sys/class/net/BR/bridge/ageing_time
* setfd BR N: "N*100\n" to /sys/class/net/BR/bridge/forward_delay * setfd BR N: "N*100\n" to /sys/class/net/BR/bridge/forward_delay
* sethello BR N: "N*100\n" to /sys/class/net/BR/bridge/hello_time * sethello BR N: "N*100\n" to /sys/class/net/BR/bridge/hello_time
* setmaxage BR N: "N*100\n" to /sys/class/net/BR/bridge/max_age * setmaxage BR N: "N*100\n" to /sys/class/net/BR/bridge/max_age
*/ */
write_uint(br, write_uint(br,
nth_string( nth_string(
"bridge/ageing_time" "\0" /* ARG_setageing */ "bridge/ageing_time" "\0" /* ARG_setageing */
"bridge/forward_delay""\0" /* ARG_setfd */ "bridge/forward_delay""\0" /* ARG_setfd */
"bridge/hello_time" "\0" /* ARG_sethello */ "bridge/hello_time" "\0" /* ARG_sethello */
"bridge/max_age", /* ARG_setmaxage */ "bridge/max_age", /* ARG_setmaxage */
key - ARG_setageing key - ARG_setageing
), ),
str_to_jiffies(*argv) str_to_jiffies(*argv)
); );
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if (key == ARG_setbridgeprio) { if (key == ARG_setbridgeprio) {
write_uint(br, "bridge/priority", xatoi_positive(*argv)); write_uint(br, "bridge/priority", xatoi_positive(*argv));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if (key == ARG_setpathcost if (key == ARG_setpathcost
|| key == ARG_setportprio || key == ARG_setportprio
) { ) {
if (!argv[1]) if (!argv[1])
bb_show_usage(); bb_show_usage();
/* BR is not used (and ignored!) for these commands: /* BR is not used (and ignored!) for these commands:
* "setpathcost BR PORT N" writes "N\n" to * "setpathcost BR PORT N" writes "N\n" to
* /sys/class/net/PORT/brport/path_cost * /sys/class/net/PORT/brport/path_cost
* "setportprio BR PORT N" writes "N\n" to * "setportprio BR PORT N" writes "N\n" to
* /sys/class/net/PORT/brport/priority * /sys/class/net/PORT/brport/priority
*/ */
write_uint(argv[0], write_uint(argv[0],
nth_string( nth_string(
"brport/path_cost" "\0" /* ARG_setpathcost */ "brport/path_cost" "\0" /* ARG_setpathcost */
"brport/priority", /* ARG_setportprio */ "brport/priority", /* ARG_setportprio */
key - ARG_setpathcost key - ARG_setpathcost
), ),
xatoi_positive(argv[1]) xatoi_positive(argv[1])
); );
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
#endif #endif
/* always true: if (key == ARG_addif || key == ARG_delif) */ { /* always true: if (key == ARG_addif || key == ARG_delif) */ {
/* addif or delif */ struct ifreq ifr;
struct ifreq ifr; int fd = xsocket(AF_INET, SOCK_STREAM, 0);
int fd = xsocket(AF_INET, SOCK_STREAM, 0);
strncpy_IFNAMSIZ(ifr.ifr_name, br); strncpy_IFNAMSIZ(ifr.ifr_name, br);
ifr.ifr_ifindex = if_nametoindex(*argv); ifr.ifr_ifindex = if_nametoindex(*argv);
if (ifr.ifr_ifindex == 0) { if (ifr.ifr_ifindex == 0) {
bb_perror_msg_and_die("iface %s", *argv); bb_perror_msg_and_die("iface %s", *argv);
}
ioctl_or_perror_and_die(fd,
key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF,
&ifr, "bridge %s", br
);
if (ENABLE_FEATURE_CLEAN_UP)
close(fd);
return EXIT_SUCCESS;
} }
ioctl_or_perror_and_die(fd,
key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF,
&ifr, "bridge %s", br
);
if (ENABLE_FEATURE_CLEAN_UP)
close(fd);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;