Remove `sc_dead' logic from pppac(4). It is used to prevent
authormvs <mvs@openbsd.org>
Wed, 10 Feb 2021 13:38:46 +0000 (13:38 +0000)
committermvs <mvs@openbsd.org>
Wed, 10 Feb 2021 13:38:46 +0000 (13:38 +0000)
pppac_ioctl() be called on dying pppac(4) interface. But now if_detach()
makes dying `ifp' inaccessible and waits for references which are in-use
in ioctl(2) path. This logic is not required anymore. Also if_detach()
was moved before klist_invalidate() to prevent the case while
pppac_qstart() bump `sc_rsel'.

ok yasuoka@

sys/net/if_pppx.c

index 4280558..2c8caa9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_pppx.c,v 1.108 2021/02/01 07:46:55 mvs Exp $ */
+/*     $OpenBSD: if_pppx.c,v 1.109 2021/02/10 13:38:46 mvs Exp $ */
 
 /*
  * Copyright (c) 2010 Claudio Jeker <claudio@openbsd.org>
@@ -930,7 +930,6 @@ RBT_GENERATE(pppx_ifs, pppx_if, pxi_entry, pppx_if_cmp);
 
 struct pppac_softc {
        struct ifnet    sc_if;
-       unsigned int    sc_dead;        /* [N] */
        dev_t           sc_dev;         /* [I] */
        LIST_ENTRY(pppac_softc)
                        sc_entry;       /* [K] */
@@ -1305,17 +1304,16 @@ pppacclose(dev_t dev, int flags, int mode, struct proc *p)
        int s;
 
        NET_LOCK();
-       sc->sc_dead = 1;
        CLR(ifp->if_flags, IFF_RUNNING);
        NET_UNLOCK();
 
+       if_detach(ifp);
+
        s = splhigh();
        klist_invalidate(&sc->sc_rsel.si_note);
        klist_invalidate(&sc->sc_wsel.si_note);
        splx(s);
 
-       if_detach(ifp);
-
        pool_put(&pipex_session_pool, sc->sc_multicast_session);
        NET_LOCK();
        pipex_destroy_all_sessions(sc);
@@ -1330,13 +1328,9 @@ pppacclose(dev_t dev, int flags, int mode, struct proc *p)
 static int
 pppac_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
-       struct pppac_softc *sc = ifp->if_softc;
        /* struct ifreq *ifr = (struct ifreq *)data; */
        int error = 0;
 
-       if (sc->sc_dead)
-               return (ENXIO);
-
        switch (cmd) {
        case SIOCSIFADDR:
                SET(ifp->if_flags, IFF_UP); /* XXX cry cry */