commit 84a761ef3024cc3b5c66e202e3ebb7e5ec81c796 from: Stefan Sperling date: Thu Mar 09 16:45:52 2023 UTC add a "show bridge" command This command provides a quick overview of bridges in the system and shows their member interfaces and descriptions. Long lists of member interfaces wrap at 80 columns. For example: nsh/show bridge % Bridge Status Member Interfaces veb0 up vport0 em1 athn0 tap0 tap1 tap80 tap81 tap82 tap83 tap84 tap85 tap86 tap87 tap88 tap89 tap90 tap91 tap92 tap93 tap94 tap95 tap96 tap97 tap98 tap99 Description: wifi/ethernet/vpn bridge bridge0 down tap72 tap71 tap70 Description: - nsh/ commit - 4dfca50932823e49f95aaf15a6f690e20705e1d8 commit + 84a761ef3024cc3b5c66e202e3ebb7e5ec81c796 blob - 466ff2ef225f9867bc2af333a122be8e53db54c0 blob + 957f80a5b029774b2090aa6cee5d016469084a0e --- bridge.c +++ bridge.c @@ -76,6 +76,7 @@ int bridge_confaddrs(int, char *, char *, FILE *); int bridge_protect(const char *, int, const char *, const char *); int bridge_unprotect(const char *, int, const char *); void brprotect_usage(void); +int show_bridge(char *); char *stpstates[] = { "disabled", @@ -1643,3 +1644,115 @@ brprotect(char *ifname, int ifs, int argc, char **argv else return bridge_unprotect(ifname, ifs, argv[1]); } + +int +show_bridge(char *ifname) +{ + struct if_nameindex *ifn_list, *ifnp; + int ifs, flags, totlen, len, found_bridge = 0, header_shown = 0; + char buf[1024], *p, *member; + struct ifreq ifr; + char ifdescr[IFDESCRSIZE], *description; + + if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("%% show_bridge: socket: %s\n", strerror(errno)); + return 0; + } + + if (ifname) { + if (!is_valid_ifname(ifname) || !is_bridge(ifs, ifname)) { + printf("%% interface %s is not a bridge\n", ifname); + close(ifs); + return 0; + } + } + + if ((ifn_list = if_nameindex()) == NULL) { + printf("%% show_vlan: if_nameindex failed\n"); + close(ifs); + return 0; + } + + for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { + if (ifname) { + if (strcmp(ifname, ifnp->if_name) != 0) + continue; + found_bridge = 1; + } else if (!is_bridge(ifs, ifnp->if_name)) + continue; + + if (!header_shown) { + puts("% Bridge Status Member Interfaces"); + header_shown = 1; + } + if (bridge_list(ifs, ifnp->if_name, NULL, buf, sizeof(buf), + MEMBER) == 0) + buf[0] = '\0'; + + flags = get_ifflags(ifnp->if_name, ifs); + + len = printf(" %-9s %-7s", ifnp->if_name, + (flags & IFF_UP) ? "up" : "down"); + if (len < 0) { + printf("\n%% show_bridge: printf failed: %s\n", + strerror(errno)); + goto out; + } + totlen = len; + + p = buf; + while ((member = strsep(&p, " ")) != NULL) { + if (totlen + strlen(member) >= 80) { + printf("\n "); + len = 19; + totlen = len; + } + + len = printf(" %s", member); + if (len < 0) { + printf("\n%% show_bridge: printf failed: %s\n", + strerror(errno)); + goto out; + } + totlen += len; + } + printf("\n"); + + memset(&ifr, 0, sizeof(ifr)); + if (strlcpy(ifr.ifr_name, ifnp->if_name, + sizeof(ifr.ifr_name)) >= sizeof(ifr.ifr_name)) { + printf("%% %s: interface name is too long\n", + ifnp->if_name); + continue; + } + + ifr.ifr_data = (caddr_t)&ifdescr; + if (ioctl(ifs, SIOCGIFDESCR, &ifr) == 0 && + ifr.ifr_data[0] != '\0') + description = ifr.ifr_data; + else + description = "-"; + printf(" Description: %s\n", description); + + if (found_bridge) + break; + } +out: + if_freenameindex(ifn_list); + close(ifs); + return 0; +} + +int +show_bridges(int argc, char **argv) +{ + switch (argc) { + case 2: + show_bridge(NULL); + break; + case 3: + show_bridge(argv[2]); + break; + } + return 0; +} blob - f1bf08371228e7adba03257740a3c587c0f3d35b blob + 2dd877fc0ca63a5f36fa0cefeedc8773d776bf6d --- commands.c +++ commands.c @@ -168,6 +168,7 @@ Menu showlist[] = { { "arp", "ARP table", CMPL0 0, 0, 0, 1, pr_arp }, { "ndp", "NDP table", CMPL0 0, 0, 0, 1, pr_ndp }, { "vlan", "802.1Q/802.1ad VLANs", CMPL0 0, 0, 0, 1, show_vlans }, + { "bridge", "Ethernet bridges", CMPL0 0, 0, 0, 1, show_bridges }, { "kernel", "Kernel statistics", CMPL(ta) (char **)stts, sizeof(struct stt), 0, 1, pr_kernel }, { "bgp", "BGP information", CMPL(ta) (char **)bgcs, sizeof(struct prot1), 0, 4, pr_prot1 }, { "ospf", "OSPF information", CMPL(ta) (char **)oscs, sizeof(struct prot1), 0, 3, pr_prot1 }, blob - ee19c6a2191be0ed569d12fdb514e512a8fbda74 blob + fc8626fcc61c9c24599265d53954d9ef7b542bb2 --- externs.h +++ externs.h @@ -453,6 +453,7 @@ int flush_bridgedyn(char *); int flush_bridgeall(char *); int flush_bridgerule(char *, char*); int brprotect(char *, int, int, char **); +int show_bridges(int, char **); /* tunnel.c */ int inttunnel(char *, int, int, char **);