Date: Fri, 31 Aug 2001 08:56:29 -0700 From: Maksim Yevmenkin <myevmenk@digisle.net> To: Brooks Davis <brooks@one-eyed-alien.net>, freebsd-current@freebsd.org, freebsd-net@freebsd.org, Vladimir Silyaev <vsilyaev@mindspring.com>, Nick Sayer <nsayer@quack.kfu.com> Subject: PATCH: if_tap device cloning (final) Message-ID: <3B8FB3AD.4A3F20D1@digisle.net> References: <3B8EB490.6875087F@digisle.net> <20010830151026.B18097@Odin.AC.HMC.Edu> <3B8EBC8A.43DFFCD7@digisle.net> <20010830154127.A22437@Odin.AC.HMC.Edu> <3B8ECAA0.2A41AE04@digisle.net> <20010830165150.B27635@Odin.AC.HMC.Edu> <3B8EE1F8.3426B811@digisle.net> <20010830182256.A10150@Odin.AC.HMC.Edu>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------A09F7670A8BACD9104B3E55E Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hackers, Attached some patches that implements device cloning (with devfs(5) support) for tap(4). The implementation is based on resource manager (see tun(4) and gif(4)). Brooks Davis (brooks@one-eyed-alien.net) took a quick look at the patch and seems has no objection. Please review, test and if there is no objection Brooks Davis will commit it. If there are any problems, please let me know. thanks, max p.s. i'm not on freebsd-net list, so please reply directly p.p.s. Brooks Davis wrote: [...] > Looks good. If could post a copy to freebsd-net and give it another > 24hrs or so for other responses, I'll commit it if nothing else comes > up. --------------A09F7670A8BACD9104B3E55E Content-Type: text/plain; charset=us-ascii; name="if_tap.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="if_tap.diff" diff -ru /usr/src/share/man/man4/tap.4 ./src/share/man/man4/tap.4 --- /usr/src/share/man/man4/tap.4 Thu Aug 30 14:23:44 2001 +++ ./src/share/man/man4/tap.4 Thu Aug 30 15:14:40 2001 @@ -1,4 +1,4 @@ -.\" $FreeBSD: src/share/man/man4/tap.4,v 1.8 2001/08/07 15:48:39 ru Exp $ +.\" $FreeBSD: src/share/man/man4/tap.4,v 1.7 2001/05/01 09:15:13 schweikh Exp $ .\" Based on PR#2411 .\" .Dd July 9, 2000 @@ -36,11 +36,50 @@ interface. .Pp The network interfaces are named -.Sy tap Ns Ar 0 , -.Sy tap Ns Ar 1 , -etc, as many as were made by -.Xr MAKEDEV 8 . -Each one supports the usual Ethernet network-interface +.Dq Li tap0 , +.Dq Li tap1 , +etc., one for each control device that has been opened. +These Ethernet network interfaces persist until +.Pa if_tap.ko +module is unloaded (if +.Nm +is built into your kernel, the network interfaces can not be removed). +.Pp +On older systems without +.Xr devfs 5 +support, +.Xr MAKEDEV 8 +should be used to create the initial control devices and the task +of locating an unused device is left up to the opener (a +.Nm +device is usually obtained by attempting to open +.Pa /dev/tap0 , +and if that fails +.Pa /dev/tap1 +etc., until an +.Va errno +of +.Er EBUSY +is not received). +.Pp +On systems with +.Xr devfs 5 +support, +.Nm +permits opens on the special control device +.Pa /dev/tap . +When this device is opened, +.Nm +will return a handle for the lowest unused +.Nm +device (use +.Xr devname 3 +to determine which). +Control devices (once successfully opened) persist until +.Pa if_tap.ko +is unloaded in the same way that network interfaces persist (see above). +.Pp +Each interface supports the usual Ethernet network interface .Xr ioctl 2 Ns s , such as .Dv SIOCSIFADDR @@ -56,7 +95,7 @@ there); writing an Ethernet frame to the control device generates an input frame on the network interface, as if the -(non-existent) +.Pq non-existent hardware had just received it. .Pp The Ethernet tunnel device, normally @@ -91,15 +130,14 @@ .Fn write . Writes will not block; if the frame cannot be accepted for a transient reason -(e.g., no buffer space available), +.Pq e.g., no buffer space available , it is silently dropped; if the reason is not transient -(e.g., frame too large), +.Pq e.g., frame too large , an error is returned. The following .Xr ioctl 2 calls are supported -(defined in -.Aq Pa net/if_tap.h ) : +.Pq defined in Aq Pa net/if_tap.h Ns : .Bl -tag -width VMIO_SIOCSETMACADDR .It Dv TAPSDEBUG The argument should be a pointer to an @@ -115,7 +153,7 @@ Turn non-blocking I/O for reads off or on, according as the argument .Va int Ns 's value is or isn't zero -(Writes are always nonblocking). +.Pq Writes are always nonblocking . .It Dv FIOASYNC Turn asynchronous I/O for reads (i.e., generation of @@ -172,8 +210,7 @@ .Dq remote side. This command is used by VMware port and expected to be executed on a descriptor, associated with control device -(usually -.Pa /dev/vmnet Ns Sy N ) . +.Pq usually Pa /dev/vmnet Ns Sy N . .El .Pp The control device also supports @@ -199,7 +236,7 @@ and .Nm vmnet devices. VMnet minor numbers begin at -.Va 0x10000 +.Va 0x800000 + .Va N . Where diff -ru /usr/src/sys/net/if_tap.c ./src/sys/net/if_tap.c --- /usr/src/sys/net/if_tap.c Mon Mar 26 04:41:17 2001 +++ ./src/sys/net/if_tap.c Thu Aug 30 17:51:00 2001 @@ -54,6 +54,9 @@ #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> #include <net/ethernet.h> @@ -73,7 +76,9 @@ #define TAP "tap" #define VMNET "vmnet" -#define VMNET_DEV_MASK 0x00010000 +#define TAPMAXUNIT 0x7fff +#define VMNET_DEV_MASK 0x00800000 + /* 0x007f00ff */ /* module */ static int tapmodevent __P((module_t, int, void *)); @@ -111,9 +116,12 @@ /* flags */ 0, }; -static int taprefcnt = 0; /* module ref. counter */ -static int taplastunit = -1; /* max. open unit number */ -static int tapdebug = 0; /* debug flag */ +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) MALLOC_DECLARE(M_TAP); MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface"); @@ -131,61 +139,100 @@ int type; void *data; { - static int attached = 0; - static eventhandler_tag eh_tag = NULL; + static eventhandler_tag eh_tag = NULL; + struct tap_softc *tp = NULL; + struct ifnet *ifp = NULL; + int error, s; switch (type) { case MOD_LOAD: - if (attached) - return (EEXIST); + /* 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); - cdevsw_add(&tap_cdevsw); - attached = 1; - break; + if (eh_tag == NULL) { + error = ENOMEM; + goto bail2; + } - case MOD_UNLOAD: { - int unit; + if (!devfs_present) { + error = cdevsw_add(&tap_cdevsw); + if (error != 0) { + EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); + goto bail2; + } + } + + return (0); +bail2: + rman_fini(vmnetunits); +bail1: + rman_fini(tapunits); +bail: + return (error); - if (taprefcnt > 0) - return (EBUSY); + case MOD_UNLOAD: + SLIST_FOREACH(tp, &taphead, tap_next) + if (tp->tap_unit != NULL) + return (EBUSY); EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); - cdevsw_remove(&tap_cdevsw); - unit = 0; - while (unit <= taplastunit) { - int s; - struct ifnet *ifp = NULL; + 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); + + ifp = &tp->tap_if; + + TAPDEBUG("detaching %s%d\n", ifp->if_name,ifp->if_unit); + + KASSERT(!(tp->tap_flags & TAP_OPEN), + ("%s%d flags is out of sync", ifp->if_name, + ifp->if_unit)); + + /* XXX makedev check? nah.. not right now :) */ s = splimp(); - TAILQ_FOREACH(ifp, &ifnet, if_link) - if ((strcmp(ifp->if_name, TAP) == 0) || - (strcmp(ifp->if_name, VMNET) == 0)) - if (ifp->if_unit == unit) - break; + ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); splx(s); - if (ifp != NULL) { - struct tap_softc *tp = ifp->if_softc; - - TAPDEBUG("detaching %s%d. minor = %#x, " \ - "taplastunit = %d\n", - ifp->if_name, unit, minor(tp->tap_dev), - taplastunit); - - s = splimp(); - ether_ifdetach(ifp, 1); - splx(s); - destroy_dev(tp->tap_dev); - FREE(tp, M_TAP); - } - else - unit ++; + FREE(tp, M_TAP); } - attached = 0; - } break; + if (tapbasedev != NOUDEV) + destroy_dev(udev2dev(tapbasedev, 0)); + + if (!devfs_present) + cdevsw_remove(&tap_cdevsw); + + break; default: return (EOPNOTSUPP); @@ -207,26 +254,66 @@ int namelen; dev_t *dev; { - int unit, minor; - char *device_name = NULL; + int unit, minor = 0 /* XXX avoid warning */ , error; + char *device_name = name; + struct resource *r = NULL; if (*dev != NODEV) return; - device_name = TAP; - if (dev_stdclone(name, NULL, device_name, &unit) != 1) { - device_name = VMNET; + 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; + } + + 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; + if (dev_stdclone(name, NULL, device_name, &unit) != 1) + return; - minor = unit2minor(unit | VMNET_DEV_MASK); + minor = unit2minor(unit) | VMNET_DEV_MASK; + } else + minor = unit2minor(unit); } - 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); + } } /* tapclone */ @@ -247,21 +334,22 @@ /* 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); + + unit = dev2unit(dev) & TAPMAXUNIT; /* select device: tap or vmnet */ if (minor(dev) & VMNET_DEV_MASK) { name = VMNET; - unit = dev2unit(dev) & 0xff; tp->tap_flags |= TAP_VMNET; - } - else { + } else name = TAP; - unit = dev2unit(dev); - } - tp->tap_dev = make_dev(&tap_cdevsw, minor(dev), UID_ROOT, GID_WHEEL, + TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, minor(dev)); + + if (!(dev->si_flags & SI_NAMED)) + dev = make_dev(&tap_cdevsw, minor(dev), UID_ROOT, GID_WHEEL, 0600, "%s%d", name, unit); - tp->tap_dev->si_drv1 = dev->si_drv1 = tp; /* generate fake MAC address: 00 bd xx xx xx unit_no */ macaddr_hi = htons(0x00bd); @@ -272,11 +360,7 @@ /* fill the rest and attach interface */ ifp = &tp->tap_if; ifp->if_softc = tp; - ifp->if_unit = unit; - if (unit > taplastunit) - taplastunit = unit; - ifp->if_name = name; ifp->if_init = tapifinit; ifp->if_output = ether_output; @@ -286,14 +370,16 @@ ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); ifp->if_snd.ifq_maxlen = ifqmaxlen; + dev->si_drv1 = tp; + s = splimp(); - ether_ifattach(ifp, 1); + ether_ifattach(ifp, ETHER_BPF_SUPPORTED); splx(s); tp->tap_flags |= TAP_INITED; - TAPDEBUG("interface %s%d created. minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + TAPDEBUG("interface %s%d is created. minor = %#x\n", + ifp->if_name, ifp->if_unit, minor(dev)); } /* tapcreate */ @@ -310,29 +396,43 @@ struct proc *p; { struct tap_softc *tp = NULL; - int error; + int unit, error; + struct resource *r = NULL; if ((error = suser(p)) != 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) { tapcreate(dev); tp = dev->si_drv1; } - if (tp->tap_flags & TAP_OPEN) - return (EBUSY); + KASSERT(!(tp->tap_flags & TAP_OPEN), + ("%s%d flags is out of sync", tp->tap_if.if_name, unit)); bcopy(tp->arpcom.ac_enaddr, tp->ether_addr, sizeof(tp->ether_addr)); + tp->tap_unit = r; tp->tap_pid = p->p_pid; tp->tap_flags |= TAP_OPEN; - taprefcnt ++; - TAPDEBUG("%s%d is open. minor = %#x, refcnt = %d, taplastunit = %d\n", - tp->tap_if.if_name, tp->tap_if.if_unit, - minor(tp->tap_dev), taprefcnt, taplastunit); + TAPDEBUG("%s%d is open. minor = %#x\n", + tp->tap_if.if_name, unit, minor(dev)); return (0); } /* tapopen */ @@ -350,20 +450,15 @@ int bar; struct proc *p; { - int s; + int s, error; struct tap_softc *tp = dev->si_drv1; struct ifnet *ifp = &tp->tap_if; - struct mbuf *m = NULL; - /* junk all pending output */ + KASSERT((tp->tap_unit != NULL), + ("%s%d is not open", ifp->if_name, ifp->if_unit)); - s = splimp(); - do { - IF_DEQUEUE(&ifp->if_snd, m); - if (m != NULL) - m_freem(m); - } while (m != NULL); - splx(s); + /* junk all pending output */ + IF_DRAIN(&ifp->if_snd); /* * do not bring the interface down, and do not anything with @@ -401,18 +496,13 @@ tp->tap_flags &= ~TAP_OPEN; tp->tap_pid = 0; + error = rman_release_resource(tp->tap_unit); + KASSERT((error == 0), + ("%s%d could not release unit", ifp->if_name, ifp->if_unit)); + tp->tap_unit = NULL; - taprefcnt --; - if (taprefcnt < 0) { - taprefcnt = 0; - printf("%s%d minor = %#x, refcnt = %d is out of sync. " \ - "set refcnt to 0\n", ifp->if_name, ifp->if_unit, - minor(tp->tap_dev), taprefcnt); - } - - TAPDEBUG("%s%d is closed. minor = %#x, refcnt = %d, taplastunit = %d\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev), - taprefcnt, taplastunit); + TAPDEBUG("%s%d is closed. minor = %#x\n", + ifp->if_name, ifp->if_unit, minor(dev)); return (0); } /* tapclose */ @@ -430,8 +520,7 @@ struct tap_softc *tp = (struct tap_softc *)xtp; struct ifnet *ifp = &tp->tap_if; - TAPDEBUG("initializing %s%d, minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + TAPDEBUG("initializing %s%d\n", ifp->if_name, ifp->if_unit); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -468,7 +557,7 @@ case SIOCSIFFLAGS: /* XXX -- just like vmnet does */ case SIOCADDMULTI: case SIOCDELMULTI: - break; + break; case SIOCGIFSTATUS: s = splimp(); @@ -479,7 +568,7 @@ sizeof(ifs->ascii) - dummy, "\tOpened by PID %d\n", tp->tap_pid); splx(s); - break; + break; default: return (EINVAL); @@ -501,8 +590,7 @@ struct tap_softc *tp = ifp->if_softc; int s; - TAPDEBUG("%s%d starting, minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + TAPDEBUG("%s%d starting\n", ifp->if_name, ifp->if_unit); /* * do not junk pending output if we are in VMnet mode. @@ -513,9 +601,8 @@ ((tp->tap_flags & TAP_READY) != TAP_READY)) { struct mbuf *m = NULL; - TAPDEBUG("%s%d not ready. minor = %#x, tap_flags = 0x%x\n", - ifp->if_name, ifp->if_unit, - minor(tp->tap_dev), tp->tap_flags); + TAPDEBUG("%s%d not ready, tap_flags = 0x%x\n", ifp->if_name, + ifp->if_unit, tp->tap_flags); s = splimp(); do { @@ -567,6 +654,7 @@ struct ifnet *ifp = &tp->tap_if; struct tapinfo *tapp = NULL; int s; + short f; switch (cmd) { case TAPSIFINFO: @@ -576,25 +664,25 @@ ifp->if_type = tapp->type; ifp->if_baudrate = tapp->baudrate; splx(s); - break; + break; case TAPGIFINFO: tapp = (struct tapinfo *)data; tapp->mtu = ifp->if_mtu; tapp->type = ifp->if_type; tapp->baudrate = ifp->if_baudrate; - break; + break; case TAPSDEBUG: tapdebug = *(int *)data; - break; + break; case TAPGDEBUG: *(int *)data = tapdebug; - break; + break; case FIONBIO: - break; + break; case FIOASYNC: s = splimp(); @@ -603,7 +691,7 @@ else tp->tap_flags &= ~TAP_ASYNC; splx(s); - break; + break; case FIONREAD: s = splimp(); @@ -612,11 +700,10 @@ for(*(int *)data = 0;mb != NULL;mb = mb->m_next) *(int *)data += mb->m_len; - } - else + } else *(int *)data = 0; splx(s); - break; + break; case FIOSETOWN: return (fsetown(*(int *)data, &tp->tap_sigio)); @@ -638,11 +725,10 @@ case SIOCGIFFLAGS: /* get ifnet flags */ bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags)); - break; - - case VMIO_SIOCSIFFLAGS: { /* VMware/VMnet SIOCSIFFLAGS */ - short f = *(short *)data; + break; + case VMIO_SIOCSIFFLAGS: /* VMware/VMnet SIOCSIFFLAGS */ + f = *(short *)data; f &= 0x0fff; f &= ~IFF_CANTCHANGE; f |= IFF_UP; @@ -650,16 +736,16 @@ s = splimp(); ifp->if_flags = f | (ifp->if_flags & IFF_CANTCHANGE); splx(s); - } break; + break; case OSIOCGIFADDR: /* get MAC address of the remote side */ case SIOCGIFADDR: bcopy(tp->ether_addr, data, sizeof(tp->ether_addr)); - break; + break; case SIOCSIFADDR: /* set MAC address of the remote side */ bcopy(data, tp->ether_addr, sizeof(tp->ether_addr)); - break; + break; default: return (ENOTTY); @@ -685,13 +771,12 @@ struct mbuf *m = NULL, *m0 = NULL; int error = 0, len, s; - TAPDEBUG("%s%d reading, minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + TAPDEBUG("%s%d reading, minor = %#x\n", + ifp->if_name, ifp->if_unit, minor(dev)); if ((tp->tap_flags & TAP_READY) != TAP_READY) { TAPDEBUG("%s%d not ready. minor = %#x, tap_flags = 0x%x\n", - ifp->if_name, ifp->if_unit, - minor(tp->tap_dev), tp->tap_flags); + ifp->if_name, ifp->if_unit, minor(dev), tp->tap_flags); return (EHOSTDOWN); } @@ -731,8 +816,8 @@ } if (m0 != NULL) { - TAPDEBUG("%s%d dropping mbuf, minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + TAPDEBUG("%s%d dropping mbuf, minor = %#x\n", ifp->if_name, + ifp->if_unit, minor(dev)); m_freem(m0); } @@ -757,16 +842,15 @@ struct ether_header *eh = NULL; int error = 0, tlen, mlen; - TAPDEBUG("%s%d writting, minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + TAPDEBUG("%s%d writting, minor = %#x\n", + ifp->if_name, ifp->if_unit, minor(dev)); if (uio->uio_resid == 0) return (0); if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) { TAPDEBUG("%s%d invalid packet len = %d, minor = %#x\n", - ifp->if_name, ifp->if_unit, - uio->uio_resid, minor(tp->tap_dev)); + ifp->if_name, ifp->if_unit, uio->uio_resid, minor(dev)); return (EIO); } @@ -836,21 +920,20 @@ struct ifnet *ifp = &tp->tap_if; int s, revents = 0; - TAPDEBUG("%s%d polling, minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + TAPDEBUG("%s%d polling, minor = %#x\n", + ifp->if_name, ifp->if_unit, minor(dev)); s = splimp(); if (events & (POLLIN | POLLRDNORM)) { if (ifp->if_snd.ifq_len > 0) { TAPDEBUG("%s%d have data in queue. len = %d, " \ "minor = %#x\n", ifp->if_name, ifp->if_unit, - ifp->if_snd.ifq_len, minor(tp->tap_dev)); + ifp->if_snd.ifq_len, minor(dev)); revents |= (events & (POLLIN | POLLRDNORM)); - } - else { + } else { TAPDEBUG("%s%d waiting for data, minor = %#x\n", - ifp->if_name, ifp->if_unit, minor(tp->tap_dev)); + ifp->if_name, ifp->if_unit, minor(dev)); selrecord(p, &tp->tap_rsel); } diff -ru /usr/src/sys/net/if_tapvar.h ./src/sys/net/if_tapvar.h --- /usr/src/sys/net/if_tapvar.h Tue Jul 25 16:50:30 2000 +++ ./src/sys/net/if_tapvar.h Thu Aug 30 16:06:21 2001 @@ -44,7 +44,7 @@ struct tap_softc { struct arpcom arpcom; /* ethernet common data */ #define tap_if arpcom.ac_if - dev_t tap_dev; /* device */ + struct resource *tap_unit; /* unit */ u_short tap_flags; /* misc flags */ #define TAP_OPEN (1 << 0) @@ -59,6 +59,8 @@ pid_t tap_pid; /* PID of process to open */ struct sigio *tap_sigio; /* information for async I/O */ struct selinfo tap_rsel; /* read select */ + + SLIST_ENTRY(tap_softc) tap_next; /* next device in chain */ }; #endif /* !_NET_IF_TAPVAR_H_ */ --------------A09F7670A8BACD9104B3E55E-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3B8FB3AD.4A3F20D1>