PATCH: brctl show

L. Gabriel Somlo somlo at cmu.edu
Sat Apr 5 14:10:44 PDT 2008


Hi,

I need to be able to see the list of ports currently configured on a
bridge, so I took a shot at implementing 'brctl show'. Might follow up
with 'showmacs' later, but for now, let me know what you think, and
please apply...

Thanks,
Gabriel
-------------- next part --------------
diff -NarU5 busybox-svn-21645.orig/include/usage.h busybox-svn-21645/include/usage.h
--- busybox-svn-21645.orig/include/usage.h	2008-04-05 16:55:33.000000000 -0400
+++ busybox-svn-21645/include/usage.h	2008-04-05 17:05:36.000000000 -0400
@@ -149,10 +149,13 @@
      "\n	setmaxage BRIDGE TIME		Set max message age" \
      "\n	setpathcost BRIDGE COST		Set path cost" \
      "\n	setportprio BRIDGE PRIO		Set port priority" \
      "\n	setbridgeprio BRIDGE PRIO	Set bridge priority" \
      "\n	stp BRIDGE [1|0]		STP on/off" \
+	) \
+	USE_FEATURE_BRCTL_SHOW( \
+     "\n	show			Show a list of bridges" \
 	)
 #define bunzip2_trivial_usage \
        "[OPTION]... [FILE]"
 #define bunzip2_full_usage \
        "Uncompress FILE (or standard input if FILE is '-' or omitted)\n" \
diff -NarU5 busybox-svn-21645.orig/networking/brctl.c busybox-svn-21645/networking/brctl.c
--- busybox-svn-21645.orig/networking/brctl.c	2008-04-05 16:55:29.000000000 -0400
+++ busybox-svn-21645/networking/brctl.c	2008-04-05 17:05:36.000000000 -0400
@@ -23,16 +23,10 @@
 
 /* Use internal number parsing and not the "exact" conversion.  */
 /* #define BRCTL_USE_INTERNAL 0 */ /* use exact conversion */
 #define BRCTL_USE_INTERNAL 1
 
