Clear the internal table used by if_get(9) and sleep until all
authormpi <mpi@openbsd.org>
Tue, 30 May 2017 06:42:13 +0000 (06:42 +0000)
committermpi <mpi@openbsd.org>
Tue, 30 May 2017 06:42:13 +0000 (06:42 +0000)
remaining ifp references are released *without* the NET_LOCK().

It's safe to do so because the KERNEL_LOCK() serializes accesses
to ``if_map''.

More importantly this fix possible deadlocks between if_get() and
the NET_LOCK().  It is now possible to call them in whatever order.

ok visa@, dlg@

sys/net/if.c

index d519ddc..29ec903 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if.c,v 1.500 2017/05/29 06:08:21 mpi Exp $    */
+/*     $OpenBSD: if.c,v 1.501 2017/05/30 06:42:13 mpi Exp $    */
 /*     $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $  */
 
 /*
@@ -1014,11 +1014,11 @@ if_detach(struct ifnet *ifp)
 
        ifq_clr_oactive(&ifp->if_snd);
 
-       NET_LOCK(s);
-       s2 = splnet();
        /* Other CPUs must not have a reference before we start destroying. */
        if_idxmap_remove(ifp);
 
+       NET_LOCK(s);
+       s2 = splnet();
        ifp->if_qstart = if_detached_qstart;
        ifp->if_ioctl = if_detached_ioctl;
        ifp->if_watchdog = NULL;