--- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -104 if_clone_destroy() - ifnet_lock(); - ifp = ifunit(name); - ifnet_unlock(); - if (ifp == NULL) - return (ENXIO); - if ((ifc = if_clone_lookup(ifp->if_dname)) == NULL) - return (EINVAL); - unit = ifp->if_dunit; - if (unit < ifc->ifc_minifs) - return (EINVAL); - if (ifc->ifc_destroy == NULL) - return (EOPNOTSUPP); - ifnet_lock(); + ifp = ifunit(name); /* DF-3414: hold the lock + * across lookup..teardown */ + if (ifp == NULL) { ifnet_unlock(); return (ENXIO); } + if ((ifc = if_clone_lookup(ifp->if_dname)) == NULL) { + ifnet_unlock(); return (EINVAL); + } + unit = ifp->if_dunit; + if (unit < ifc->ifc_minifs) { ifnet_unlock(); return (EINVAL); } + if (ifc->ifc_destroy == NULL) { ifnet_unlock(); return (EOPNOTSUPP); } if_clone_free_unit(ifc, unit); error = ifc->ifc_destroy(ifp); if (error) if_clone_alloc_unit(ifc, &unit); ifnet_unlock(); (validated in the DF-3407 pack: stock kernel panics, patched runs 2x120s of the same race clean)