diff options
author | rwatson <rwatson@FreeBSD.org> | 2005-01-09 05:10:43 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2005-01-09 05:10:43 +0000 |
commit | 09474340ccfc8ce982f3dd22efb3df1e98a0cb0f (patch) | |
tree | 8f84fe0e883e64c196e832403fa50884cbb9be82 /sys/netipx/ipx_pcb.c | |
parent | c7ec30d9b796b05c4aad6442913085be5405f138 (diff) | |
download | FreeBSD-src-09474340ccfc8ce982f3dd22efb3df1e98a0cb0f.zip FreeBSD-src-09474340ccfc8ce982f3dd22efb3df1e98a0cb0f.tar.gz |
Assert or acquire the IPX PCB list lock or IPX PCB locks throughout
the IPX-related PCB routines. In general, the list lock is required
to iterate the PCB list, either for read or write; the PCB lock is
required to access or modify a PCB. To change the binding of a PCB,
both locks must be held.
MFC after: 3 weeks
Diffstat (limited to 'sys/netipx/ipx_pcb.c')
-rw-r--r-- | sys/netipx/ipx_pcb.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/sys/netipx/ipx_pcb.c b/sys/netipx/ipx_pcb.c index 322e569..12f6577 100644 --- a/sys/netipx/ipx_pcb.c +++ b/sys/netipx/ipx_pcb.c @@ -63,6 +63,8 @@ ipx_pcballoc(so, head, td) { register struct ipxpcb *ipxp; + IPX_LIST_LOCK_ASSERT(); + MALLOC(ipxp, struct ipxpcb *, sizeof *ipxp, M_PCB, M_NOWAIT | M_ZERO); if (ipxp == NULL) return (ENOBUFS); @@ -84,6 +86,9 @@ ipx_pcbbind(ipxp, nam, td) register struct sockaddr_ipx *sipx; u_short lport = 0; + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(ipxp); + if (ipxp->ipxp_lport || !ipx_nullhost(ipxp->ipxp_laddr)) return (EINVAL); if (nam == NULL) @@ -140,6 +145,9 @@ ipx_pcbconnect(ipxp, nam, td) register struct route *ro; struct ifnet *ifp; + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(ipxp); + ia = NULL; if (sipx->sipx_family != AF_IPX) @@ -260,6 +268,9 @@ ipx_pcbdisconnect(ipxp) struct ipxpcb *ipxp; { + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(ipxp); + ipxp->ipxp_faddr = zeroipx_addr; if (ipxp->ipxp_socket->so_state & SS_NOFDREF) ipx_pcbdetach(ipxp); @@ -271,6 +282,9 @@ ipx_pcbdetach(ipxp) { struct socket *so = ipxp->ipxp_socket; + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(ipxp); + ACCEPT_LOCK(); SOCK_LOCK(so); so->so_pcb = NULL; @@ -293,7 +307,9 @@ ipx_setsockaddr(ipxp, nam) bzero((caddr_t)sipx, sizeof(*sipx)); sipx->sipx_len = sizeof(*sipx); sipx->sipx_family = AF_IPX; + IPX_LOCK(ipxp); sipx->sipx_addr = ipxp->ipxp_laddr; + IPX_UNLOCK(ipxp); *nam = sodupsockaddr((struct sockaddr *)sipx, M_WAITOK); } @@ -303,12 +319,14 @@ ipx_setpeeraddr(ipxp, nam) struct sockaddr **nam; { struct sockaddr_ipx *sipx, ssipx; - + sipx = &ssipx; bzero(sipx, sizeof(*sipx)); sipx->sipx_len = sizeof(*sipx); sipx->sipx_family = AF_IPX; + IPX_LOCK(ipxp); sipx->sipx_addr = ipxp->ipxp_faddr; + IPX_UNLOCK(ipxp); *nam = sodupsockaddr((struct sockaddr *)sipx, M_WAITOK); } @@ -322,6 +340,8 @@ ipx_pcblookup(faddr, lport, wildp) int matchwild = 3, wildcard; u_short fport; + IPX_LIST_LOCK_ASSERT(); + fport = faddr->x_port; LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { if (ipxp->ipxp_lport != lport) |