summaryrefslogtreecommitdiff
path: root/sys/net/if_tun.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-09-09 20:18:04 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-09-09 20:18:04 +0000
commit014dd0ae40bb6ee04650737132a6aea89e378a7b (patch)
tree5fb59daebfff64d53cee448fdb4275a130a8c146 /sys/net/if_tun.c
parent185e18676f87788d2794087cf18acdbc226162bf (diff)
if_put after if_get.
this is a bit funky cos we give up the ref while sleeping in tunread, and have to get a new ref on wakeup. ok claudio@
Diffstat (limited to 'sys/net/if_tun.c')
-rw-r--r--sys/net/if_tun.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index d0fc0936efa..ba8bb3a4c48 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tun.c,v 1.153 2015/09/01 21:24:04 bluhm Exp $ */
+/* $OpenBSD: if_tun.c,v 1.154 2015/09/09 20:18:03 dlg Exp $ */
/* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */
/*
@@ -729,7 +729,7 @@ tunread(dev_t dev, struct uio *uio, int ioflag)
if ((tp = tun_lookup(minor(dev))) == NULL)
return (ENXIO);
- ifp = &tp->tun_if;
+ ifp = if_ref(&tp->tun_if);
ifindex = ifp->if_index;
TUNDEBUG(("%s: read\n", ifp->if_xname));
if ((tp->tun_flags & TUN_READY) != TUN_READY) {
@@ -742,6 +742,7 @@ tunread(dev_t dev, struct uio *uio, int ioflag)
s = splnet();
do {
while ((tp->tun_flags & TUN_READY) != TUN_READY) {
+ if_put(ifp);
if ((error = tsleep((caddr_t)tp,
(PZERO + 1)|PCATCH, "tunread", 0)) != 0) {
splx(s);
@@ -754,6 +755,7 @@ tunread(dev_t dev, struct uio *uio, int ioflag)
}
IFQ_DEQUEUE(&ifp->if_snd, m0);
if (m0 == NULL) {
+ if_put(ifp);
if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY) {
splx(s);
return (EWOULDBLOCK);
@@ -787,6 +789,7 @@ tunread(dev_t dev, struct uio *uio, int ioflag)
if (error)
ifp->if_oerrors++;
+ if_put(ifp);
return (error);
}