diff options
author | Bernhard Reutner-Fischer | 2008-01-13 18:43:50 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer | 2008-01-13 18:43:50 +0000 |
commit | 1aac3ab49f8d1de8d7a66adb57cbd7df4a1f2020 (patch) | |
tree | 37986fc0fbda3d5de0c432b6048833e435420755 /networking | |
parent | 78e1d58d3a320637cbe78fa5c86081931392875b (diff) | |
download | busybox-1aac3ab49f8d1de8d7a66adb57cbd7df4a1f2020.zip busybox-1aac3ab49f8d1de8d7a66adb57cbd7df4a1f2020.tar.gz |
- shrink a bit and implement time related fancy features. Improve help texts.
text data bss dec hex filename
253 20 0 273 111 networking/brctl.o.bare
613 20 0 633 279 networking/brctl.o.fancy-time
Diffstat (limited to 'networking')
-rw-r--r-- | networking/Config.in | 19 | ||||
-rw-r--r-- | networking/brctl.c | 132 |
2 files changed, 115 insertions, 36 deletions
diff --git a/networking/Config.in b/networking/Config.in index 83579bc..f4d4e7e 100644 --- a/networking/Config.in +++ b/networking/Config.in @@ -52,6 +52,25 @@ config BRCTL 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 + Add support for extended option like: + setageing, setfd, sethello, setmaxage, + setpathcost, setportprio, setbridgeprio, + stp config DNSD bool "dnsd" diff --git a/networking/brctl.c b/networking/brctl.c index 5255a55..7c9d90f 100644 --- a/networking/brctl.c +++ b/networking/brctl.c @@ -6,6 +6,9 @@ * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ +/* This applet currently uses only the ioctl interface and no sysfs at all. + * At the time of this writing this was considered a feature. + */ #include "libbb.h" #include <linux/sockios.h> #include <net/if.h> @@ -15,72 +18,129 @@ #endif #define ENABLE_FEATURE_BRCTL_SHOW 0 #define USE_FEATURE_BRCTL_SHOW(...) - - -/* Fancy diagnostics -- printing add/del -- costs 49 bytes. */ #if 0 -#define BRCTL_VERBOSE(...) __VA_ARGS__ +#define ENABLE_FEATURE_BRCTL_FANCY 0 +#if ENABLE_FEATURE_BRCTL_FANCY +#define USE_FEATURE_BRCTL_FANCY(...) __VA_ARGS__ #else -#define BRCTL_VERBOSE(...) +#define USE_FEATURE_BRCTL_FANCY(...) +#endif +#endif +#if ENABLE_FEATURE_BRCTL_FANCY +#include <linux/if_bridge.h> +/* FIXME: These 4 funcs are not really clean and could be improved */ +static inline ALWAYS_INLINE void strtotimeval(struct timeval *tv, + const char *time_str) +{ + double secs; + if (sscanf(time_str, "%lf", &secs) != 1) + bb_error_msg_and_die (bb_msg_invalid_arg, time_str, "timespec"); + tv->tv_sec = secs; + tv->tv_usec = 1000000 * (secs - tv->tv_sec); +} + +static inline ALWAYS_INLINE unsigned long __tv_to_jiffies(const struct timeval *tv) +{ + unsigned long long jif; + + jif = 1000000ULL * tv->tv_sec + tv->tv_usec; + + return jif/10000; +} +# ifdef UNUSED && 00 +static void __jiffies_to_tv(struct timeval *tv, unsigned long jiffies) +{ + unsigned long long tvusec; + + tvusec = 10000ULL*jiffies; + tv->tv_sec = tvusec/1000000; + tv->tv_usec = tvusec - 1000000 * tv->tv_sec; +} +# endif +static unsigned long str_to_jiffies(const char *time_str) +{ + struct timeval tv; + strtotimeval(&tv, time_str); + return __tv_to_jiffies(&tv); +} #endif -int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int brctl_main(int argc, char **argv) + +int brctl_main(int argc ATTRIBUTE_UNUSED, char **argv) MAIN_EXTERNALLY_VISIBLE; +int brctl_main(int argc ATTRIBUTE_UNUSED, char **argv) { int fd; static const char keywords[] ALIGN1 = "addbr\0" "delbr\0" "addif\0" "delif\0" - USE_FEATURE_BRCTL_SHOW("show\0"); - enum { ARG_addbr = 1, ARG_delbr, ARG_addif, ARG_delif - USE_FEATURE_BRCTL_SHOW(, ARG_show) }; - smalluint key; - static char info[] = BRCTL_VERBOSE("%s ")"bridge %s\0 iface %s"; + USE_FEATURE_BRCTL_FANCY( + "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" + "setpathcost\0" "setportprio\0" "setbridgeprio\0" + "stp\0" + ) + USE_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); + enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif + USE_FEATURE_BRCTL_FANCY(, + ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, + ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio, + ARG_stp + ) + USE_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) }; + smallint key; + struct ifreq ifr; + static char info[] = "bridge %s\0 iface %s"; char *br; argv++; while (*argv) { - BRCTL_VERBOSE(char *op;) - - key = index_in_strings(keywords, *argv) + 1; - if (key == 0) /* no match found in keywords array, bail out. */ + 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++; #if ENABLE_FEATURE_BRCTL_SHOW if (key == ARG_show) { /* show */ - ; + goto out; /* FIXME: implement me! :) */ } #endif - BRCTL_VERBOSE(op = (char*)((key % 2) ? "add" : "del");) fd = xsocket(AF_INET, SOCK_STREAM, 0); br = *(argv++); - if (key < 3) { /* addbr or delbr */ - if (ioctl(fd, key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR, br) < 0) - { - info[9 BRCTL_VERBOSE(+3)] = '\0'; - bb_perror_msg_and_die(info, BRCTL_VERBOSE(op,) br); - } + if (key == ARG_addbr || key == ARG_delbr) { /* addbr or delbr */ + ioctl_or_perror_and_die(fd, + key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR, + br, info, br); + goto done; } - if (key > 2) { /* addif or delif */ - struct ifreq ifr; + if (!*argv) /* all but 'show' need at least one argument */ + bb_show_usage(); + safe_strncpy(ifr.ifr_name, br, IFNAMSIZ); + if (key == ARG_addif || key == ARG_delif) { /* addif or delif */ char *brif; - if (!*argv) - bb_show_usage(); brif = *(argv++); - if (!(ifr.ifr_ifindex = if_nametoindex(brif))) { - bb_perror_msg_and_die(info+11 BRCTL_VERBOSE(+3), brif); - } - safe_strncpy(ifr.ifr_name, br, IFNAMSIZ); - if (ioctl(fd, - key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF, &ifr) < 0) { - info[9 BRCTL_VERBOSE(+3)] = ','; - bb_perror_msg_and_die (info, BRCTL_VERBOSE(op,) br, brif); + bb_perror_msg_and_die(info+11, brif); } + ioctl_or_perror_and_die(fd, + key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF, + &ifr, info, br); + } +#if ENABLE_FEATURE_BRCTL_FANCY + if (key - ARG_delif < 5) { /* time related ops */ + unsigned long op = (key == ARG_setageing) ? BRCTL_SET_AGEING_TIME : + (key == ARG_setfd) ? BRCTL_SET_BRIDGE_FORWARD_DELAY: + (key == ARG_sethello) ? BRCTL_SET_BRIDGE_HELLO_TIME: + (key == ARG_setmaxage) ? BRCTL_SET_BRIDGE_MAX_AGE : + -1/*will never be used */; + unsigned long jiff = str_to_jiffies (*(argv++)); + unsigned long args[4] = {op, jiff, 0, 0}; + ifr.ifr_data = (char *) &args; + xioctl(fd, SIOCDEVPRIVATE, &ifr); } +#endif + done: if (ENABLE_FEATURE_CLEAN_UP) close(fd); } + out: return EXIT_SUCCESS; } |