summaryrefslogtreecommitdiffstats
path: root/sys/net/if_bridge.c
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2015-02-14 18:15:14 +0000
committerhrs <hrs@FreeBSD.org>2015-02-14 18:15:14 +0000
commitaae7e542bc5f5d7e9d45cff295345b09440356f1 (patch)
tree378cb16dc2ca1dccb6cdef29a9c447b74f403f10 /sys/net/if_bridge.c
parent9b83a1eb03a39e0c25ec6c20050e639b2b443898 (diff)
downloadFreeBSD-src-aae7e542bc5f5d7e9d45cff295345b09440356f1.zip
FreeBSD-src-aae7e542bc5f5d7e9d45cff295345b09440356f1.tar.gz
Fix a panic when tearing down a vnet on a VIMAGE-enabled kernel.
There was a race that bridge_ifdetach() could be called via ifnet_departure event handler after vnet_bridge_uninit(). PR: 195859 Reported by: Danilo Egea Gondolfo
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r--sys/net/if_bridge.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 019bbf5..753854d 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -228,7 +228,7 @@ struct bridge_softc {
static VNET_DEFINE(struct mtx, bridge_list_mtx);
#define V_bridge_list_mtx VNET(bridge_list_mtx)
-eventhandler_tag bridge_detach_cookie = NULL;
+static eventhandler_tag bridge_detach_cookie;
int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
@@ -538,6 +538,7 @@ vnet_bridge_uninit(const void *unused __unused)
{
if_clone_detach(V_bridge_cloner);
+ V_bridge_cloner = NULL;
BRIDGE_LIST_LOCK_DESTROY();
}
VNET_SYSUNINIT(vnet_bridge_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
@@ -1797,7 +1798,13 @@ bridge_ifdetach(void *arg __unused, struct ifnet *ifp)
if (ifp->if_flags & IFF_RENAMING)
return;
-
+ if (V_bridge_cloner == NULL) {
+ /*
+ * This detach handler can be called after
+ * vnet_bridge_uninit(). Just return in that case.
+ */
+ return;
+ }
/* Check if the interface is a bridge member */
if (sc != NULL) {
BRIDGE_LOCK(sc);
OpenPOWER on IntegriCloud