summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_bridge.c
diff options
context:
space:
mode:
authorarchie <archie@FreeBSD.org>2001-12-15 20:48:53 +0000
committerarchie <archie@FreeBSD.org>2001-12-15 20:48:53 +0000
commitdf155dfc652ae1be3b5ac135373e8620189a14d2 (patch)
tree6eabec496e1ca483b00fd69e01b1e5cbe9def161 /sys/netgraph/ng_bridge.c
parent27bbab02b765aab221c5b395c7000fc3e9b4f868 (diff)
downloadFreeBSD-src-df155dfc652ae1be3b5ac135373e8620189a14d2.zip
FreeBSD-src-df155dfc652ae1be3b5ac135373e8620189a14d2.tar.gz
Don't free a structure containing a 'struct callout' structure while that
callout is still pending. MFC after: 3 days
Diffstat (limited to 'sys/netgraph/ng_bridge.c')
-rw-r--r--sys/netgraph/ng_bridge.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c
index 9d93201..a09ed9f 100644
--- a/sys/netgraph/ng_bridge.c
+++ b/sys/netgraph/ng_bridge.c
@@ -334,9 +334,10 @@ ng_bridge_constructor(node_p node)
NG_NODE_SET_PRIVATE(node, priv);
priv->node = node;
- /* Start timer by faking a timeout event */
- NG_NODE_REF(node); /* because the timeout will drop a reference */
- ng_bridge_timeout(node);
+ /* Start timer; timer is always running while node is alive */
+ callout_reset(&priv->timer, hz, ng_bridge_timeout, priv->node);
+
+ /* Done */
return (0);
}
@@ -766,13 +767,17 @@ ng_bridge_shutdown(node_p node)
{
const priv_p priv = NG_NODE_PRIVATE(node);
+ /*
+ * Shut down everything except the timer. There's no way to
+ * avoid another possible timeout event (it may have already
+ * been dequeued), so we can't free the node yet.
+ */
KASSERT(priv->numLinks == 0 && priv->numHosts == 0,
("%s: numLinks=%d numHosts=%d",
__func__, priv->numLinks, priv->numHosts));
FREE(priv->tab, M_NETGRAPH_BRIDGE);
- FREE(priv, M_NETGRAPH_BRIDGE);
- NG_NODE_SET_PRIVATE(node, NULL);
- NG_NODE_UNREF(node);
+
+ /* NG_INVALID flag is now set so node will be freed at next timeout */
return (0);
}
@@ -967,6 +972,8 @@ ng_bridge_remove_hosts(priv_p priv, int linkNum)
* we decrement link->loopCount for those links being muted due to
* a detected loopback condition, and we remove any hosts from
* the hashtable whom we haven't heard from in a long while.
+ *
+ * If the node has the NG_INVALID flag set, out job is to kill it.
*/
static void
ng_bridge_timeout(void *arg)
@@ -977,9 +984,11 @@ ng_bridge_timeout(void *arg)
int counter = 0;
int linkNum;
- /* Avoid race condition with ng_bridge_shutdown() */
+ /* If node was shut down, this is the final lingering timeout */
s = splnet();
- if ((NG_NODE_NOT_VALID(node)) || priv == NULL) {
+ if (NG_NODE_NOT_VALID(node)) {
+ FREE(priv, M_NETGRAPH);
+ NG_NODE_SET_PRIVATE(node, NULL);
NG_NODE_UNREF(node);
splx(s);
return;
OpenPOWER on IntegriCloud