Skip site navigation (1)Skip section navigation (2)
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>