-#ifdef ENABLE_FEATURE_BRCTL_SHOW
-#error Remove these
-#endif
-#define ENABLE_FEATURE_BRCTL_SHOW 0
-#define USE_FEATURE_BRCTL_SHOW(...)
-
 #if ENABLE_FEATURE_BRCTL_FANCY
 #include <linux/if_bridge.h>
 
 /* FIXME: These 4 funcs are not really clean and could be improved */
 static ALWAYS_INLINE void strtotimeval(struct timeval *tv,
@@ -121,26 +115,88 @@
 	while (*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, *argv, applet_name);
 		argv++;
+		fd = xsocket(AF_INET, SOCK_STREAM, 0);
+
 #if ENABLE_FEATURE_BRCTL_SHOW
 		if (key == ARG_show) { /* show */
-			goto out; /* FIXME: implement me! :) */
+			char brname[IFNAMSIZ];
+			int bridx[MAX_PORTS];
+			int i, num;
+			arm_ioctl(args, BRCTL_GET_BRIDGES,
+						(unsigned long) bridx, MAX_PORTS);
+			num = ioctl_or_warn(fd, SIOCGIFBR, args);
+			if (num < 0)
+				bb_simple_perror_msg_and_die("can't get bridge indices");
+			printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n");
+			for (i = 0; i < num; i++) {
+				char ifname[IFNAMSIZ];
+				int ifidx[MAX_PORTS];
+				int j, tabs;
+				struct __bridge_info bi;
+				unsigned char *x;
+
+				ifr.ifr_data = (char *) &args;
+				if (!if_indextoname(bridx[i], brname))
+					bb_perror_msg_and_die("can't get bridge name for index %d", i);
+				safe_strncpy(ifr.ifr_name, brname, IFNAMSIZ);
+
+				arm_ioctl(args, BRCTL_GET_BRIDGE_INFO,
+							(unsigned long) &bi, 0);
+				xioctl(fd, SIOCDEVPRIVATE, &ifr);
+				printf("%s\t\t", brname);
+
+
+				/* print bridge id */
+				x = (unsigned char *) &bi.bridge_id;
+				for (j = 0; j < 8; j++) {
+					printf("%.2x", x[j]);
+					if (j == 1)
+						printf(".");
+				}
+				printf("\t%s", bi.stp_enabled? "yes" : "no");
+
+				/* print interface list */
+				arm_ioctl(args, BRCTL_GET_PORT_LIST,
+							(unsigned long) ifidx, MAX_PORTS);
+				xioctl(fd, SIOCDEVPRIVATE, &ifr);
+				tabs = 0;
+				for (j = 0; j < MAX_PORTS; j++) {
+					if (!ifidx[j])
+						continue;
+					if (!if_indextoname(ifidx[j], ifname))
+						bb_perror_msg_and_die("can't get interface name for index %d", j);
+					if (tabs)
+						printf("\t\t\t\t\t");
+					else
+						tabs = 1;
+					printf("\t\t%s\n", ifname);
+				}
+				if (!tabs)	/* bridge has no interfaces */
+					printf("\n");
+			}
+			goto done;
 		}
 #endif
-		fd = xsocket(AF_INET, SOCK_STREAM, 0);
+
+		if (!*argv) /* all but 'show' need at least one argument */
+			bb_show_usage();
+
 		br = *argv++;
 
 		if (key == ARG_addbr || key == ARG_delbr) { /* addbr or delbr */
 			ioctl_or_perror_and_die(fd,
 					key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR,
 					br, "bridge %s", br);
 			goto done;
 		}
-		if (!*argv) /* all but 'show' need at least one argument */
+
+		if (!*argv) /* all but 'addif/delif' need at least two arguments */
 			bb_show_usage();
+
 		safe_strncpy(ifr.ifr_name, br, IFNAMSIZ);
 		if (key == ARG_addif || key == ARG_delif) { /* addif or delif */
 			brif = *argv++;
 			ifr.ifr_ifindex = if_nametoindex(brif);
 			if (!ifr.ifr_ifindex) {
@@ -217,8 +273,7 @@
 #endif
  done:
 		if (ENABLE_FEATURE_CLEAN_UP)
 			close(fd);
 	}
- USE_FEATURE_BRCTL_SHOW(out:)
 	return EXIT_SUCCESS;
 }
diff -NarU5 busybox-svn-21645.orig/networking/Config.in busybox-svn-21645/networking/Config.in
--- busybox-svn-21645.orig/networking/Config.in	2008-04-05 16:55:29.000000000 -0400
+++ busybox-svn-21645/networking/Config.in	2008-04-05 17:05:36.000000000 -0400
@@ -52,18 +52,10 @@
 	default n
 	help
 	  Manage ethernet bridges.
 	  Supports addbr/delbr and addif/delif.
 
-#config FEATURE_BRCTL_SHOW
-#	bool "Support show, showmac and showstp"
-#	default n
-#	depends on BRCTL
-#	help
-#	  Add support for option which print the current config:
-#	    showmacs, showstp, show
-
 config FEATURE_BRCTL_FANCY
 	bool "Fancy options"
 	default n
 	depends on BRCTL
 	help
@@ -71,10 +63,18 @@
 	    setageing, setfd, sethello, setmaxage,
 	    setpathcost, setportprio, setbridgeprio,
 	    stp
 	  This adds about 600 bytes.
 
+config FEATURE_BRCTL_SHOW
+	bool "Support show, showmac and showstp"
+	default n
+	depends on BRCTL && FEATURE_BRCTL_FANCY
+	help
+	  Add support for option which print the current config:
+	    showmacs, showstp, show
+
 config DNSD
 	bool "dnsd"
 	default n
 	help
 	  Small and static DNS server daemon.


More information about the busybox mailing list