aboutsummaryrefslogtreecommitdiffstats
path: root/brctl/brctl_cmd.c
diff options
context:
space:
mode:
authorshemminger <shemminger>2004-05-21 17:41:48 +0000
committershemminger <shemminger>2004-05-21 17:41:48 +0000
commit328f4711bbc369dcccf8f8cfba2adf5dd0f74479 (patch)
tree8dd07660534f32407d249d0259e2e8f3a62f2ae5 /brctl/brctl_cmd.c
parent064717a4d7e47b47ba42e658abfd36acaa4a65d6 (diff)
downloadandroid_external_brctl-328f4711bbc369dcccf8f8cfba2adf5dd0f74479.tar.gz
android_external_brctl-328f4711bbc369dcccf8f8cfba2adf5dd0f74479.tar.bz2
android_external_brctl-328f4711bbc369dcccf8f8cfba2adf5dd0f74479.zip
New version of command and library that use sysfs.
Update make system to build with or without sysfs.
Diffstat (limited to 'brctl/brctl_cmd.c')
-rw-r--r--brctl/brctl_cmd.c367
1 files changed, 202 insertions, 165 deletions
diff --git a/brctl/brctl_cmd.c b/brctl/brctl_cmd.c
index 99d9725..f9da974 100644
--- a/brctl/brctl_cmd.c
+++ b/brctl/brctl_cmd.c
@@ -35,280 +35,291 @@ static int strtotimeval(struct timeval *tv, const char *time)
return 0;
}
-void br_cmd_addbr(struct bridge *br, char *brname, char *arg1)
+static int br_cmd_addbr(char** argv)
{
int err;
- if ((err = br_add_bridge(brname)) == 0)
- return;
+ switch (err = br_add_bridge(argv[1])) {
+ case 0:
+ return 0;
- switch (err) {
case EEXIST:
fprintf(stderr, "device %s already exists; can't create "
- "bridge with the same name\n", brname);
- break;
-
+ "bridge with the same name\n", argv[1]);
+ return 1;
default:
fprintf(stderr, "add bridge failed: %s\n",
strerror(err));
- break;
+ return 1;
}
}
-void br_cmd_delbr(struct bridge *br, char *brname, char *arg1)
+static int br_cmd_delbr(char** argv)
{
int err;
- if ((err = br_del_bridge(brname)) == 0)
- return;
+ switch (err = br_del_bridge(argv[1])){
+ case 0:
+ return 0;
- switch (err) {
case ENXIO:
fprintf(stderr, "bridge %s doesn't exist; can't delete it\n",
- brname);
- break;
+ argv[1]);
+ return 1;
case EBUSY:
fprintf(stderr, "bridge %s is still up; can't delete it\n",
- brname);
- break;
+ argv[1]);
+ return 1;
default:
fprintf(stderr, "can't delete bridge %s: %s\n",
- brname, strerror(err));
- break;
+ argv[1], strerror(err));
+ return 1;
}
}
-void br_cmd_addif(struct bridge *br, char *ifname, char *arg1)
+static int br_cmd_addif(char** argv)
{
int err;
- int ifindex;
+ int ifindex = if_nametoindex(argv[2]);
- ifindex = if_nametoindex(ifname);
if (!ifindex) {
- fprintf(stderr, "interface %s does not exist!\n", ifname);
- return;
+ fprintf(stderr, "interface %s does not exist!\n", argv[2]);
+ return 1;
}
- if ((err = br_add_interface(br, ifindex)) == 0)
- return;
+ switch (err = br_add_interface(argv[1], ifindex)) {
+ case 0:
+ return 0;
- switch (err) {
case EBUSY:
fprintf(stderr, "device %s is already a member of a bridge; "
- "can't enslave it to bridge %s.\n", ifname,
- br->ifname);
- break;
+ "can't enslave it to bridge %s.\n", argv[2],
+ argv[1]);
+ return 1;
case ELOOP:
fprintf(stderr, "device %s is a bridge device itself; "
"can't enslave a bridge device to a bridge device.\n",
- ifname);
- break;
+ argv[2]);
+ return 1;
default:
fprintf(stderr, "can't add %s to bridge %s: %s\n",
- ifname, br->ifname, strerror(err));
- break;
+ argv[2], argv[1], strerror(err));
+ return 1;
}
}
-void br_cmd_delif(struct bridge *br, char *ifname, char *arg1)
+static int br_cmd_delif(char** argv)
{
int err;
- int ifindex;
+ int ifindex = if_nametoindex(argv[2]);
- ifindex = if_nametoindex(ifname);
if (!ifindex) {
- fprintf(stderr, "interface %s does not exist!\n", ifname);
- return;
+ fprintf(stderr, "interface %s does not exist!\n", argv[2]);
+ return 1;
}
- if ((err = br_del_interface(br, ifindex)) == 0)
- return;
+ switch (err = br_del_interface(argv[1], ifindex)) {
+ case 0:
+ return 0;
- switch (err) {
case EINVAL:
fprintf(stderr, "device %s is not a slave of %s\n",
- ifname, br->ifname);
- break;
+ argv[2], argv[1]);
+ return 1;
default:
fprintf(stderr, "can't delete %s from %s: %s\n",
- ifname, br->ifname, strerror(err));
- break;
+ argv[2], argv[1], strerror(err));
+ return 1;
}
}
-void br_cmd_setageing(struct bridge *br, char *time, char *arg1)
+static int br_cmd_setageing(char** argv)
{
int err;
struct timeval tv;
-
- if (strtotimeval(&tv, time)) {
+
+ if (strtotimeval(&tv, argv[2])) {
fprintf(stderr, "bad ageing time value\n");
- return;
+ return 1;
}
- err = br_set_ageing_time(br, &tv);
+
+ err = br_set_ageing_time(argv[1], &tv);
if (err)
fprintf(stderr, "set ageing time failed: %s\n",
strerror(err));
+
+ return err != 0;
}
-void br_cmd_setbridgeprio(struct bridge *br, char *_prio, char *arg1)
+static int br_cmd_setbridgeprio(char** argv)
{
int prio;
int err;
- if (sscanf(_prio, "%i", &prio) != 1) {
+ if (sscanf(argv[2], "%i", &prio) != 1) {
fprintf(stderr,"bad priority\n");
- return;
+ return 1;
}
- err = br_set_bridge_priority(br, prio);
+
+ err = br_set_bridge_priority(argv[1], prio);
if (err)
fprintf(stderr, "set bridge priority failed: %s\n",
strerror(err));
+ return err != 0;
}
-void br_cmd_setfd(struct bridge *br, char *time, char *arg1)
+static int br_cmd_setfd(char** argv)
{
struct timeval tv;
int err;
- if (strtotimeval(&tv, time)) {
+ if (strtotimeval(&tv, argv[2])) {
fprintf(stderr, "bad forward delay value\n");
- return;
+ return 1;
}
- err = br_set_bridge_forward_delay(br, &tv);
+ err = br_set_bridge_forward_delay(argv[1], &tv);
if (err)
fprintf(stderr, "set forward delay failed: %s\n",
strerror(err));
+
+ return err != 0;
}
-void br_cmd_sethello(struct bridge *br, char *time, char *arg1)
+static int br_cmd_sethello(char** argv)
{
struct timeval tv;
int err;
- if (strtotimeval(&tv, time)) {
+ if (strtotimeval(&tv, argv[2])) {
fprintf(stderr, "bad hello timer value\n");
- return;
+ return 1;
}
- err = br_set_bridge_hello_time(br, &tv);
+ err = br_set_bridge_hello_time(argv[1], &tv);
if (err)
fprintf(stderr, "set hello timer failed: %s\n",
strerror(err));
+
+ return err != 0;
}
-void br_cmd_setmaxage(struct bridge *br, char *time, char *arg1)
+static int br_cmd_setmaxage(char** argv)
{
struct timeval tv;
int err;
- if (strtotimeval(&tv, time)) {
+ if (strtotimeval(&tv, argv[2])) {
fprintf(stderr, "bad max age value\n");
- return;
+ return 1;
}
- err = br_set_bridge_max_age(br, &tv);
+ err = br_set_bridge_max_age(argv[1], &tv);
if (err)
fprintf(stderr, "set max age failed: %s\n",
strerror(err));
+
+ return err != 0;
}
-void br_cmd_setpathcost(struct bridge *br, char *arg0, char *arg1)
+static int br_cmd_setpathcost(char** argv)
{
int cost, err;
- struct port *p;
- if (sscanf(arg1, "%i", &cost) != 1) {
+ if (sscanf(argv[3], "%i", &cost) != 1) {
fprintf(stderr, "bad path cost value\n");
- return;
- }
-
- if ((p = br_find_port(br, arg0)) == NULL) {
- fprintf(stderr, "can't find port %s in bridge %s\n", arg0, br->ifname);
- return;
+ return 1;
}
- err = br_set_path_cost(p, cost);
+ err = br_set_path_cost(argv[1], argv[2], cost);
if (err)
fprintf(stderr, "set path cost failed: %s\n",
strerror(err));
+ return err != 0;
}
-void br_cmd_setportprio(struct bridge *br, char *arg0, char *arg1)
+static int br_cmd_setportprio(char** argv)
{
int cost, err;
- struct port *p;
- if (sscanf(arg1, "%i", &cost) != 1) {
+ if (sscanf(argv[3], "%i", &cost) != 1) {
fprintf(stderr, "bad path priority value\n");
- return;
+ return 1;
}
- if ((p = br_find_port(br, arg0)) == NULL) {
- fprintf(stderr, "can't find port %s in bridge %s\n", arg0, br->ifname);
- return;
- }
- err = br_set_port_priority(p, cost);
+ err = br_set_path_cost(argv[1], argv[2], cost);
if (err)
fprintf(stderr, "set port priority failed: %s\n",
- strerror(err));
+ strerror(errno));
+
+ return err != 0;
}
-void br_cmd_stp(struct bridge *br, char *arg0, char *arg1)
+static int br_cmd_stp(char** argv)
{
int stp, err;
- if (!strcmp(arg0, "on") || !strcmp(arg0, "yes")
- || !strcmp(arg0, "1"))
+ if (!strcmp(argv[2], "on") || !strcmp(argv[2], "yes")
+ || !strcmp(argv[2], "1"))
stp = 1;
- else if (!strcmp(arg0, "off") || !strcmp(arg0, "no")
- || !strcmp(arg0, "0"))
+ else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "no")
+ || !strcmp(argv[2], "0"))
stp = 0;
else {
fprintf(stderr, "expect on/off for argument\n");
- return;
+ return 1;
}
- err = br_set_stp_state(br, stp);
+ err = br_set_stp_state(argv[1], stp);
if (err)
- fprintf(stderr, "set stp status failed: %d\n", err);
+ fprintf(stderr, "set stp status failed: %s\n",
+ strerror(errno));
+ return err != 0;
}
-void br_cmd_showstp(struct bridge *br, char *arg0, char *arg1)
+static int br_cmd_showstp(char** argv)
{
struct bridge_info info;
- if (br_get_bridge_info(br, &info)) {
- fprintf(stderr, "%s: can't get info %s\n", br->ifname,
+ if (br_get_bridge_info(argv[1], &info)) {
+ fprintf(stderr, "%s: can't get info %s\n", argv[1],
strerror(errno));
- return;
+ return 1;
}
- br_dump_info(br, &info);
+
+ br_dump_info(argv[1], &info);
+ return 0;
}
-void br_cmd_show(struct bridge *br, char *arg0, char *arg1)
+static int show_bridge(const char *name, void *arg)
{
struct bridge_info info;
- printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n");
- for (br = bridge_list; br; br = br->next) {
- printf("%s\t\t", br->ifname);
- if (br_get_bridge_info(br, &info)) {
- fprintf(stderr, "can't get info %s\n",
+ printf("%s\t\t", name);
+ fflush(stdout);
+
+ if (br_get_bridge_info(name, &info)) {
+ fprintf(stderr, "can't get info %s\n",
strerror(errno));
- continue;
- }
+ return 1;
+ }
- br_dump_bridge_id((unsigned char *)&info.bridge_id);
- printf("\t%s\t\t", info.stp_enabled?"yes":"no");
- br_dump_interface_list(br);
+ br_dump_bridge_id((unsigned char *)&info.bridge_id);
+ printf("\t%s\t\t", info.stp_enabled?"yes":"no");
- }
+ br_dump_interface_list(name);
+ return 0;
+}
+
+static int br_cmd_show(char** argv)
+{
+ printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n");
+ br_foreach_bridge(show_bridge, NULL);
+ return 0;
}
static int compare_fdbs(const void *_f0, const void *_f1)
@@ -319,75 +330,101 @@ static int compare_fdbs(const void *_f0, const void *_f1)
return memcmp(f0->mac_addr, f1->mac_addr, 6);
}
-static void __dump_fdb_entry(const struct fdb_entry *f)
-{
- printf("%3i\t", f->port_no);
- printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t",
- f->mac_addr[0], f->mac_addr[1], f->mac_addr[2],
- f->mac_addr[3], f->mac_addr[4], f->mac_addr[5]);
- printf("%s\t\t", f->is_local?"yes":"no");
- br_show_timer(&f->ageing_timer_value);
- printf("\n");
-}
-
-void br_cmd_showmacs(struct bridge *br, char *arg0, char *arg1)
+static int br_cmd_showmacs(char** argv)
{
- struct fdb_entry fdb[1024];
- int offset;
-
- printf("port no\tmac addr\t\tis local?\tageing timer\n");
-
- offset = 0;
- while (1) {
- int i;
- int num;
-
- num = br_read_fdb(br, fdb, offset, 1024);
- if (num < 0) {
- fprintf(stderr, "read of forward table failed\n");
- break;
+ const char *brname = argv[1];
+#define CHUNK 128
+ int i, n;
+ struct fdb_entry *fdb = NULL;
+ int offset = 0;
+
+ for(;;) {
+ fdb = realloc(fdb, (offset + CHUNK) * sizeof(struct fdb_entry));
+ if (!fdb) {
+ fprintf(stderr, "Out of memory\n");
+ return 1;
}
-
- if (!num)
+
+ n = br_read_fdb(brname, fdb+offset, offset, CHUNK);
+ if (n == 0)
break;
-
- qsort(fdb, num, sizeof(struct fdb_entry), compare_fdbs);
- for (i=0;i<num;i++)
- __dump_fdb_entry(fdb+i);
+ if (n < 0) {
+ fprintf(stderr, "read of forward table failed: %s\n",
+ strerror(errno));
+ return 1;
+ }
+
+ offset += n;
+ }
+
+ qsort(fdb, offset, sizeof(struct fdb_entry), compare_fdbs);
- offset += num;
+ printf("port no\tmac addr\t\tis local?\tageing timer\n");
+ for (i = 0; i < offset; i++) {
+ const struct fdb_entry *f = fdb + i;
+ printf("%3i\t", f->port_no);
+ printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t",
+ f->mac_addr[0], f->mac_addr[1], f->mac_addr[2],
+ f->mac_addr[3], f->mac_addr[4], f->mac_addr[5]);
+ printf("%s\t\t", f->is_local?"yes":"no");
+ br_show_timer(&f->ageing_timer_value);
+ printf("\n");
}
+ return 0;
}
-static struct command commands[] = {
- {0, 1, "addbr", br_cmd_addbr},
- {1, 1, "addif", br_cmd_addif},
- {0, 1, "delbr", br_cmd_delbr},
- {1, 1, "delif", br_cmd_delif},
- {1, 1, "setageing", br_cmd_setageing},
- {1, 1, "setbridgeprio", br_cmd_setbridgeprio},
- {1, 1, "setfd", br_cmd_setfd},
- {1, 1, "sethello", br_cmd_sethello},
- {1, 1, "setmaxage", br_cmd_setmaxage},
- {1, 2, "setpathcost", br_cmd_setpathcost},
- {1, 2, "setportprio", br_cmd_setportprio},
- {0, 0, "show", br_cmd_show},
- {1, 0, "showmacs", br_cmd_showmacs},
- {1, 0, "showstp", br_cmd_showstp},
- {1, 1, "stp", br_cmd_stp},
+static const struct command commands[] = {
+ { 1, "addbr", br_cmd_addbr, "<bridge>\t\tadd bridge" },
+ { 1, "delbr", br_cmd_delbr, "<bridge>\t\tdelete bridge" },
+ { 2, "addif", br_cmd_addif,
+ "<bridge> <device>\tadd interface to bridge" },
+ { 2, "delif", br_cmd_delif,
+ "<bridge> <device>\tdelete interface from bridge" },
+ { 2, "setageing", br_cmd_setageing,
+ "<bridge> <time>\t\tset ageing time" },
+ { 2, "setbridgeprio", br_cmd_setbridgeprio,
+ "<bridge> <prio>\t\tset bridge priority" },
+ { 2, "setfd", br_cmd_setfd,
+ "<bridge> <time>\t\tset bridge forward delay" },
+ { 2, "sethello", br_cmd_sethello,
+ "<bridge> <time>\t\tset hello time" },
+ { 2, "setmaxage", br_cmd_setmaxage,
+ "<bridge> <time>\t\tset max message age" },
+ { 3, "setpathcost", br_cmd_setpathcost,
+ "<bridge> <port> <cost>\tset path cost" },
+ { 3, "setportprio", br_cmd_setportprio,
+ "<bridge> <port> <prio>\tset port priority" },
+ { 0, "show", br_cmd_show, "\t\t\tshow a list of bridges" },
+ { 1, "showmacs", br_cmd_showmacs,
+ "<bridge>\t\tshow a list of mac addrs"},
+ { 1, "showstp", br_cmd_showstp,
+ "<bridge>\t\tshow bridge stp info"},
+ { 1, "stp", br_cmd_stp,
+ "<bridge> <state>\tturn stp on/off" },
};
-struct command *br_command_lookup(char *cmd)
+const struct command *command_lookup(const char *cmd)
{
int i;
- int numcommands;
-
- numcommands = sizeof(commands)/sizeof(commands[0]);
- for (i=0;i<numcommands;i++)
+ for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
if (!strcmp(cmd, commands[i].name))
return &commands[i];
+ }
return NULL;
}
+
+void command_help(const struct command *cmd)
+{
+ printf("\t%-10s\t%s\n", cmd->name, cmd->help);
+}
+
+void command_helpall(void)
+{
+ int i;
+
+ for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++)
+ command_help(commands+i);
+}