summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1999-09-22 00:40:47 +0000
committerbrian <brian@FreeBSD.org>1999-09-22 00:40:47 +0000
commit531472ba31cba86db696789d70af350ac50faa0c (patch)
treec57202a4f821be33d494a67c4a12ed7f73d3a39c /usr.sbin/ppp
parent227027e9978c1e9aada6ef823c687b00c69e6436 (diff)
downloadFreeBSD-src-531472ba31cba86db696789d70af350ac50faa0c.zip
FreeBSD-src-531472ba31cba86db696789d70af350ac50faa0c.tar.gz
Do a kldload() if we get ENXIO trying to open /dev/tun0
Originally submitted by: green
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r--usr.sbin/ppp/bundle.c29
-rw-r--r--usr.sbin/ppp/id.c19
-rw-r--r--usr.sbin/ppp/id.h3
3 files changed, 50 insertions, 1 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 072b5c3..822f13c 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -45,6 +45,9 @@
#include <string.h>
#include <sys/uio.h>
#include <sys/wait.h>
+#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
+#include <sys/linker.h>
+#endif
#include <termios.h>
#include <unistd.h>
@@ -601,6 +604,9 @@ bundle_Create(const char *prefix, int type, const char **argv)
static struct bundle bundle; /* there can be only one */
int enoentcount, err;
const char *ifname;
+#ifdef KLDSYM_LOOKUP
+ int kldtried;
+#endif
#if defined(TUNSIFMODE) || defined(TUNSLMODE)
int iff;
#endif
@@ -612,6 +618,9 @@ bundle_Create(const char *prefix, int type, const char **argv)
err = ENOENT;
enoentcount = 0;
+#ifdef KLDSYM_LOOKUP
+ kldtried = 0;
+#endif
for (bundle.unit = 0; ; bundle.unit++) {
snprintf(bundle.dev.Name, sizeof bundle.dev.Name, "%s%d",
prefix, bundle.unit);
@@ -619,6 +628,26 @@ bundle_Create(const char *prefix, int type, const char **argv)
if (bundle.dev.fd >= 0)
break;
else if (errno == ENXIO) {
+#ifdef KLDSYM_LOOKUP
+ if (bundle.unit == 0 && !kldtried++) {
+ /*
+ * XXX: For some odd reason, FreeBSD (right now) allows if_tun.ko to
+ * load even when the kernel contains the tun device. This lookup
+ * should go away when this is fixed, leaving just the kldload().
+ * Note also that kldsym() finds static symbols...
+ */
+ char devsw[] = "tun_cdevsw";
+ struct kld_sym_lookup ksl = { sizeof ksl, devsw, 0, 0 };
+
+ if (kldsym(0, KLDSYM_LOOKUP, &ksl) == -1) {
+ if (ID0kldload("if_tun") != -1) {
+ bundle.unit--;
+ continue;
+ }
+ log_Printf(LogWARN, "kldload: if_tun: %s\n", strerror(errno));
+ }
+ }
+#endif
err = errno;
break;
} else if (errno == ENOENT) {
diff --git a/usr.sbin/ppp/id.c b/usr.sbin/ppp/id.c
index 4aaba37..79dec72 100644
--- a/usr.sbin/ppp/id.c
+++ b/usr.sbin/ppp/id.c
@@ -26,7 +26,7 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -37,6 +37,9 @@
#include <stdio.h>
#include <string.h>
#include <sysexits.h>
+#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
+#include <sys/linker.h>
+#endif
#include <unistd.h>
#ifdef __OpenBSD__
#include <util.h>
@@ -265,3 +268,17 @@ ID0kill(pid_t pid, int sig)
ID0setuser();
return result;
}
+
+#ifdef KLDSYM_LOOKUP
+int
+ID0kldload(const char *dev)
+{
+ int result;
+
+ ID0set0();
+ result = kldload(dev);
+ log_Printf(LogID0, "%d = kldload(\"%s\")\n", result, dev);
+ ID0setuser();
+ return result;
+}
+#endif
diff --git a/usr.sbin/ppp/id.h b/usr.sbin/ppp/id.h
index 18b1f44..ddf0d7c 100644
--- a/usr.sbin/ppp/id.h
+++ b/usr.sbin/ppp/id.h
@@ -45,3 +45,6 @@ extern void ID0logout(const char *);
extern int ID0bind_un(int, const struct sockaddr_un *);
extern int ID0connect_un(int, const struct sockaddr_un *);
extern int ID0kill(pid_t, int);
+#ifdef KLDSYM_LOOKUP
+extern int ID0kldload(const char *);
+#endif
OpenPOWER on IntegriCloud