From fc3034ca7d6516ccdd952217b34e8a1cc8654650 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Wed, 22 Sep 1999 00:40:47 +0000 Subject: [PATCH] Do a kldload() if we get ENXIO trying to open /dev/tun0 Originally submitted by: green --- usr.sbin/ppp/bundle.c | 29 +++++++++++++++++++++++++++++ usr.sbin/ppp/id.c | 19 ++++++++++++++++++- usr.sbin/ppp/id.h | 3 +++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index 072b5c384618..822f13ce0480 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -45,6 +45,9 @@ #include #include #include +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +#include +#endif #include #include @@ -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 4aaba3714417..79dec7209d3c 100644 --- a/usr.sbin/ppp/id.c +++ b/usr.sbin/ppp/id.c @@ -26,7 +26,7 @@ * $FreeBSD$ */ -#include +#include #include #include @@ -37,6 +37,9 @@ #include #include #include +#if defined(__FreeBSD__) && !defined(NOKLDLOAD) +#include +#endif #include #ifdef __OpenBSD__ #include @@ -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 18b1f44a2991..ddf0d7c2e883 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