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>
This commit is contained in:
parent
5e067d612f
commit
f2ba84d72d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149615
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user