summaryrefslogtreecommitdiffstats
path: root/sbin/ifconfig
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1999-09-20 07:58:08 +0000
committermsmith <msmith@FreeBSD.org>1999-09-20 07:58:08 +0000
commit4d16916f800d4c5ee37fb3c93ca6981ad9b33eb3 (patch)
tree5b592961e207d65234082b26dbf3f3e862123282 /sbin/ifconfig
parent965d9c056daf76619c8e96d8984663f84f9d6d32 (diff)
downloadFreeBSD-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')
-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 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);
+}
OpenPOWER on IntegriCloud