diff options
author | msmith <msmith@FreeBSD.org> | 1999-09-20 07:58:08 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 1999-09-20 07:58:08 +0000 |
commit | 4d16916f800d4c5ee37fb3c93ca6981ad9b33eb3 (patch) | |
tree | 5b592961e207d65234082b26dbf3f3e862123282 /sbin/ifconfig/ifconfig.c | |
parent | 965d9c056daf76619c8e96d8984663f84f9d6d32 (diff) | |
download | FreeBSD-src-4d16916f800d4c5ee37fb3c93ca6981ad9b33eb3.zip FreeBSD-src-4d16916f800d4c5ee37fb3c93ca6981ad9b33eb3.tar.gz |
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
Diffstat (limited to 'sbin/ifconfig/ifconfig.c')
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index f2ece8f..00fb30f 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -50,6 +50,8 @@ static const char rcsid[] = #include <sys/socket.h> #include <sys/sysctl.h> #include <sys/time.h> +#include <sys/module.h> +#include <sys/linker.h> #include <net/if.h> #include <net/if_var.h> @@ -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); +} |