-/* $OpenBSD: if_tun.c,v 1.233 2022/02/15 04:19:52 dlg Exp $ */
+/* $OpenBSD: if_tun.c,v 1.234 2022/02/16 02:22:39 dlg Exp $ */
/* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */
/*
KERNEL_ASSERT_LOCKED();
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
+ refcnt_init(&sc->sc_refs);
+
ifp = &sc->sc_if;
snprintf(ifp->if_xname, sizeof(ifp->if_xname),
"%s%d", ifc->ifc_name, unit);
}
sigio_init(&sc->sc_sigio);
- refcnt_init(&sc->sc_refs);
/* tell tun_dev_open we're initialised */
rdomain = rtable_l2(p->p_p->ps_rtableid);
/* let's find or make an interface to work with */
- while ((ifp = if_unit(name)) == NULL) {
+ while ((sc = tun_name_lookup(name)) == NULL) {
error = if_clone_create(name, rdomain);
switch (error) {
case 0: /* it's probably ours */
}
}
- sc = ifp->if_softc;
+ refcnt_take(&sc->sc_refs);
+
/* wait for it to be fully constructed before we use it */
- while (!ISSET(sc->sc_flags, TUN_INITED)) {
+ for (;;) {
+ if (ISSET(sc->sc_flags, TUN_DEAD)) {
+ error = ENXIO;
+ goto done;
+ }
+
+ if (ISSET(sc->sc_flags, TUN_INITED))
+ break;
+
error = tsleep_nsec(sc, PCATCH, "tuninit", INFSLP);
if (error != 0) {
/* XXX if_clone_destroy if stayup? */
- if_put(ifp);
- return (error);
+ goto done;
}
}
if (sc->sc_dev != 0) {
/* aww, we lost */
- if_put(ifp);
- return (EBUSY);
+ error = EBUSY;
+ goto done;
}
/* it's ours now */
sc->sc_dev = dev;
CLR(sc->sc_flags, stayup);
/* automatically mark the interface running on open */
+ ifp = &sc->sc_if;
NET_LOCK();
SET(ifp->if_flags, IFF_UP | IFF_RUNNING);
NET_UNLOCK();
tun_link_state(ifp, LINK_STATE_FULL_DUPLEX);
- if_put(ifp);
+ error = 0;
- return (0);
+done:
+ tun_put(sc);
+ return (error);
}
/*