summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-01-09 05:15:59 +0000
committerrwatson <rwatson@FreeBSD.org>2005-01-09 05:15:59 +0000
commit1845f530cba5145fb492c5215954971bef542381 (patch)
tree21df01e71ba8d154af722897352cec4ae7000c17
parent056eceb4700e1ba69510991224a31bf6399bdc5d (diff)
downloadFreeBSD-src-1845f530cba5145fb492c5215954971bef542381.zip
FreeBSD-src-1845f530cba5145fb492c5215954971bef542381.tar.gz
Protect ipx_pexseq with the IPX PCB list mutex.
When processing socket options against IPX PCBs, generally protect PCB fields using the IPX PCB mutex. Where possible, use unlocked reads on integer values to avoid locking overhead. MFC after: 3 weeks
-rw-r--r--sys/netipx/ipx_input.c2
-rw-r--r--sys/netipx/ipx_usrreq.c13
2 files changed, 12 insertions, 3 deletions
diff --git a/sys/netipx/ipx_input.c b/sys/netipx/ipx_input.c
index d0d01a4..ee1ca23 100644
--- a/sys/netipx/ipx_input.c
+++ b/sys/netipx/ipx_input.c
@@ -95,7 +95,7 @@ struct ipxpcbhead ipxrawpcb_list;
static int ipxqmaxlen = IFQ_MAXLEN;
static struct ifqueue ipxintrq;
-long ipx_pexseq;
+long ipx_pexseq; /* Locked with ipxpcb_list_mtx. */
static int ipx_do_route(struct ipx_addr *src, struct route *ro);
static void ipx_undo_route(struct route *ro);
diff --git a/sys/netipx/ipx_usrreq.c b/sys/netipx/ipx_usrreq.c
index dd03614..21e7612 100644
--- a/sys/netipx/ipx_usrreq.c
+++ b/sys/netipx/ipx_usrreq.c
@@ -325,6 +325,7 @@ ipx_ctloutput(so, sopt)
int mask, error, optval;
short soptval;
struct ipx ioptval;
+ long seq;
error = 0;
if (ipxp == NULL)
@@ -348,6 +349,7 @@ ipx_ctloutput(so, sopt)
case SO_HEADERS_ON_OUTPUT:
mask = IPXP_RAWOUT;
get_flags:
+ /* Unlocked read. */
soptval = ipxp->ipxp_flags & mask;
error = sooptcopyout(sopt, &soptval, sizeof soptval);
break;
@@ -356,16 +358,20 @@ ipx_ctloutput(so, sopt)
ioptval.ipx_len = 0;
ioptval.ipx_sum = 0;
ioptval.ipx_tc = 0;
+ IPX_LOCK(ipxp);
ioptval.ipx_pt = ipxp->ipxp_dpt;
ioptval.ipx_dna = ipxp->ipxp_faddr;
ioptval.ipx_sna = ipxp->ipxp_laddr;
+ IPX_UNLOCK(ipxp);
error = sooptcopyout(sopt, &soptval, sizeof soptval);
break;
case SO_SEQNO:
- error = sooptcopyout(sopt, &ipx_pexseq,
- sizeof ipx_pexseq);
+ IPX_LIST_LOCK();
+ seq = ipx_pexseq;
ipx_pexseq++;
+ IPX_LIST_UNLOCK();
+ error = sooptcopyout(sopt, &seq, sizeof seq);
break;
default:
@@ -393,10 +399,12 @@ ipx_ctloutput(so, sopt)
sizeof optval);
if (error)
break;
+ IPX_LOCK(ipxp);
if (optval)
ipxp->ipxp_flags |= mask;
else
ipxp->ipxp_flags &= ~mask;
+ IPX_UNLOCK(ipxp);
break;
case SO_DEFAULT_HEADERS:
@@ -404,6 +412,7 @@ ipx_ctloutput(so, sopt)
sizeof ioptval);
if (error)
break;
+ /* Unlocked write. */
ipxp->ipxp_dpt = ioptval.ipx_pt;
break;
#ifdef IPXIP
OpenPOWER on IntegriCloud