Changeset View
Changeset View
Standalone View
Standalone View
sys/netgraph/ng_eiface.c
Show First 20 Lines • Show All 617 Lines • ▼ Show 20 Lines | ng_eiface_rmnode(node_p node) | ||||
const priv_p priv = NG_NODE_PRIVATE(node); | const priv_p priv = NG_NODE_PRIVATE(node); | ||||
struct ifnet *const ifp = priv->ifp; | struct ifnet *const ifp = priv->ifp; | ||||
/* | /* | ||||
* the ifnet may be in a different vnet than the netgraph node, | * the ifnet may be in a different vnet than the netgraph node, | ||||
* hence we have to change the current vnet context here. | * hence we have to change the current vnet context here. | ||||
*/ | */ | ||||
CURVNET_SET_QUIET(ifp->if_vnet); | CURVNET_SET_QUIET(ifp->if_vnet); | ||||
ifmedia_removeall(&priv->media); | |||||
ether_ifdetach(ifp); | ether_ifdetach(ifp); | ||||
if_free(ifp); | if_free(ifp); | ||||
ifmedia_removeall(&priv->media); | |||||
vmaffione: Move the `ifmedia_removeall` before `if_free`, because the ifmedia callbacks need to access… | |||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
free_unr(V_ng_eiface_unit, priv->unit); | free_unr(V_ng_eiface_unit, priv->unit); | ||||
free(priv, M_NETGRAPH); | free(priv, M_NETGRAPH); | ||||
NG_NODE_SET_PRIVATE(node, NULL); | NG_NODE_SET_PRIVATE(node, NULL); | ||||
NG_NODE_UNREF(node); | NG_NODE_UNREF(node); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines |
Move the ifmedia_removeall before if_free, because the ifmedia callbacks need to access ifp, and so in theory the callbacks may be called after if_free and before ifmedia_removeall, resulting in a crash (if lucky).
Moreover, ifdetach --> ifmedia_removeall --> if_free is the same sequence used in all the other drivers.