diff options
author | rwatson <rwatson@FreeBSD.org> | 2005-01-09 05:15:59 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2005-01-09 05:15:59 +0000 |
commit | 1845f530cba5145fb492c5215954971bef542381 (patch) | |
tree | 21df01e71ba8d154af722897352cec4ae7000c17 /sys/netipx/ipx_usrreq.c | |
parent | 056eceb4700e1ba69510991224a31bf6399bdc5d (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/netipx/ipx_usrreq.c')
-rw-r--r-- | sys/netipx/ipx_usrreq.c | 13 |
1 files changed, 11 insertions, 2 deletions
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 |