commit - 3e900a0e4ce20da82f78e6b5b2ab520729e3e62c
commit + 1edb14c1c67f348a1056574a5a133747677b9f50
blob - b1d9c274def09e29eae01f867cb11514985521cc
blob + 466ff2ef225f9867bc2af333a122be8e53db54c0
--- bridge.c
+++ bridge.c
return (identified);
}
+/*
+ * Find a bridge, if any, which the given interface is a member of.
+ * Return the interface index of the bridge, or 0 if not found.
+ * A given interface can only be a member of one bridge at a time.
+ */
int
+bridge_member_search(int ifs, char *ifname)
+{
+ struct if_nameindex *ifn_list, *ifnp;
+ int idx = 0;
+ char buf[1024];
+ char *p, *s;
+
+ if (!is_valid_ifname(ifname) || is_bridge(ifs, ifname)) {
+ printf("%% bridge_member_search: bad interface %s\n", ifname);
+ return 0;
+ }
+
+ if ((ifn_list = if_nameindex()) == NULL) {
+ printf("%% bridge_member_search: if_nameindex failed\n");
+ return 0;
+ }
+
+ /* Search all bridges. */
+ for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) {
+ if (!is_bridge(ifs, ifnp->if_name))
+ continue;
+ if (bridge_list(ifs, ifnp->if_name, NULL, buf, sizeof(buf),
+ MEMBER) == 0)
+ continue;
+ p = buf;
+ while ((s = strsep(&p, " ")) != NULL) {
+ if (strcmp(s, ifname) == 0) {
+ idx = ifnp->if_index;
+ goto found;
+ }
+ }
+ }
+found:
+ if_freenameindex(ifn_list);
+ return idx;
+}
+
+int
bridge_add(int s, char *brdg, char *ifn)
{
struct ifbreq req;
blob - 9de8d9a66405e5604734ee27af9681d8f639a925
blob + f1bf08371228e7adba03257740a3c587c0f3d35b
--- commands.c
+++ commands.c
{ "sadb", "Security Association Database", CMPL0 0, 0, 0, 0, pr_sadb },
{ "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 },
{ "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 - 0bf82578b4be5faafabd5a26c5369e900453f07d
blob + ee19c6a2191be0ed569d12fdb514e512a8fbda74
--- externs.h
+++ externs.h
void imr_init(char *);
int is_valid_ifname(char *);
int show_int(int, char **);
+int show_vlans(int, char **);
int show_autoconf(int, char **);
int get_rdomain(int, char *);
int get_ifdata(char *, int);
int bridge_confaddrs(int, char *, char *, FILE *);
int bridge_rules(int, char *, char *, char *, FILE *);
int bridge_list(int, char *, char *, char *, int, int);
+int bridge_member_search(int, char *);
int bridge_addrs(int, char *, char *, char *);
int set_ifflag(int, char *, short);
int clr_ifflag(int, char *, short);
blob - ff37c8bb238a7c157908dcaf8a18acf7bd72bfc7
blob + 033de835920959e576e9e82209adc8f2086beb02
--- if.c
+++ if.c
void printifhwfeatures(int, char *);
void show_vnet_parent(int, char *);
void pwe3usage(void);
+int show_vlan(int);
static struct ifmpwreq imrsave;
static char imrif[IFNAMSIZ];
printf("%% intvnetflowid: SIOCSVNETFLOWID: %s\n", strerror(errno));
return(0);
+}
+
+int
+show_vlan(int wanted_vnetid)
+{
+ struct if_nameindex *ifn_list, *ifnp;
+ struct ifreq ifr;
+ struct if_parent ifp;
+ int ifs, vnetid, flags, bridx;
+ const char *parent, *description, *bridgename;
+ char ifdescr[IFDESCRSIZE];
+ char vnetid_str[5];
+ int found_vnetid = 0, header_shown = 0;
+ char ifix_buf[IFNAMSIZ];
+
+ if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ printf("%% show_vlan: %s\n", strerror(errno));
+ 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 (!isprefix("vlan", ifnp->if_name) &&
+ !isprefix("svlan", ifnp->if_name))
+ continue;
+
+ 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;
+ }
+
+ vnetid = -1;
+ if (ioctl(ifs, SIOCGVNETID, &ifr) == -1) {
+ if (errno != EADDRNOTAVAIL) {
+ printf("%% %s: SIOCGVNETID: %s\n",
+ ifnp->if_name, strerror(errno));
+ continue;
+ }
+ } else if (ifr.ifr_vnetid >= 0)
+ vnetid = ifr.ifr_vnetid;
+
+ if (wanted_vnetid != -1) {
+ if (vnetid != wanted_vnetid)
+ continue;
+ found_vnetid = 1;
+ }
+
+ if (!header_shown) {
+ puts("% Interface Tag Status Type "
+ "Parent Bridge Description");
+ header_shown = 1;
+ }
+
+ memset(&ifp, 0, sizeof(ifp));
+ if (strlcpy(ifp.ifp_name, ifnp->if_name,
+ sizeof(ifp.ifp_name)) >= sizeof(ifp.ifp_name)) {
+ printf("%% %s: interface name is too long\n",
+ ifnp->if_name);
+ continue;
+ }
+ parent = "-";
+ if (ioctl(ifs, SIOCGIFPARENT, &ifp) == -1) {
+ if (errno != EADDRNOTAVAIL) {
+ printf("%% %s: SIOCGIFPARENT: %s\n",
+ ifnp->if_name, strerror(errno));
+ continue;
+ }
+ } else
+ parent = ifp.ifp_parent;
+
+ flags = get_ifflags(ifnp->if_name, ifs);
+
+ memset(ifdescr, 0, sizeof(ifdescr));
+ ifr.ifr_data = (caddr_t)&ifdescr;
+ if (ioctl(ifs, SIOCGIFDESCR, &ifr) == 0)
+ description = ifr.ifr_data;
+ else
+ description = "";
+
+ if (vnetid == -1)
+ strlcpy(vnetid_str, "-", sizeof(vnetid_str));
+ else
+ snprintf(vnetid_str, sizeof(vnetid_str), "%d", vnetid);
+
+ bridx = bridge_member_search(ifs, ifnp->if_name);
+ if (bridx)
+ bridgename = if_indextoname(bridx, ifix_buf);
+ else
+ bridgename = "-";
+
+ printf(" %-10s %-5s %-7s %-8s %-7s %-8s %s\n", ifnp->if_name,
+ vnetid_str, (flags & IFF_UP) ? "up" : "down",
+ isprefix("vlan", ifnp->if_name) ? "802.1Q" : "802.1ad",
+ parent, bridgename, description);
+ }
+
+ if (wanted_vnetid != -1 && !found_vnetid)
+ printf("%% no VLAN with tag %d configured\n", wanted_vnetid);
+
+ if_freenameindex(ifn_list);
+ close(ifs);
+ return 0;
}
+
+int
+show_vlans(int argc, char **argv)
+{
+ long long vnetid = -1;
+ const char *errstr;
+
+ switch (argc) {
+ case 2:
+ show_vlan(-1);
+ break;
+ case 3:
+ vnetid = strtonum(argv[2], EVL_VLID_NULL,
+ EVL_VLID_MAX, &errstr);
+ if (errstr) {
+ printf("%% VLAN tag %s is %s\n", argv[2], errstr);
+ break;
+ }
+ show_vlan(vnetid);
+ break;
+ }
+ return 0;
+}
blob - 5f9794d6b92a5e5ef101c1b2fc72a8e8fdb75b2d
blob + dfdab5d2d531b2a4f4f76dde6b9e16bcb1d70484
--- nsh.8
+++ nsh.8
.El
.Tg show
.Ic show
-.Op hostname | interface | route | route6 | sadb | arp | ndp | kernel | bgp | ospf\
+.Op hostname | interface | route | route6 | sadb | arp | ndp | vlan | kernel | bgp | ospf\
| ospf6 |eigrp | rip | ldp | ike | ipsec | dvmrp | relay | dhcp | smtp\
| ldap | monitor | version | users | running-config | startup-config |\&? | help
.Pp
sadb Security Association Database
arp ARP table
ndp NDP table
+ vlan 802.1Q/802.1ad VLANs
kernel Kernel statistics
bgp BGP information
ospf OSPF information