Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_tap.c
Show First 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | |||||
* exception of tapdebug, which is accessed unlocked; tapclones is | * exception of tapdebug, which is accessed unlocked; tapclones is | ||||
* static at runtime. | * static at runtime. | ||||
*/ | */ | ||||
static struct mtx tapmtx; | static struct mtx tapmtx; | ||||
static int tapdebug = 0; /* debug flag */ | static int tapdebug = 0; /* debug flag */ | ||||
static int tapuopen = 0; /* allow user open() */ | static int tapuopen = 0; /* allow user open() */ | ||||
static int tapuponopen = 0; /* IFF_UP on open() */ | static int tapuponopen = 0; /* IFF_UP on open() */ | ||||
static int tapdclone = 1; /* enable devfs cloning */ | static int tapdclone = 1; /* enable devfs cloning */ | ||||
static int tapclonereuse = 0; /* reuse closed taps */ | |||||
static SLIST_HEAD(, tap_softc) taphead; /* first device */ | static SLIST_HEAD(, tap_softc) taphead; /* first device */ | ||||
static struct clonedevs *tapclones; | static struct clonedevs *tapclones; | ||||
MALLOC_DECLARE(M_TAP); | MALLOC_DECLARE(M_TAP); | ||||
MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface"); | MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface"); | ||||
SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, ""); | SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, ""); | ||||
SYSCTL_DECL(_net_link); | SYSCTL_DECL(_net_link); | ||||
static SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0, | static SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0, | ||||
"Ethernet tunnel software network interface"); | "Ethernet tunnel software network interface"); | ||||
SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0, | SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0, | ||||
"Allow user to open /dev/tap (based on node permissions)"); | "Allow user to open /dev/tap (based on node permissions)"); | ||||
SYSCTL_INT(_net_link_tap, OID_AUTO, up_on_open, CTLFLAG_RW, &tapuponopen, 0, | SYSCTL_INT(_net_link_tap, OID_AUTO, up_on_open, CTLFLAG_RW, &tapuponopen, 0, | ||||
"Bring interface up when /dev/tap is opened"); | "Bring interface up when /dev/tap is opened"); | ||||
SYSCTL_INT(_net_link_tap, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tapdclone, 0, | SYSCTL_INT(_net_link_tap, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tapdclone, 0, | ||||
"Enably legacy devfs interface creation"); | "Enably legacy devfs interface creation"); | ||||
SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, ""); | SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, ""); | ||||
SYSCTL_INT(_net_link_tap, OID_AUTO, clone_reuse_closed, CTLFLAG_RWTUN, | |||||
&tapclonereuse, 0, "Re-use closed interfaces in devfs cloning"); | |||||
DEV_MODULE(if_tap, tapmodevent, NULL); | DEV_MODULE(if_tap, tapmodevent, NULL); | ||||
static int | static int | ||||
tap_clone_create(struct if_clone *ifc, int unit, caddr_t params) | tap_clone_create(struct if_clone *ifc, int unit, caddr_t params) | ||||
{ | { | ||||
struct cdev *dev; | struct cdev *dev; | ||||
int i; | int i; | ||||
▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* DEVFS handler | * DEVFS handler | ||||
* | * | ||||
* We need to support two kind of devices - tap and vmnet | * We need to support two kind of devices - tap and vmnet | ||||
*/ | */ | ||||
static void | static void | ||||
tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev) | tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev) | ||||
{ | { | ||||
struct tap_softc *tp; | |||||
char devname[SPECNAMELEN + 1]; | char devname[SPECNAMELEN + 1]; | ||||
int i, unit, append_unit; | int i, unit, append_unit; | ||||
int extra; | int extra; | ||||
if (*dev != NULL) | if (*dev != NULL) | ||||
return; | return; | ||||
if (!tapdclone || | if (!tapdclone || | ||||
Show All 13 Lines | tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev) | ||||
} else if (dev_stdclone(name, NULL, tapname, &unit) != 1) { | } else if (dev_stdclone(name, NULL, tapname, &unit) != 1) { | ||||
if (dev_stdclone(name, NULL, vmnetname, &unit) != 1) { | if (dev_stdclone(name, NULL, vmnetname, &unit) != 1) { | ||||
return; | return; | ||||
} else { | } else { | ||||
extra = VMNET_DEV_MASK; | extra = VMNET_DEV_MASK; | ||||
} | } | ||||
} | } | ||||
if (unit == -1 && tapclonereuse) { | |||||
mtx_lock(&tapmtx); | |||||
SLIST_FOREACH(tp, &taphead, tap_next) { | |||||
mtx_lock(&tp->tap_mtx); | |||||
if (!(tp->tap_flags & TAP_OPEN)) { | |||||
dev_ref(tp->tap_dev); | |||||
*dev = tp->tap_dev; | |||||
mtx_unlock(&tp->tap_mtx); | |||||
mtx_unlock(&tapmtx); | |||||
return; | |||||
} | |||||
mtx_unlock(&tp->tap_mtx); | |||||
} | |||||
mtx_unlock(&tapmtx); | |||||
} | |||||
if (unit == -1) | if (unit == -1) | ||||
append_unit = 1; | append_unit = 1; | ||||
CURVNET_SET(CRED_TO_VNET(cred)); | CURVNET_SET(CRED_TO_VNET(cred)); | ||||
/* find any existing device, or allocate new unit number */ | /* find any existing device, or allocate new unit number */ | ||||
i = clone_create(&tapclones, &tap_cdevsw, &unit, dev, extra); | i = clone_create(&tapclones, &tap_cdevsw, &unit, dev, extra); | ||||
if (i) { | if (i) { | ||||
if (append_unit) { | if (append_unit) { | ||||
▲ Show 20 Lines • Show All 736 Lines • Show Last 20 Lines |