On Tue, Nov 22, 2022 at 08:09:11AM -0700, Theo de Raadt wrote: > Florian Obser <flor...@openbsd.org> wrote: > > > On 2022-11-22 18:06 +10, David Gwynne <da...@gwynne.id.au> wrote: > > > > > > There are a few things to keep in mind if we're going to use lladdrs like > > > this. > > > > > > vlan interfaces start with their lladdr as 00:00:00:00:00:00 and then > > > assume the lladdr of the parent interface when that is configured. > > > > > > Clonable devices (eg, egre, vport, aggr, etc) tend to generate random > > > lladdrs when they're created. If you want a consistent lladdr for > > > these you configure that in /etc/hostname.vportX or whatever you're > > > using. > > > > ifconfig(8) already knows about these (see -C option). Which made me > > think, it might be easier to just ask ifconfig(8). > > > > $ ifconfig -Q 00:80:41:7b:f3:c3 > > vio0 > > > > Would that be helpful? > > I'm unsure about the rest of your proposal, where MAC works in place if > the IF argument. Let's say we do this in ifcconfig. Do we do it in route? > Or ten other commands? I think that is the wrong way to go. > > But this first idea is valid. We've now seen 3 monster functions trying to > do this task of convering MAC to IF in shell. Here's code to do it in > ifconfig. > > I've done it as -M
Better than [Q]uery. > > It fails if the same MAC is on multiple interfaces. Go back to using > hostname.if# files, you heathen. This reads like a viable approach, much cleaner than the netstart globbing attempts. Using ifconfig -M, I can give the shell bits a try later this week. Nits inline. > > Index: ifconfig.8 > =================================================================== > RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v > retrieving revision 1.385 > diff -u -p -u -r1.385 ifconfig.8 > --- ifconfig.8 26 Oct 2022 17:06:31 -0000 1.385 > +++ ifconfig.8 22 Nov 2022 15:04:09 -0000 > @@ -40,6 +40,7 @@ > .Sh SYNOPSIS > .Nm ifconfig > .Op Fl AaC > +.Op Fl M Ar lladdr > .Op Ar interface > .Op Ar address_family > .Oo > @@ -88,6 +89,11 @@ This is the default, if no parameters ar > Print the names of all network pseudo-devices that > can be created dynamically at runtime using > .Nm Cm create . > +.It Fl M Ar lladdr > +Scan the interface list for the MAC address > +.Ar lladdr > +and print the name of that interface. > +If the MAC address is found on multiple interfaces, print nothing. > .It Ar interface > The > .Ar interface > Index: ifconfig.c > =================================================================== > RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v > retrieving revision 1.457 > diff -u -p -u -r1.457 ifconfig.c > --- ifconfig.c 26 Oct 2022 17:06:31 -0000 1.457 > +++ ifconfig.c 22 Nov 2022 15:02:20 -0000 > @@ -368,6 +368,8 @@ void wg_status(int); > void setignore(const char *, int); > #endif > > +void findmac(char *); > + > /* > * Media stuff. Whenever a media command is first performed, the > * currently select media is grabbed for this interface. If `media' > @@ -759,6 +761,7 @@ main(int argc, char *argv[]) > int create = 0; > int Cflag = 0; > int gflag = 0; > + int Mflag = 0; > int found_rulefile = 0; > int i; > > @@ -795,6 +798,12 @@ main(int argc, char *argv[]) > Cflag = 1; > nomore = 1; > break; > + case 'M': > + if (argv[1] == NULL) > + usage(); > + findmac(argv[1]); > + exit(1); Above main() already uses return, no need for exit here, I think: return findmac(argv[1]); > + break; > default: > usage(); > break; > @@ -6614,7 +6623,7 @@ __dead void > usage(void) > { > fprintf(stderr, > - "usage: ifconfig [-AaC] [interface] [address_family] " > + "usage: ifconfig [-AaC] [-M lladdr] [interface] [address_family] " > "[address [dest_address]]\n" > "\t\t[parameters]\n"); > exit(1); > @@ -6782,3 +6791,30 @@ setignore(const char *id, int param) > /* just digest the command */ > } > #endif > + > +void > +findmac(char *mac) > +{ > + struct ifaddrs *ifap, *ifa; > + char *ifnam = NULL; Both *mac and *ifnam can be const. > + > + if (getifaddrs(&ifap) != 0) > + err(1, "getifaddrs"); > + > + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { > + struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr; > + > + if (sdl != NULL && sdl->sdl_alen && > + (sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_CARP)) { > + if (strcmp(ether_ntoa((struct ether_addr *)LLADDR(sdl)), > + mac) == 0) { > + if (ifnam) /* same MAC on multiple ifp */ > + exit(1); > + ifnam = ifa->ifa_name; > + } > + } > + } > + if (ifnam) > + printf("%s\n", ifnam); > + exit(0); And these exit()s can be return to fold the call as above. > +} >