Applied, thanks
On Sun, Sep 15, 2019 at 6:06 PM Martin Lewis <martin.lewis....@gmail.com> wrote: > > Signed-off-by: Martin Lewis <martin.lewis....@gmail.com> > --- > networking/brctl.c | 119 > ++++++++++++++++++++++++++++++++++++++++++++--------- > 1 file changed, 100 insertions(+), 19 deletions(-) > > diff --git a/networking/brctl.c b/networking/brctl.c > index 586ca9b..35771a5 100644 > --- a/networking/brctl.c > +++ b/networking/brctl.c > @@ -61,10 +61,10 @@ > //usage: "\n setbridgeprio BRIDGE PRIO Set bridge priority" > //usage: "\n setportprio BRIDGE IFACE PRIO Set port priority" > //usage: "\n setpathcost BRIDGE IFACE COST Set path cost" > +//usage: "\n showmacs BRIDGE List mac addrs" > //usage: ) > // Not yet implemented: > // hairpin BRIDGE IFACE on|off Hairpin on/off > -// showmacs BRIDGE List mac addrs > // showstp BRIDGE Show stp info > > #include "libbb.h" > @@ -196,6 +196,94 @@ static void write_uint(const char *name, const char > *leaf, unsigned val) > bb_simple_perror_msg_and_die(name); > close(fd); > } > + > +struct __fdb_entry { > + uint8_t mac_addr[6]; > + uint8_t port_no; > + uint8_t is_local; > + uint32_t ageing_timer_value; > + uint8_t port_hi; > + uint8_t pad0; > + uint16_t unused; > +}; > + > +static int compare_fdbs(const void *_f0, const void *_f1) > +{ > + const struct __fdb_entry *f0 = _f0; > + const struct __fdb_entry *f1 = _f1; > + > + return memcmp(f0->mac_addr, f1->mac_addr, 6); > +} > + > +static int read_bridge_forward_db(const char *name, struct __fdb_entry > **_fdb, size_t *_nentries) > +{ > + struct __fdb_entry *fdb = NULL; > + size_t nentries = 0; > + > + char *path; > + int fd; > + ssize_t cc; > + > + path = concat_path_file(name, "/brforward"); > + fd = open(path, O_RDONLY); > + free(path); > + if (fd < 0) > + return -1; > + > + for (;;) { > + fdb = xrealloc(fdb, (nentries + 1) * sizeof(*fdb)); > + cc = full_read(fd, &fdb[nentries], sizeof(*fdb)); > + if (cc < 0) { > + bb_perror_msg_and_die("can't read bridge %s forward > db", name); > + } > + if (cc == 0) { > + break; > + } > + ++nentries; > + } > + > + close(fd); > + > + qsort(fdb, nentries, sizeof(*fdb), compare_fdbs); > + > + *_fdb = fdb; > + *_nentries = nentries; > + return 0; > +} > + > +static inline void show_bridge_timer(uint32_t ageing_timer) > +{ > + unsigned long long tvusec = 10000ULL * ageing_timer; > + unsigned int tv_sec = tvusec / 1000000; > + unsigned int tv_usec = tvusec - (1000000 * tv_sec); > + > + printf("%4u.%.2u", tv_sec, tv_usec / 10000); > +} > + > +static int show_bridge_macs(const char *name) > +{ > + struct __fdb_entry *fdb; > + size_t nentries; > + size_t i; > + > + if (read_bridge_forward_db(name, &fdb, &nentries) < 0) > + return -1; > + > + printf("port no\tmac addr\t\tis local?\tageing timer\n"); > + for (i = 0; i < nentries; ++i) { > + const struct __fdb_entry *f = &fdb[i]; > + printf("%3u\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"); > + show_bridge_timer(f->ageing_timer_value); > + printf("\n"); > + } > + > + free(fdb); > + return 0; > +} > #endif > > int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; > @@ -208,6 +296,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) > "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" > "setpathcost\0" "setportprio\0" > "setbridgeprio\0" > + "showmacs\0" > ) > IF_FEATURE_BRCTL_SHOW("show\0"); > enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif > @@ -215,7 +304,8 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) > ARG_stp, > ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, > ARG_setpathcost, ARG_setportprio, > - ARG_setbridgeprio > + ARG_setbridgeprio, > + ARG_showmacs > ) > IF_FEATURE_BRCTL_SHOW(, ARG_show) > }; > @@ -299,6 +389,14 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) > return EXIT_SUCCESS; > } > > + if (key == ARG_showmacs) { > + if (show_bridge_macs(br) < 0) { > + bb_error_msg("bridge %s does not exist", br); > + return EXIT_FAILURE; > + } > + return EXIT_SUCCESS; > + } > + > if (!*argv) /* all but 'addbr/delbr' need at least two > arguments */ > bb_show_usage(); > > @@ -365,23 +463,6 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) > //goto done_next_argv; > return EXIT_SUCCESS; > } > - > -/* TODO: "showmacs BR" > - * port no\tmac addr\t\tis local?\tageing timer > - * <sp><sp>1\txx:xx:xx:xx:xx:xx\tno\t\t<sp><sp><sp>1.31 > - * port no mac addr is local? ageing timer > - * 1 xx:xx:xx:xx:xx:xx no 1.31 > - * Read fixed-sized records from /sys/class/net/BR/brforward: > - * struct __fdb_entry { > - * uint8_t mac_addr[ETH_ALEN]; > - * uint8_t port_no; //lsb > - * uint8_t is_local; > - * uint32_t ageing_timer_value; > - * uint8_t port_hi; > - * uint8_t pad0; > - * uint16_t unused; > - * }; > - */ > #endif > /* always true: if (key == ARG_addif || key == ARG_delif) */ { > /* addif or delif */ > -- > 1.9.1 > > _______________________________________________ > busybox mailing list > busybox@busybox.net > http://lists.busybox.net/mailman/listinfo/busybox _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox