Date: Mon, 22 Sep 2008 18:49:14 -0700 From: "Maksim Yevmenkin" <maksim.yevmenkin@gmail.com> To: "Maxim Sobolev" <sobomax@freebsd.org> Cc: Alexey Shuvaev <shuvaev@physik.uni-wuerzburg.de>, Kostik Belousov <kostikbel@gmail.com>, freebsd-current@freebsd.org, Ed Schouten <ed@80386.nl> Subject: Re: Interface auto-cloning bug or feature? Message-ID: <bb4a86c70809221849v640e66awa52a2b5d944ca0dc@mail.gmail.com> In-Reply-To: <48D8196E.7020005@FreeBSD.org> References: <48D2F942.4070801@FreeBSD.org> <20080919084201.GD44330@wep4035.physik.uni-wuerzburg.de> <48D38DFF.8000803@FreeBSD.org> <20080919203310.GA34131@localhost.my.domain> <bb4a86c70809191543y7f3d38ex73c48186dfd163c5@mail.gmail.com> <bb4a86c70809191551y774c233g5e664c431be62a50@mail.gmail.com> <48D8196E.7020005@FreeBSD.org>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
[...]
>>> ok, how about attached patch. i put it together *very* quickly and
>>> only gave it a light testing. its for tap(4), because i could compile
>>> it as a module and tun(4) is compiled into kernel by default, but the
>>> idea should identical for tun(4). should be even simpler for tun(4)
>>> because it does not have to deal with 2 kind of devices (i.e. tap and
>>> vmnet). give it a try, and see if it works. please try both cloning
>>> paths, i.e.
>>>
>>> 1) cat /dev/tap (/dev/vmnet) with and/or without unit number
>>>
>>> and
>>>
>>> 2) ifconfig tapX (vmnetX) create/destroy
>>>
>>> in the mean time i will prepare something similar for tun(4).
>>
>> attached is similar patch for tun(4). i only made sure it compiles :)
>> rebuilding kernel now...
attached is a slightly better patch for tap(4). the idea is to use
extra ALLOCATED flag that prevents the race Kostik pointed out. could
you please give it a try? any review comments are greatly appreciated.
if this is acceptable, i will prepare something similar for tun(4)
thanks,
max
[-- Attachment #2 --]
--- if_tap.c.orig 2008-09-08 17:20:57.000000000 -0700
+++ if_tap.c 2008-09-22 18:36:16.000000000 -0700
@@ -94,6 +94,7 @@
static int tapifioctl(struct ifnet *, u_long, caddr_t);
static void tapifinit(void *);
+static int tap_clone_lookup(struct cdev **, u_short);
static int tap_clone_create(struct if_clone *, int, caddr_t);
static void tap_clone_destroy(struct ifnet *);
static int vmnet_clone_create(struct if_clone *, int, caddr_t);
@@ -176,6 +177,30 @@
DEV_MODULE(if_tap, tapmodevent, NULL);
static int
+tap_clone_lookup(struct cdev **dev, u_short extra)
+{
+ struct tap_softc *tp;
+
+ mtx_lock(&tapmtx);
+ SLIST_FOREACH(tp, &taphead, tap_next) {
+ mtx_lock(&tp->tap_mtx);
+
+ if ((tp->tap_flags & (TAP_OPEN|TAP_ALLOCATED|extra)) == extra) {
+ tp->tap_flags |= TAP_ALLOCATED;
+ *dev = tp->tap_dev;
+ mtx_unlock(&tp->tap_mtx);
+ mtx_unlock(&tapmtx);
+
+ return (1);
+ }
+ mtx_unlock(&tp->tap_mtx);
+ }
+ mtx_unlock(&tapmtx);
+
+ return (0);
+}
+
+static int
tap_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct cdev *dev;
@@ -288,7 +313,7 @@
mtx_lock(&tapmtx);
SLIST_FOREACH(tp, &taphead, tap_next) {
mtx_lock(&tp->tap_mtx);
- if (tp->tap_flags & TAP_OPEN) {
+ if (tp->tap_flags & (TAP_OPEN|TAP_ALLOCATED)) {
mtx_unlock(&tp->tap_mtx);
mtx_unlock(&tapmtx);
return (EBUSY);
@@ -353,8 +378,18 @@
/* We're interested in only tap/vmnet devices. */
if (strcmp(name, TAP) == 0) {
+ if (tap_clone_lookup(dev, 0)) {
+ dev_ref(*dev);
+ return;
+ }
+
unit = -1;
} else if (strcmp(name, VMNET) == 0) {
+ if (tap_clone_lookup(dev, TAP_VMNET)) {
+ dev_ref(*dev);
+ return;
+ }
+
unit = -1;
extra = VMNET_DEV_MASK;
} else if (dev_stdclone(name, NULL, TAP, &unit) != 1) {
@@ -559,12 +594,11 @@
KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0);
mtx_lock(&tp->tap_mtx);
- tp->tap_flags &= ~TAP_OPEN;
+ tp->tap_flags &= ~(TAP_OPEN|TAP_ALLOCATED);
tp->tap_pid = 0;
mtx_unlock(&tp->tap_mtx);
- TAPDEBUG("%s is closed. minor = %#x\n",
- ifp->if_xname, minor(dev));
+ TAPDEBUG("%s is closed. minor = %#x\n", ifp->if_xname, minor(dev));
return (0);
} /* tapclose */
--- if_tapvar.h.orig 2005-06-10 12:04:52.000000000 -0700
+++ if_tapvar.h 2008-09-22 17:34:00.000000000 -0700
@@ -54,6 +54,7 @@
#define TAP_ASYNC (1 << 3)
#define TAP_READY (TAP_OPEN|TAP_INITED)
#define TAP_VMNET (1 << 4)
+#define TAP_ALLOCATED (1 << 5)
u_int8_t ether_addr[ETHER_ADDR_LEN]; /* ether addr of the remote side */
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bb4a86c70809221849v640e66awa52a2b5d944ca0dc>
