- implement brctl setpathcost, setportprio, setbridgeprio, stp

text    data     bss     dec     hex filename
    907      20       0     927     39f networking/brctl.o
This commit is contained in:
Bernhard Reutner-Fischer 2008-01-14 16:10:11 +00:00
parent c2f0de5eef
commit 2b11fb483e
3 changed files with 98 additions and 22 deletions

View File

@ -133,6 +133,10 @@ USE_FEATURE_BRCTL_FANCY("\n" \
" setfd <bridge <time> set bridge forward delay\n" \ " setfd <bridge <time> set bridge forward delay\n" \
" sethello <bridge <time> set hello time\n" \ " sethello <bridge <time> set hello time\n" \
" setmaxage <bridge <time> set max message age\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] turn stp on/off\n" \
) )
#define bunzip2_trivial_usage \ #define bunzip2_trivial_usage \
"[OPTION]... [FILE]" "[OPTION]... [FILE]"

View File

@ -71,6 +71,7 @@ config FEATURE_BRCTL_FANCY
setageing, setfd, sethello, setmaxage, setageing, setfd, sethello, setmaxage,
setpathcost, setportprio, setbridgeprio, setpathcost, setportprio, setbridgeprio,
stp stp
This adds about 600 bytes.
config DNSD config DNSD
bool "dnsd" bool "dnsd"

View File

