aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-10-12 19:42:37 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-10-12 19:42:37 +0200
commitb4fa16d5ed51d13c7c8e9037e4613cc147ce27da (patch)
treebe20e942ec9ac7c3f7c79923abd5a67bea820fb9
parent339875381800668df26922dd0fb8789e9862698d (diff)
downloadbusybox-w32-b4fa16d5ed51d13c7c8e9037e4613cc147ce27da.tar.gz
busybox-w32-b4fa16d5ed51d13c7c8e9037e4613cc147ce27da.tar.bz2
busybox-w32-b4fa16d5ed51d13c7c8e9037e4613cc147ce27da.zip
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>
-rw-r--r--networking/brctl.c318
1 files changed, 153 insertions, 165 deletions
diff --git a/networking/brctl.c b/networking/brctl.c
index 04ea08253..09c55cd0e 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -390,28 +390,6 @@ static void show_bridge_port(const char *name)
390 printf("\n\n"); 390 printf("\n\n");
391} 391}
392 392
393static void show_bridge_ports(const char *name)
394{
395 DIR *ifaces;
396 struct dirent *ent;
397 char pathbuf[IFNAMSIZ + sizeof("/brif") + 8];
398
399#if IFNAMSIZ == 16
400 sprintf(pathbuf, "%.16s/brif", name);
401#else
402 sprintf(pathbuf, "%.*s/brif", (int)IFNAMSIZ, name);
403#endif
404 ifaces = opendir(pathbuf);
405 if (ifaces) {
406 while ((ent = readdir(ifaces)) != NULL) {
407 if (DOT_OR_DOTDOT(ent->d_name))
408 continue; /* . or .. */
409 show_bridge_port(ent->d_name);
410 }
411 closedir(ifaces);
412 }
413}
414
415static void show_bridge_stp(const char *name) 393static void show_bridge_stp(const char *name)
416{ 394{
417 char pathbuf[IFNAMSIZ + sizeof("/bridge/topology_change_timer") + 8]; 395 char pathbuf[IFNAMSIZ + sizeof("/bridge/topology_change_timer") + 8];
@@ -490,7 +468,24 @@ static void show_bridge_stp(const char *name)
490 printf("TOPOLOGY_CHANGE_DETECTED "); 468 printf("TOPOLOGY_CHANGE_DETECTED ");
491 printf("\n\n\n"); 469 printf("\n\n\n");
492 470
493 show_bridge_ports(name); 471 /* Show bridge ports */
472 {
473 DIR *ifaces;
474
475 /* sfx points past "BR/bridge/", turn it to "BR/brif": */
476 strcpy(sfx - 4, "f");
477 ifaces = opendir(pathbuf);
478 if (ifaces) {
479 struct dirent *ent;
480 while ((ent = readdir(ifaces)) != NULL) {
481 if (DOT_OR_DOTDOT(ent->d_name))
482 continue; /* . or .. */
483 show_bridge_port(ent->d_name);
484 }
485 if (ENABLE_FEATURE_CLEAN_UP)
486 closedir(ifaces);
487 }
488 }
494} 489}
495#endif 490#endif
496 491
@@ -519,6 +514,8 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
519 ) 514 )
520 IF_FEATURE_BRCTL_SHOW(, ARG_show) 515 IF_FEATURE_BRCTL_SHOW(, ARG_show)
521 }; 516 };
517 int key;
518 char *br;
522 519
523 argv++; 520 argv++;
524 if (!*argv) { 521 if (!*argv) {
@@ -528,166 +525,157 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
528 525
529 xchdir("/sys/class/net"); 526 xchdir("/sys/class/net");
530 527
531// while (*argv) 528 key = index_in_strings(keywords, *argv);
532 { 529 if (key == -1) /* no match found in keywords array, bail out. */
533 smallint key; 530 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
534 char *br; 531 argv++;
535
536 key = index_in_strings(keywords, *argv);
537 if (key == -1) /* no match found in keywords array, bail out. */
538 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
539 argv++;
540 532
541#if ENABLE_FEATURE_BRCTL_SHOW 533#if ENABLE_FEATURE_BRCTL_SHOW
542 if (key == ARG_show) { /* show [BR]... */ 534 if (key == ARG_show) { /* show [BR]... */
543 DIR *net; 535 DIR *net;
544 struct dirent *ent; 536 struct dirent *ent;
545 int need_hdr = 1; 537 int need_hdr = 1;
546 int exitcode = EXIT_SUCCESS; 538 int exitcode = EXIT_SUCCESS;
547 539
548 if (*argv) { 540 if (*argv) {
549 /* "show BR1 BR2 BR3" */ 541 /* "show BR1 BR2 BR3" */
550 do { 542 do {
551 if (show_bridge(*argv, need_hdr) >= 0) { 543 if (show_bridge(*argv, need_hdr) >= 0) {
552 need_hdr = 0; 544 need_hdr = 0;
553 } else { 545 } else {
554 bb_error_msg("bridge %s does not exist", *argv); 546 bb_error_msg("bridge %s does not exist", *argv);
555//TODO: if device exists, but is not a BR, brctl from bridge-utils 1.6 547//TODO: if device exists, but is not a BR, brctl from bridge-utils 1.6
556//says this instead: "device eth0 is not a bridge" 548//says this instead: "device eth0 is not a bridge"
557 exitcode = EXIT_FAILURE; 549 exitcode = EXIT_FAILURE;
558 } 550 }
559 } while (*++argv != NULL); 551 } while (*++argv != NULL);
560 return exitcode;
561 }
562
563 /* "show" (if no ifaces, shows nothing, not even header) */
564 net = xopendir(".");
565 while ((ent = readdir(net)) != NULL) {
566 if (DOT_OR_DOTDOT(ent->d_name))
567 continue; /* . or .. */
568 if (show_bridge(ent->d_name, need_hdr) >= 0)
569 need_hdr = 0;
570 }
571 if (ENABLE_FEATURE_CLEAN_UP)
572 closedir(net);
573 return exitcode; 552 return exitcode;
574 } 553 }
554
555 /* "show" (if no ifaces, shows nothing, not even header) */
556 net = xopendir(".");
557 while ((ent = readdir(net)) != NULL) {
558 if (DOT_OR_DOTDOT(ent->d_name))
559 continue; /* . or .. */
560 if (show_bridge(ent->d_name, need_hdr) >= 0)
561 need_hdr = 0;
562 }
563 if (ENABLE_FEATURE_CLEAN_UP)
564 closedir(net);
565 return exitcode;
566 }
575#endif 567#endif
576 568
577 if (!*argv) /* all but 'show' need at least one argument */ 569 if (!*argv) /* all but 'show' need at least one argument */
578 bb_show_usage(); 570 bb_show_usage();
579 571
580 br = *argv++; 572 br = *argv++;
581
582 if (key == ARG_addbr || key == ARG_delbr) {
583 /* addbr or delbr */
584 /* brctl from bridge-utils 1.6 still uses ioctl
585 * for SIOCBRADDBR / SIOCBRDELBR, not /sys accesses
586 */
587 int fd = xsocket(AF_INET, SOCK_STREAM, 0);
588 ioctl_or_perror_and_die(fd,
589 key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR,
590 br, "bridge %s", br
591 );
592 //close(fd);
593 //goto done;
594 /* bridge-utils 1.6 simply ignores trailing args:
595 * "brctl addbr BR1 ARGS" ignores ARGS
596 */
597 if (ENABLE_FEATURE_CLEAN_UP)
598 close(fd);
599 return EXIT_SUCCESS;
600 }
601 573
602 if (key == ARG_showmacs) { 574 if (key == ARG_addbr || key == ARG_delbr) {
603 show_bridge_macs(br); 575 /* brctl from bridge-utils 1.6 still uses ioctl
604 return EXIT_SUCCESS; 576 * for SIOCBRADDBR / SIOCBRDELBR, not /sys accesses
605 } 577 */
606 if (key == ARG_showstp) { 578 int fd = xsocket(AF_INET, SOCK_STREAM, 0);
607 show_bridge_stp(br); 579 ioctl_or_perror_and_die(fd,
608 return EXIT_SUCCESS; 580 key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR,
609 } 581 br, "bridge %s", br
582 );
583 //close(fd);
584 //goto done;
585 /* bridge-utils 1.6 simply ignores trailing args:
586 * "brctl addbr BR1 ARGS" ignores ARGS
587 */
588 if (ENABLE_FEATURE_CLEAN_UP)
589 close(fd);
590 return EXIT_SUCCESS;
591 }
610 592
611 if (!*argv) /* all but 'addbr/delbr' need at least two arguments */ 593 if (key == ARG_showmacs) {
612 bb_show_usage(); 594 show_bridge_macs(br);
595 return EXIT_SUCCESS;
596 }
597 if (key == ARG_showstp) {
598 show_bridge_stp(br);
599 return EXIT_SUCCESS;
600 }
601
602 if (!*argv) /* all but 'addbr/delbr' need at least two arguments */
603 bb_show_usage();
613 604
614#if ENABLE_FEATURE_BRCTL_FANCY 605#if ENABLE_FEATURE_BRCTL_FANCY
615 if (key == ARG_stp) { /* stp */ 606 if (key == ARG_stp) {
616 static const char no_yes[] ALIGN1 = 607 static const char no_yes[] ALIGN1 =
617 "0\0" "off\0" "n\0" "no\0" /* 0 .. 3 */ 608 "0\0" "off\0" "n\0" "no\0" /* 0 .. 3 */
618 "1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */ 609 "1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */
619 int onoff = index_in_strings(no_yes, *argv); 610 int onoff = index_in_strings(no_yes, *argv);
620 if (onoff < 0) 611 if (onoff < 0)
621 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); 612 bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
622 onoff = (unsigned)onoff / 4; 613 onoff = (unsigned)onoff / 4;
623 write_uint(br, "bridge/stp_state", onoff); 614 write_uint(br, "bridge/stp_state", onoff);
624 return EXIT_SUCCESS; 615 return EXIT_SUCCESS;
625 } 616 }
626 617
627 if ((unsigned)(key - ARG_setageing) < 4) { /* time related ops */ 618 if ((unsigned)(key - ARG_setageing) < 4) { /* time related ops */
628 /* setageing BR N: "N*100\n" to /sys/class/net/BR/bridge/ageing_time 619 /* setageing BR N: "N*100\n" to /sys/class/net/BR/bridge/ageing_time
629 * setfd BR N: "N*100\n" to /sys/class/net/BR/bridge/forward_delay 620 * setfd BR N: "N*100\n" to /sys/class/net/BR/bridge/forward_delay
630 * sethello BR N: "N*100\n" to /sys/class/net/BR/bridge/hello_time 621 * sethello BR N: "N*100\n" to /sys/class/net/BR/bridge/hello_time
631 * setmaxage BR N: "N*100\n" to /sys/class/net/BR/bridge/max_age 622 * setmaxage BR N: "N*100\n" to /sys/class/net/BR/bridge/max_age
632 */ 623 */
633 write_uint(br, 624 write_uint(br,
634 nth_string( 625 nth_string(
635 "bridge/ageing_time" "\0" /* ARG_setageing */ 626 "bridge/ageing_time" "\0" /* ARG_setageing */
636 "bridge/forward_delay""\0" /* ARG_setfd */ 627 "bridge/forward_delay""\0" /* ARG_setfd */
637 "bridge/hello_time" "\0" /* ARG_sethello */ 628 "bridge/hello_time" "\0" /* ARG_sethello */
638 "bridge/max_age", /* ARG_setmaxage */ 629 "bridge/max_age", /* ARG_setmaxage */
639 key - ARG_setageing 630 key - ARG_setageing
640 ), 631 ),
641 str_to_jiffies(*argv) 632 str_to_jiffies(*argv)
642 ); 633 );
643 return EXIT_SUCCESS; 634 return EXIT_SUCCESS;
644 } 635 }
645 636
646 if (key == ARG_setbridgeprio) { 637 if (key == ARG_setbridgeprio) {
647 write_uint(br, "bridge/priority", xatoi_positive(*argv)); 638 write_uint(br, "bridge/priority", xatoi_positive(*argv));
648 return EXIT_SUCCESS; 639 return EXIT_SUCCESS;
649 } 640 }
650 641
651 if (key == ARG_setpathcost 642 if (key == ARG_setpathcost
652 || key == ARG_setportprio 643 || key == ARG_setportprio
653 ) { 644 ) {
654 if (!argv[1]) 645 if (!argv[1])
655 bb_show_usage(); 646 bb_show_usage();
656 /* BR is not used (and ignored!) for these commands: 647 /* BR is not used (and ignored!) for these commands:
657 * "setpathcost BR PORT N" writes "N\n" to 648 * "setpathcost BR PORT N" writes "N\n" to
658 * /sys/class/net/PORT/brport/path_cost 649 * /sys/class/net/PORT/brport/path_cost
659 * "setportprio BR PORT N" writes "N\n" to 650 * "setportprio BR PORT N" writes "N\n" to
660 * /sys/class/net/PORT/brport/priority 651 * /sys/class/net/PORT/brport/priority
661 */ 652 */
662 write_uint(argv[0], 653 write_uint(argv[0],
663 nth_string( 654 nth_string(
664 "brport/path_cost" "\0" /* ARG_setpathcost */ 655 "brport/path_cost" "\0" /* ARG_setpathcost */
665 "brport/priority", /* ARG_setportprio */ 656 "brport/priority", /* ARG_setportprio */
666 key - ARG_setpathcost 657 key - ARG_setpathcost
667 ), 658 ),
668 xatoi_positive(argv[1]) 659 xatoi_positive(argv[1])
669 ); 660 );
670 return EXIT_SUCCESS; 661 return EXIT_SUCCESS;
671 } 662 }
672#endif 663#endif
673 /* always true: if (key == ARG_addif || key == ARG_delif) */ { 664 /* always true: if (key == ARG_addif || key == ARG_delif) */ {
674 /* addif or delif */ 665 struct ifreq ifr;
675 struct ifreq ifr; 666 int fd = xsocket(AF_INET, SOCK_STREAM, 0);
676 int fd = xsocket(AF_INET, SOCK_STREAM, 0); 667
677 668 strncpy_IFNAMSIZ(ifr.ifr_name, br);
678 strncpy_IFNAMSIZ(ifr.ifr_name, br); 669 ifr.ifr_ifindex = if_nametoindex(*argv);
679 ifr.ifr_ifindex = if_nametoindex(*argv); 670 if (ifr.ifr_ifindex == 0) {
680 if (ifr.ifr_ifindex == 0) { 671 bb_perror_msg_and_die("iface %s", *argv);
681 bb_perror_msg_and_die("iface %s", *argv);
682 }
683 ioctl_or_perror_and_die(fd,
684 key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF,
685 &ifr, "bridge %s", br
686 );
687 if (ENABLE_FEATURE_CLEAN_UP)
688 close(fd);
689 return EXIT_SUCCESS;
690 } 672 }
673 ioctl_or_perror_and_die(fd,
674 key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF,
675 &ifr, "bridge %s", br
676 );
677 if (ENABLE_FEATURE_CLEAN_UP)
678 close(fd);
691 } 679 }
692 680
693 return EXIT_SUCCESS; 681 return EXIT_SUCCESS;