[PATCH] brctl: Added support for showmacs command

Denys Vlasenko vda.linux at googlemail.com
Tue Oct 8 12:44:18 UTC 2019


Applied, thanks

On Sun, Sep 15, 2019 at 6:06 PM Martin Lewis <martin.lewis.x84 at gmail.com> wrote:
>
> Signed-off-by: Martin Lewis <martin.lewis.x84 at 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 at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list