On Fri, Apr 10, 2020 at 11:39:59PM +0200, Hrvoje Popovski wrote:
> hostname.tpmr20
> trunkport vxlan20
> trunkport vlan20
> up
> 
> 
> x3550m4# ifconfig tpmr20 destroy
> 
> splassert: vlan_ioctl: want 2 have 0
> Starting stack trace...
> vlan_ioctl(ffff80000129d800,80206910,ffff800021d048a8) at vlan_ioctl+0x65
> ifpromisc(ffff80000129d800,0) at ifpromisc+0xbb
> tpmr_p_dtor(ffff800000b0e800,ffff800001288100,5ea751037d06af69) at
> tpmr_p_dtor+0xa0
> tpmr_clone_destroy(ffff800000b0e800) at tpmr_clone_destroy+0xba
> ifioctl(fffffd8784ae41c8,80206979,ffff800021d04ab0,ffff800021c0cd90) at
> ifioctl+0x1c2
> soo_ioctl(fffffd877da53e10,80206979,ffff800021d04ab0,ffff800021c0cd90)
> at soo_ioctl+0x171
> sys_ioctl(ffff800021c0cd90,ffff800021d04bc0,ffff800021d04c20) at
> sys_ioctl+0x2df
> syscall(ffff800021d04c90) at syscall+0x389
> Xsyscall() at Xsyscall+0x128
> end of kernel
> end trace frame: 0x7f7ffffc1250, count: 248
> End of stack trace.

The diff below should fix that.

Index: net/if_tpmr.c
===================================================================
RCS file: src/sys/net/if_tpmr.c,v
retrieving revision 1.8
diff -u -p -r1.8 if_tpmr.c
--- net/if_tpmr.c       10 Nov 2019 10:03:28 -0000      1.8
+++ net/if_tpmr.c       11 Apr 2020 03:02:27 -0000
@@ -127,7 +127,7 @@ static int  tpmr_p_output(struct ifnet *,
 
 static int     tpmr_get_trunk(struct tpmr_softc *, struct trunk_reqall *);
 static void    tpmr_p_dtor(struct tpmr_softc *, struct tpmr_port *,
-                   const char *);
+                   const char *, int);
 static int     tpmr_add_port(struct tpmr_softc *,
                    const struct trunk_reqport *);
 static int     tpmr_get_port(struct tpmr_softc *, struct trunk_reqport *);
@@ -205,7 +205,7 @@ tpmr_clone_destroy(struct ifnet *ifp)
                struct tpmr_port *p = SMR_PTR_GET_LOCKED(&sc->sc_ports[i]);
                if (p == NULL)
                        continue;
-               tpmr_p_dtor(sc, p, "destroy");
+               tpmr_p_dtor(sc, p, "destroy", 0);
        }
 
        free(sc, M_DEVBUF, sizeof(*sc));
@@ -644,7 +644,7 @@ tpmr_del_port(struct tpmr_softc *sc, con
        if (p == NULL)
                return (EINVAL);
 
-       tpmr_p_dtor(sc, p, "del");
+       tpmr_p_dtor(sc, p, "del", 1);
 
        return (0);
 }
@@ -700,11 +700,13 @@ tpmr_p_output(struct ifnet *ifp0, struct
 }
 
 static void
-tpmr_p_dtor(struct tpmr_softc *sc, struct tpmr_port *p, const char *op)
+tpmr_p_dtor(struct tpmr_softc *sc, struct tpmr_port *p, const char *op,
+    int netlocked)
 {
        struct ifnet *ifp = &sc->sc_if;
        struct ifnet *ifp0 = p->p_ifp0;
        struct arpcom *ac0 = (struct arpcom *)ifp0;
+       int error;
 
        DPRINTF(sc, "%s %s: destroying port\n",
            ifp->if_xname, ifp0->if_xname);
@@ -720,7 +722,14 @@ tpmr_p_dtor(struct tpmr_softc *sc, struc
        sc->sc_nports--;
        SMR_PTR_SET_LOCKED(&sc->sc_ports[p->p_slot], NULL);
 
-       if (ifpromisc(ifp0, 0) != 0) {
+       if (netlocked) {
+               error = ifpromisc(ifp0, 0);
+       } else {
+               NET_LOCK();
+               error = ifpromisc(ifp0, 0);
+               NET_UNLOCK();
+       }
+       if (error != 0) {
                log(LOG_WARNING, "%s %s: unable to disable promisc",
                    ifp->if_xname, ifp0->if_xname);
        }
@@ -745,7 +754,7 @@ tpmr_p_detach(void *arg)
        struct tpmr_port *p = arg;
        struct tpmr_softc *sc = p->p_tpmr;
 
-       tpmr_p_dtor(sc, p, "detach");
+       tpmr_p_dtor(sc, p, "detach", 1);
 
        NET_ASSERT_LOCKED();
 }

Reply via email to