diff options
author | shemminger <shemminger> | 2004-05-21 17:41:48 +0000 |
---|---|---|
committer | shemminger <shemminger> | 2004-05-21 17:41:48 +0000 |
commit | 328f4711bbc369dcccf8f8cfba2adf5dd0f74479 (patch) | |
tree | 8dd07660534f32407d249d0259e2e8f3a62f2ae5 /brctl/brctl_cmd.c | |
parent | 064717a4d7e47b47ba42e658abfd36acaa4a65d6 (diff) | |
download | android_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.c | 367 |
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); +} |