diff options
author | glebius <glebius@FreeBSD.org> | 2005-08-30 09:51:54 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-08-30 09:51:54 +0000 |
commit | d066ce1d4bdc71ea45d98ddec665cb97502585ae (patch) | |
tree | 629cfb6921fb5339a29f6a2264dcfbaf07b20749 /sys/netgraph | |
parent | 37e64fd444cca4bb35a47f956fc4cb5ce547948f (diff) | |
download | FreeBSD-src-d066ce1d4bdc71ea45d98ddec665cb97502585ae.zip FreeBSD-src-d066ce1d4bdc71ea45d98ddec665cb97502585ae.tar.gz |
Lock down PPTP node, since it has many data structures, that won't survive
parallel ng_pptp_rcvdata():
- Add a per-node mutex.
- Acquire mutex during all ng_pptp_rcvdata() method.
- Make callouts protected by mutex. Now callouts count as
netgraph writers, but there are plans to allow reader callouts
for nodes, that have internal locking.
- Acquire mutex in ng_pptp_reset(), which can be triggered
by a message or node shutdown.
PR: kern/80035
Tested by: Deomid Ryabkov <myself rojer.pp.ru>
Reviewed by: Deomid Ryabkov <myself rojer.pp.ru>
Diffstat (limited to 'sys/netgraph')
-rw-r--r-- | sys/netgraph/ng_pptpgre.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/sys/netgraph/ng_pptpgre.c b/sys/netgraph/ng_pptpgre.c index 13b4059..2f57ce6 100644 --- a/sys/netgraph/ng_pptpgre.c +++ b/sys/netgraph/ng_pptpgre.c @@ -58,8 +58,10 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/time.h> -#include <sys/mbuf.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/mutex.h> #include <sys/errno.h> #include <netinet/in.h> @@ -165,6 +167,7 @@ struct ng_pptpgre_private { u_int32_t xmitAck; /* last seq # we ack'd */ struct timeval startTime; /* time node was created */ struct ng_pptpgre_stats stats; /* node statistics */ + struct mtx mtx; /* node mutex */ }; typedef struct ng_pptpgre_private *priv_p; @@ -282,8 +285,9 @@ ng_pptpgre_constructor(node_p node) NG_NODE_SET_PRIVATE(node, priv); /* Initialize state */ - ng_callout_init(&priv->ackp.sackTimer); - ng_callout_init(&priv->ackp.rackTimer); + mtx_init(&priv->mtx, "ng_pptp", NULL, MTX_DEF); + ng_callout_init_mtx(&priv->ackp.sackTimer, &priv->mtx); + ng_callout_init_mtx(&priv->ackp.rackTimer, &priv->mtx); /* Done */ return (0); @@ -387,6 +391,7 @@ ng_pptpgre_rcvdata(hook_p hook, item_p item) { const node_p node = NG_HOOK_NODE(hook); const priv_p priv = NG_NODE_PRIVATE(node); + int rval; /* If not configured, reject */ if (!priv->conf.enabled) { @@ -394,12 +399,19 @@ ng_pptpgre_rcvdata(hook_p hook, item_p item) return (ENXIO); } + mtx_lock(&priv->mtx); + /* Treat as xmit or recv data */ if (hook == priv->upper) - return ng_pptpgre_xmit(node, item); - if (hook == priv->lower) - return ng_pptpgre_recv(node, item); - panic("%s: weird hook", __func__); + rval = ng_pptpgre_xmit(node, item); + else if (hook == priv->lower) + rval = ng_pptpgre_recv(node, item); + else + panic("%s: weird hook", __func__); + + mtx_unlock(&priv->mtx); + + return (rval); } /* @@ -413,6 +425,8 @@ ng_pptpgre_shutdown(node_p node) /* Reset node (stops timers) */ ng_pptpgre_reset(node); + mtx_destroy(&priv->mtx); + FREE(priv, M_NETGRAPH); /* Decrement ref count */ @@ -875,6 +889,8 @@ ng_pptpgre_reset(node_p node) const priv_p priv = NG_NODE_PRIVATE(node); struct ng_pptpgre_ackp *const a = &priv->ackp; + mtx_lock(&priv->mtx); + /* Reset adaptive timeout state */ a->ato = PPTP_MAX_TIMEOUT; a->rtt = priv->conf.peerPpd * PPTP_TIME_SCALE / 10; /* ppd in 10ths */ @@ -903,6 +919,8 @@ ng_pptpgre_reset(node_p node) /* Stop timers */ ng_pptpgre_stop_send_ack_timer(node); ng_pptpgre_stop_recv_ack_timer(node); + + mtx_unlock(&priv->mtx); } /* |