summaryrefslogtreecommitdiffstats
path: root/sys/net/if_tap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_tap.c')
-rw-r--r--sys/net/if_tap.c164
1 files changed, 35 insertions, 129 deletions
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
index 82ae3b9..f83243b 100644
--- a/sys/net/if_tap.c
+++ b/sys/net/if_tap.c
@@ -54,8 +54,6 @@
#include <sys/ttycom.h>
#include <sys/uio.h>
#include <sys/vnode.h>
-#include <machine/bus.h> /* XXX: Shouldn't really be required! */
-#include <sys/rman.h>
#include <sys/queue.h>
#include <net/bpf.h>
@@ -71,14 +69,12 @@
#define CDEV_NAME "tap"
-#define CDEV_MAJOR 149
#define TAPDEBUG if (tapdebug) printf
#define TAP "tap"
#define VMNET "vmnet"
#define TAPMAXUNIT 0x7fff
-#define VMNET_DEV_MASK 0x00800000
- /* 0x007f00ff */
+#define VMNET_DEV_MASK CLONE_FLAG0
/* module */
static int tapmodevent(module_t, int, void *);
@@ -108,15 +104,12 @@ static struct cdevsw tap_cdevsw = {
.d_ioctl = tapioctl,
.d_poll = tappoll,
.d_name = CDEV_NAME,
- .d_maj = CDEV_MAJOR,
+ .d_flags = D_PSEUDO,
};
static int tapdebug = 0; /* debug flag */
static SLIST_HEAD(, tap_softc) taphead; /* first device */
-static udev_t tapbasedev = NOUDEV; /* base device */
-static struct rman tapdevunits[2]; /* device units */
-#define tapunits tapdevunits
-#define vmnetunits (tapdevunits + 1)
+static struct clonedevs *tapclones;
MALLOC_DECLARE(M_TAP);
MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface");
@@ -137,63 +130,27 @@ tapmodevent(mod, type, data)
static eventhandler_tag eh_tag = NULL;
struct tap_softc *tp = NULL;
struct ifnet *ifp = NULL;
- int error, s;
+ int s;
switch (type) {
case MOD_LOAD:
- /* initialize resources */
- tapunits->rm_type = RMAN_ARRAY;
- tapunits->rm_descr = "open tap units";
- vmnetunits->rm_type = RMAN_ARRAY;
- vmnetunits->rm_descr = "open vmnet units";
-
- error = rman_init(tapunits);
- if (error != 0)
- goto bail;
-
- error = rman_init(vmnetunits);
- if (error != 0)
- goto bail1;
-
- error = rman_manage_region(tapunits, 0, TAPMAXUNIT);
- if (error != 0)
- goto bail2;
-
- error = rman_manage_region(vmnetunits, 0, TAPMAXUNIT);
- if (error != 0)
- goto bail2;
/* intitialize device */
SLIST_INIT(&taphead);
eh_tag = EVENTHANDLER_REGISTER(dev_clone, tapclone, 0, 1000);
- if (eh_tag == NULL) {
- error = ENOMEM;
- goto bail2;
- }
-
-
+ if (eh_tag == NULL)
+ return (ENOMEM);
return (0);
-bail2:
- rman_fini(vmnetunits);
-bail1:
- rman_fini(tapunits);
-bail:
- return (error);
case MOD_UNLOAD:
SLIST_FOREACH(tp, &taphead, tap_next)
- if (tp->tap_unit != NULL)
+ if (tp->tap_flags & TAP_OPEN)
return (EBUSY);
EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
- error = rman_fini(tapunits);
- KASSERT((error == 0), ("Could not fini tap units"));
- error = rman_fini(vmnetunits);
- KASSERT((error == 0), ("Could not fini vmnet units"));
-
while ((tp = SLIST_FIRST(&taphead)) != NULL) {
SLIST_REMOVE_HEAD(&taphead, tap_next);
@@ -204,18 +161,14 @@ bail:
KASSERT(!(tp->tap_flags & TAP_OPEN),
("%s flags is out of sync", ifp->if_xname));
- /* XXX makedev check? nah.. not right now :) */
-
+ destroy_dev(tp->tap_dev);
s = splimp();
ether_ifdetach(ifp);
splx(s);
free(tp, M_TAP);
}
-
- if (tapbasedev != NOUDEV)
- destroy_dev(udev2dev(tapbasedev, 0));
-
+ clone_cleanup(&tapclones);
break;
@@ -239,65 +192,35 @@ tapclone(arg, name, namelen, dev)
int namelen;
dev_t *dev;
{
- int unit, minor = 0 /* XXX avoid warning */ , error;
+ u_int extra;
+ int i, unit;
char *device_name = name;
- struct resource *r = NULL;
if (*dev != NODEV)
return;
- if (strcmp(device_name, TAP) == 0) {
- /* get first free tap unit */
- r = rman_reserve_resource(tapunits, 0, TAPMAXUNIT, 1,
- RF_ALLOCATED | RF_ACTIVE, NULL);
- unit = rman_get_start(r);
- minor = unit2minor(unit);
- }
- else if (strcmp(device_name, VMNET) == 0) {
- /* get first free vmnet unit */
- r = rman_reserve_resource(vmnetunits, 0, TAPMAXUNIT, 1,
- RF_ALLOCATED | RF_ACTIVE, NULL);
- unit = rman_get_start(r);
- minor = unit2minor(unit) | VMNET_DEV_MASK;
+ device_name = TAP;
+ extra = 0;
+ if (strcmp(name, TAP) == 0) {
+ unit = -1;
+ } else if (strcmp(name, VMNET) == 0) {
+ device_name = VMNET;
+ extra = VMNET_DEV_MASK;
+ unit = -1;
+ } else if (dev_stdclone(name, NULL, device_name, &unit) != 1) {
+ device_name = VMNET;
+ extra = VMNET_DEV_MASK;
+ if (dev_stdclone(name, NULL, device_name, &unit) != 1)
+ return;
}
- if (r != NULL) { /* need cloning */
- TAPDEBUG("%s%d is available. minor = %#x\n",
- device_name, unit, minor);
-
- error = rman_release_resource(r);
- KASSERT((error == 0), ("Could not release tap/vmnet unit"));
-
- /* check if device for the unit has been created */
- *dev = makedev(CDEV_MAJOR, minor);
- if ((*dev)->si_flags & SI_NAMED) {
- TAPDEBUG("%s%d device exists. minor = %#x\n",
- device_name, unit, minor);
- return; /* device has been created */
- }
- } else { /* try to match name/unit, first try tap then vmnet */
- device_name = TAP;
- if (dev_stdclone(name, NULL, device_name, &unit) != 1) {
- device_name = VMNET;
-
- if (dev_stdclone(name, NULL, device_name, &unit) != 1)
- return;
-
- minor = unit2minor(unit) | VMNET_DEV_MASK;
- } else
- minor = unit2minor(unit);
- }
-
- TAPDEBUG("make_dev(%s%d). minor = %#x\n", device_name, unit, minor);
-
- *dev = make_dev(&tap_cdevsw, minor, UID_ROOT, GID_WHEEL, 0600, "%s%d",
- device_name, unit);
-
- if (tapbasedev == NOUDEV)
- tapbasedev = (*dev)->si_udev;
- else {
- (*dev)->si_flags |= SI_CHEAPCLONE;
- dev_depends(udev2dev(tapbasedev, 0), *dev);
+ /* find any existing device, or allocate new unit number */
+ i = clone_create(&tapclones, &tap_cdevsw, &unit, dev, extra);
+ if (i) {
+ *dev = make_dev(&tap_cdevsw, unit2minor(unit) | extra,
+ UID_ROOT, GID_WHEEL, 0600, "%s%d", device_name, unit);
+ if (*dev != NULL)
+ (*dev)->si_flags |= SI_CHEAPCLONE;
}
} /* tapclone */
@@ -317,6 +240,8 @@ tapcreate(dev)
int unit, s;
char *name = NULL;
+ dev->si_flags &= ~SI_CHEAPCLONE;
+
/* allocate driver storage and create device */
MALLOC(tp, struct tap_softc *, sizeof(*tp), M_TAP, M_WAITOK | M_ZERO);
SLIST_INSERT_HEAD(&taphead, tp, tap_next);
@@ -354,6 +279,7 @@ tapcreate(dev)
ifp->if_snd.ifq_maxlen = ifqmaxlen;
dev->si_drv1 = tp;
+ tp->tap_dev = dev;
s = splimp();
ether_ifattach(ifp, tp->arpcom.ac_enaddr);
@@ -380,24 +306,12 @@ tapopen(dev, flag, mode, td)
{
struct tap_softc *tp = NULL;
int unit, error;
- struct resource *r = NULL;
if ((error = suser(td)) != 0)
return (error);
unit = dev2unit(dev) & TAPMAXUNIT;
- if (minor(dev) & VMNET_DEV_MASK)
- r = rman_reserve_resource(vmnetunits, unit, unit, 1,
- RF_ALLOCATED | RF_ACTIVE, NULL);
- else
- r = rman_reserve_resource(tapunits, unit, unit, 1,
- RF_ALLOCATED | RF_ACTIVE, NULL);
-
- if (r == NULL)
- return (EBUSY);
-
- dev->si_flags &= ~SI_CHEAPCLONE;
tp = dev->si_drv1;
if (tp == NULL) {
@@ -410,7 +324,6 @@ tapopen(dev, flag, mode, td)
bcopy(tp->arpcom.ac_enaddr, tp->ether_addr, sizeof(tp->ether_addr));
- tp->tap_unit = r;
tp->tap_pid = td->td_proc->p_pid;
tp->tap_flags |= TAP_OPEN;
@@ -433,12 +346,9 @@ tapclose(dev, foo, bar, td)
int bar;
struct thread *td;
{
- int s, error;
struct tap_softc *tp = dev->si_drv1;
struct ifnet *ifp = &tp->tap_if;
-
- KASSERT((tp->tap_unit != NULL),
- ("%s is not open", ifp->if_xname));
+ int s;
/* junk all pending output */
IF_DRAIN(&ifp->if_snd);
@@ -479,10 +389,6 @@ tapclose(dev, foo, bar, td)
tp->tap_flags &= ~TAP_OPEN;
tp->tap_pid = 0;
- error = rman_release_resource(tp->tap_unit);
- KASSERT((error == 0),
- ("%s could not release unit", ifp->if_xname));
- tp->tap_unit = NULL;
TAPDEBUG("%s is closed. minor = %#x\n",
ifp->if_xname, minor(dev));
OpenPOWER on IntegriCloud