Index: sys/net/if_tun.c =================================================================== --- sys/net/if_tun.c +++ sys/net/if_tun.c @@ -79,6 +79,7 @@ #define TUN_RWAIT 0x0040 #define TUN_ASYNC 0x0080 #define TUN_IFHEAD 0x0100 +#define TUN_DYING 0x0200 #define TUN_READY (TUN_OPEN | TUN_INITED) @@ -272,6 +273,7 @@ struct cdev *dev; mtx_lock(&tp->tun_mtx); + tp->tun_flags |= TUN_DYING; if ((tp->tun_flags & TUN_OPEN) != 0) cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx); else @@ -464,19 +466,13 @@ tp = dev->si_drv1; } - /* - * XXXRW: This use of tun_pid is subject to error due to the - * fact that a reference to the tunnel can live beyond the - * death of the process that created it. Can we replace this - * with a simple busy flag? - */ mtx_lock(&tp->tun_mtx); - if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) { + if ((tp->tun_flags & (TUN_OPEN | TUN_DYING)) != 0) { mtx_unlock(&tp->tun_mtx); return (EBUSY); } - tp->tun_pid = td->td_proc->p_pid; + tp->tun_pid = td->td_proc->p_pid; tp->tun_flags |= TUN_OPEN; ifp = TUN2IFP(tp); if_link_state_change(ifp, LINK_STATE_UP);