Do a kldload() if we get ENXIO trying to open /dev/tun0
Originally submitted by: green
This commit is contained in:
parent
e267a66620
commit
fc3034ca7d
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user