aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorMike Smith <msmith@FreeBSD.org>1999-09-20 07:58:08 +0000
committerMike Smith <msmith@FreeBSD.org>1999-09-20 07:58:08 +0000
commitf3722ef60953dd83ee81e15a3c6c3dc29143afd7 (patch)
treee7137387cf32cca8b0d83a0ec952473979be49cf /sbin
parent24514292fa6e66d4ccd79de128f8bbb41cc9664e (diff)
downloadsrc-f3722ef60953dd83ee81e15a3c6c3dc29143afd7.tar.gz
src-f3722ef60953dd83ee81e15a3c6c3dc29143afd7.zip
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
Notes
Notes: svn path=/head/; revision=51452
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ifconfig/ifconfig.c44
1 files changed, 44 insertions, 0 deletions
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 <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);
+}