diff --git a/sys/net/if.c b/sys/net/if.c index d7310ab..43ae5ab 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -335,7 +335,8 @@ if_nullioctl(struct ifnet *ifp, u_long cmd, void *data) /* Wake ifioctl_detach(), who may wait for all threads to * quit the critical section. */ - cv_signal(&ifp->if_ioctl_lock->il_emptied); + if (ifp->if_ioctl_lock != NULL) + cv_signal(&ifp->if_ioctl_lock->il_emptied); return ENXIO; } @@ -1148,8 +1149,6 @@ again: /* Announce that the interface is gone. */ rt_ifannouncemsg(ifp, IFAN_DEPARTURE); - ifioctl_detach(ifp); - IF_AFDATA_LOCK_DESTROY(ifp); softint_disestablish(ifp->if_link_si); @@ -1288,6 +1287,8 @@ if_clone_destroy(const char *name) if (ifc->ifc_destroy == NULL) return EOPNOTSUPP; + ifioctl_detach(ifp); + return (*ifc->ifc_destroy)(ifp); } @@ -2420,8 +2421,19 @@ doifioctl(struct socket *so, u_long cmd, void *data, struct lwp *l) oif_flags = ifp->if_flags; + mutex_enter(&if_clone_mtx); + if (ifp->if_ioctl_lock == NULL) { + mutex_exit(&if_clone_mtx); + return ENXIO; + } ifnet_lock_enter(ifp->if_ioctl_lock); - error = (*ifp->if_ioctl)(ifp, cmd, data); + mutex_exit(&if_clone_mtx); + + if (ifp->if_ioctl != NULL) + error = (*ifp->if_ioctl)(ifp, cmd, data); + else + error = ENXIO; + if (error != ENOTTY) ; else if (so->so_proto == NULL)