summaryrefslogtreecommitdiffstats
path: root/sys/netipx/spx_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netipx/spx_usrreq.c')
-rw-r--r--sys/netipx/spx_usrreq.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c
index 98d548c..7ef9d9d 100644
--- a/sys/netipx/spx_usrreq.c
+++ b/sys/netipx/spx_usrreq.c
@@ -1145,27 +1145,30 @@ spx_setpersist(struct spxpcb *cb)
int
spx_ctloutput(struct socket *so, struct sockopt *sopt)
{
- struct ipxpcb *ipxp = sotoipxpcb(so);
+ struct spxhdr spxhdr;
+ struct ipxpcb *ipxp;
struct spxpcb *cb;
int mask, error;
short soptval;
u_short usoptval;
int optval;
- error = 0;
-
/*
* This will have to be changed when we do more general stacking of
* protocols.
*/
if (sopt->sopt_level != IPXPROTO_SPX)
return (ipx_ctloutput(so, sopt));
+
+ ipxp = sotoipxpcb(so);
if (ipxp == NULL)
return (EINVAL);
- else
- cb = ipxtospxpcb(ipxp);
+
+ IPX_LOCK(ipxp);
+ cb = ipxtospxpcb(ipxp);
KASSERT(cb != NULL, ("spx_ctloutput: cb == NULL"));
+ error = 0;
switch (sopt->sopt_dir) {
case SOPT_GET:
switch (sopt->sopt_name) {
@@ -1176,30 +1179,33 @@ spx_ctloutput(struct socket *so, struct sockopt *sopt)
case SO_HEADERS_ON_OUTPUT:
mask = SF_HO;
get_flags:
- /* Unlocked read. */
soptval = cb->s_flags & mask;
- error = sooptcopyout(sopt, &soptval, sizeof soptval);
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &soptval,
+ sizeof(soptval));
break;
case SO_MTU:
- /* Unlocked read. */
usoptval = cb->s_mtu;
- error = sooptcopyout(sopt, &usoptval, sizeof usoptval);
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &usoptval,
+ sizeof(usoptval));
break;
case SO_LAST_HEADER:
- /* Unlocked read. */
- error = sooptcopyout(sopt, &cb->s_rhdr,
- sizeof cb->s_rhdr);
+ spxhdr = cb->s_rhdr;
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr));
break;
case SO_DEFAULT_HEADERS:
- /* Unlocked read. */
- error = sooptcopyout(sopt, &cb->s_shdr,
- sizeof cb->s_shdr);
+ spxhdr = cb->s_shdr;
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr));
break;
default:
+ IPX_UNLOCK(ipxp);
error = ENOPROTOOPT;
}
break;
@@ -1209,6 +1215,7 @@ spx_ctloutput(struct socket *so, struct sockopt *sopt)
* XXX Why are these shorts on get and ints on set? That
* doesn't make any sense...
*/
+ IPX_UNLOCK(ipxp);
switch (sopt->sopt_name) {
case SO_HEADERS_ON_INPUT:
mask = SF_HI;
@@ -1278,6 +1285,9 @@ spx_ctloutput(struct socket *so, struct sockopt *sopt)
error = ENOPROTOOPT;
}
break;
+
+ default:
+ panic("spx_ctloutput: bad socket option direction");
}
return (error);
}
OpenPOWER on IntegriCloud