@ -4,6 +4,9 @@
* *
* Copyright (C) 2008 by Bernhard Fischer * Copyright (C) 2008 by Bernhard Fischer
* *
* Some helper functions from bridge-utils are
* Copyright (C) 2000 Lennert Buytenhek
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. * 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. /* This applet currently uses only the ioctl interface and no sysfs at all.
@ -13,19 +16,21 @@
#include <linux/sockios.h> #include <linux/sockios.h>
#include <net/if.h> #include <net/if.h>
/* Maximum number of ports supported per bridge interface. */
#ifndef MAX_PORTS
#define MAX_PORTS 32
#endif
/* 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 #ifdef ENABLE_FEATURE_BRCTL_SHOW
#error Remove these #error Remove these
#endif #endif
#define ENABLE_FEATURE_BRCTL_SHOW 0 #define ENABLE_FEATURE_BRCTL_SHOW 0
#define USE_FEATURE_BRCTL_SHOW(...) #define USE_FEATURE_BRCTL_SHOW(...)
#if 0
#define ENABLE_FEATURE_BRCTL_FANCY 0
#if ENABLE_FEATURE_BRCTL_FANCY
#define USE_FEATURE_BRCTL_FANCY(...) __VA_ARGS__
#else
#define USE_FEATURE_BRCTL_FANCY(...)
#endif
#endif
#if ENABLE_FEATURE_BRCTL_FANCY #if ENABLE_FEATURE_BRCTL_FANCY
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
/* FIXME: These 4 funcs are not really clean and could be improved */ /* FIXME: These 4 funcs are not really clean and could be improved */
@ -33,7 +38,11 @@ static inline ALWAYS_INLINE void strtotimeval(struct timeval *tv,
const char *time_str) const char *time_str)
{ {
double secs; double secs;
#if BRCTL_USE_INTERNAL
if (!(secs = /*bb_*/strtod(time_str, NULL)))
#else
if (sscanf(time_str, "%lf", &secs) != 1) if (sscanf(time_str, "%lf", &secs) != 1)
#endif
bb_error_msg_and_die (bb_msg_invalid_arg, time_str, "timespec"); bb_error_msg_and_die (bb_msg_invalid_arg, time_str, "timespec");
tv->tv_sec = secs; tv->tv_sec = secs;
tv->tv_usec = 1000000 * (secs - tv->tv_sec); tv->tv_usec = 1000000 * (secs - tv->tv_sec);
@ -47,7 +56,7 @@ static inline ALWAYS_INLINE unsigned long __tv_to_jiffies(const struct timeval *
return jif/10000; return jif/10000;
} }
# ifdef UNUSED && 00 # if 00
static void __jiffies_to_tv(struct timeval *tv, unsigned long jiffies) static void __jiffies_to_tv(struct timeval *tv, unsigned long jiffies)
{ {
unsigned long long tvusec; unsigned long long tvusec;
@ -63,6 +72,15 @@ static unsigned long str_to_jiffies(const char *time_str)
strtotimeval(&tv, time_str); strtotimeval(&tv, time_str);
return __tv_to_jiffies(&tv); return __tv_to_jiffies(&tv);
} }
static void arm_ioctl(unsigned long *args,
unsigned long arg0, unsigned long arg1, unsigned long arg2)
{
args[0] = arg0;
args[1] = arg1;
args[2] = arg2;
args[3] = 0;
}
#endif #endif
@ -73,22 +91,27 @@ int brctl_main(int argc ATTRIBUTE_UNUSED, char **argv)
static const char keywords[] ALIGN1 = static const char keywords[] ALIGN1 =
"addbr\0" "delbr\0" "addif\0" "delif\0" "addbr\0" "delbr\0" "addif\0" "delif\0"
USE_FEATURE_BRCTL_FANCY( USE_FEATURE_BRCTL_FANCY(
"stp\0"
"setageing\0" "setfd\0" "sethello\0" "setmaxage\0" "setageing\0" "setfd\0" "sethello\0" "setmaxage\0"
"setpathcost\0" "setportprio\0" "setbridgeprio\0" "setpathcost\0" "setportprio\0" "setbridgeprio\0"
"stp\0"
) )
USE_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); USE_FEATURE_BRCTL_SHOW("showmacs\0" "show\0");
enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif
USE_FEATURE_BRCTL_FANCY(, USE_FEATURE_BRCTL_FANCY(,
ARG_stp,
ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage,
ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio, ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio
ARG_stp
) )
USE_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) }; USE_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) };
smallint key; smallint key;
struct ifreq ifr; struct ifreq ifr;
static char info[] = "bridge %s\0 iface %s"; static char info[] = "bridge %s\0 iface %s";
char *br; char *br, *brif;
#if ENABLE_FEATURE_BRCTL_FANCY
unsigned long args[4] = {0, 0, 0, 0};
int port;
int tmp;
#endif
argv++; argv++;
while (*argv) { while (*argv) {
@ -114,8 +137,6 @@ int brctl_main(int argc ATTRIBUTE_UNUSED, char **argv)
bb_show_usage(); bb_show_usage();
safe_strncpy(ifr.ifr_name, br, IFNAMSIZ); safe_strncpy(ifr.ifr_name, br, IFNAMSIZ);
if (key == ARG_addif || key == ARG_delif) { /* addif or delif */ if (key == ARG_addif || key == ARG_delif) { /* addif or delif */
char *brif;
brif = *(argv++); brif = *(argv++);
if (!(ifr.ifr_ifindex = if_nametoindex(brif))) { if (!(ifr.ifr_ifindex = if_nametoindex(brif))) {
bb_perror_msg_and_die(info+11, brif); bb_perror_msg_and_die(info+11, brif);
@ -123,24 +144,74 @@ int brctl_main(int argc ATTRIBUTE_UNUSED, char **argv)
ioctl_or_perror_and_die(fd, ioctl_or_perror_and_die(fd,
key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF, key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF,
&ifr, info, br); &ifr, info, br);
goto done;
} }
#if ENABLE_FEATURE_BRCTL_FANCY #if ENABLE_FEATURE_BRCTL_FANCY
if (key - ARG_delif < 5) { /* time related ops */ ifr.ifr_data = (char *) &args;
if (key == ARG_stp) { /* stp */
/* FIXME: parsing yes/y/on/1 versus no/n/off/0 is too involved */
arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE,
(unsigned)(**argv - '0'), 0);
goto fire;
}
if ((unsigned)(key - ARG_stp) < 5) { /* time related ops */
unsigned long op = (key == ARG_setageing) ? BRCTL_SET_AGEING_TIME : unsigned long op = (key == ARG_setageing) ? BRCTL_SET_AGEING_TIME :
(key == ARG_setfd) ? BRCTL_SET_BRIDGE_FORWARD_DELAY: (key == ARG_setfd) ? BRCTL_SET_BRIDGE_FORWARD_DELAY:
(key == ARG_sethello) ? BRCTL_SET_BRIDGE_HELLO_TIME: (key == ARG_sethello) ? BRCTL_SET_BRIDGE_HELLO_TIME:
(key == ARG_setmaxage) ? BRCTL_SET_BRIDGE_MAX_AGE : (key == ARG_setmaxage) ? BRCTL_SET_BRIDGE_MAX_AGE :
-1/*will never be used */; -1/* will never be used */;
unsigned long jiff = str_to_jiffies (*(argv++)); arm_ioctl(args, op, str_to_jiffies (*argv), 0);
unsigned long args[4] = {op, jiff, 0, 0}; goto fire;
ifr.ifr_data = (char *) &args;
xioctl(fd, SIOCDEVPRIVATE, &ifr);
} }
port = -1;
if (key == ARG_setpathcost || key == ARG_setportprio) {/* get portnum */
int ifidx[MAX_PORTS];
unsigned i;
if (!(port = if_nametoindex(*argv)))
bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port");
argv++;
memset(ifidx, 0, sizeof ifidx);
arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx,
MAX_PORTS);
xioctl(fd, SIOCDEVPRIVATE, &ifr);
for (i = 0; i < MAX_PORTS; i++)
if (ifidx[i] == port) {
port = i;
break;
}
}
if (key == ARG_setpathcost
|| key == ARG_setportprio || key == ARG_setbridgeprio) {
unsigned long op = (key == ARG_setpathcost) ? BRCTL_SET_PATH_COST :
(key == ARG_setportprio) ? BRCTL_SET_PORT_PRIORITY :
(key == ARG_setbridgeprio) ? BRCTL_SET_BRIDGE_PRIORITY :
-1/* will never be used */;
unsigned long arg1 = port;
unsigned long arg2;
# if BRCTL_USE_INTERNAL
tmp = xatoi(*argv);
# else
if (sscanf(*argv, "%i", &tmp) != 1)
bb_error_msg_and_die(bb_msg_invalid_arg, *argv,
key == ARG_setpathcost ? "cost" : "prio");
# endif
if (key == ARG_setbridgeprio) {
arg1 = tmp;
arg2 = 0;
} else
arg2 = tmp;
arm_ioctl(args, op, arg1, arg2);
}
fire:
/* Execute the previously set command. */
xioctl(fd, SIOCDEVPRIVATE, &ifr);
argv++;
#endif #endif
done: done:
if (ENABLE_FEATURE_CLEAN_UP) if (ENABLE_FEATURE_CLEAN_UP)
close(fd); close(fd);
} }
out: USE_FEATURE_BRCTL_SHOW(out:)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }