From f3722ef60953dd83ee81e15a3c6c3dc29143afd7 Mon Sep 17 00:00:00 2001 From: Mike Smith Date: Mon, 20 Sep 1999 07:58:08 +0000 Subject: [PATCH] If we don't appear to have a module loaded supporting the interface we're about to operate on, try to load one. Don't complain if the load fails, and always press on regardless (there may not be a module suitable or required). With the renaming of the PCI ethernet driver modules and the addition of appropriate miibus dependancies on those modules that need it, it is now no longer necessary to compile many ethernet drivers into the kernel; they will be loaded on demand the first time they are ifconfig'ed. Inspiration from: mount Reviewed by: obrien --- sbin/ifconfig/ifconfig.c | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index f2ece8fe9e11..00fb30f1a483 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -50,6 +50,8 @@ static const char rcsid[] = #include #include #include +#include +#include #include #include @@ -119,6 +121,7 @@ void status __P((const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl, struct if_msghdr *ifm, struct ifa_msghdr *ifam)); void usage __P((void)); +void ifmaybeload __P((char *name)); typedef void c_func __P((const char *cmd, int arg, int s, const struct afswtch *afp)); c_func setatphase, setatrange; @@ -343,6 +346,9 @@ main(argc, argv) strncpy(name, *argv, sizeof(name)); argc--, argv++; + + /* check and maybe load support for this interface */ + ifmaybeload(name); } /* Check for address family */ @@ -1144,3 +1150,41 @@ xns_getaddr(addr, which) } #endif +void +ifmaybeload(name) + char *name; +{ + struct module_stat mstat; + int fileid, modid; + char ifkind[35], *cp, *dp; + + + /* turn interface and unit into module name */ + strcpy(ifkind, "if_"); + for (cp = name, dp = ifkind + 3; (*cp != 0) && !isdigit(*cp); cp++, dp++) + *dp = *cp; + *dp = 0; + + /* scan files in kernel */ + mstat.version = sizeof(struct module_stat); + for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { + /* scan modules in file */ + for (modid = kldfirstmod(fileid); modid > 0; + modid = modfnext(modid)) { + if (modstat(modid, &mstat) < 0) + continue; + /* strip bus name if present */ + if ((cp = strchr(mstat.name, '/')) != NULL) { + cp++; + } else { + cp = mstat.name; + } + /* already loaded? */ + if (!strcmp(ifkind, cp)) + return; + } + } + + /* not present, we should try to load it */ + kldload(ifkind); +}