Page MenuHomeFreeBSD

D49359.diff
No OneTemporary

D49359.diff

diff --git a/sys/net/if.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1125,9 +1125,38 @@
sx_assert(&ifnet_detach_sxlock, SX_XLOCKED);
+ /*
+ * Ideally the interface has been in down state before it been detached,
+ * but that requires lots of modification of drivers, and also it is a
+ * little safer to make it down here, as the interface has already been
+ * removed from the global network interface list.
+ */
+ if ((ifp->if_flags & IFF_UP) != 0) {
+ if_down(ifp);
+
+ /* Give the driver a chance to teardown */
+ if (ifp->if_ioctl != NULL) {
+ struct ifreq ifr;
+
+ ifr.ifr_flags = ifp->if_flags & 0xffff;
+ ifr.ifr_flagshigh = ifp->if_flags >> 16;
+ (void)(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
+ }
+ }
+
/*
* At this point we know the interface still was on the ifnet list
* and we removed it so we are in a stable state.
+ *
+ * Note that, NET_EPOCH_WAIT() blocks the current thread but does not
+ * block other threads from entering net epoch. Well it is a nice
+ * synchronization point, that, threads those enter net epoch will see
+ * writes before NET_EPOCH_WAIT(), e.g. the ~IFF_UP flag.
+ *
+ * Other threads, typically the input / output path, should check the
+ * interface's up state, aka IFF_UP flag, after (re)entering net epoch.
+ * Otherwise it is possible to reference an interface in detaching
+ * progress and see consistency, e.g. NULL if_afdata[AF_INET6].
*/
NET_EPOCH_WAIT();
@@ -1149,8 +1178,6 @@
taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
taskqueue_drain(taskqueue_swi, &ifp->if_addmultitask);
- if_down(ifp);
-
#ifdef VIMAGE
/*
* On VNET shutdown abort here as the stack teardown will do all

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 21, 4:04 AM (13 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17167259
Default Alt Text
D49359.diff (1 KB)

Event Timeline