diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-06-21 21:04:12 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-06-21 21:04:12 +0000 |
commit | 9e88f817eec82327026cdbd1ec18229191f6482d (patch) | |
tree | ab15f66e2608189ce25106a3bf1b8202ed4a4dac /sys/netipx/ipx_pcb.c | |
parent | d092e8e13d0d2c4c93ccc14801eb033e16b09bb1 (diff) | |
download | FreeBSD-src-9e88f817eec82327026cdbd1ec18229191f6482d.zip FreeBSD-src-9e88f817eec82327026cdbd1ec18229191f6482d.tar.gz |
Introduce basic locking of global IPX address list 'ipx_ifaddr' using
a new rwlock, ipx_ifaddr_rw, wrapped with macros. This locking is
necessary but not sufficient, in isolation, to satisfy the stability
requirements of a fully parallel IPX input path during interface
reconfiguration.
MFC after: 3 weeks
Diffstat (limited to 'sys/netipx/ipx_pcb.c')
-rw-r--r-- | sys/netipx/ipx_pcb.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/netipx/ipx_pcb.c b/sys/netipx/ipx_pcb.c index a478c08..bfe68c3 100644 --- a/sys/netipx/ipx_pcb.c +++ b/sys/netipx/ipx_pcb.c @@ -222,10 +222,13 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) * If we found a route, use the address * corresponding to the outgoing interface */ - if (ro->ro_rt != NULL && (ifp = ro->ro_rt->rt_ifp) != NULL) + if (ro->ro_rt != NULL && (ifp = ro->ro_rt->rt_ifp) != NULL) { + IPX_IFADDR_RLOCK(); for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next) if (ia->ia_ifp == ifp) break; + IPX_IFADDR_RUNLOCK(); + } if (ia == NULL) { u_short fport = sipx->sipx_addr.x_port; sipx->sipx_addr.x_port = 0; @@ -251,20 +254,29 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) * If we found a route, use the address * corresponding to the outgoing interface */ - if (ro->ro_rt != NULL && (ifp = ro->ro_rt->rt_ifp) != NULL) + if (ro->ro_rt != NULL && (ifp = ro->ro_rt->rt_ifp) != NULL) { + IPX_IFADDR_RLOCK(); for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next) if (ia->ia_ifp == ifp) break; + IPX_IFADDR_RUNLOCK(); + } if (ia == NULL) { u_short fport = sipx->sipx_addr.x_port; sipx->sipx_addr.x_port = 0; ia = (struct ipx_ifaddr *) ifa_ifwithdstaddr((struct sockaddr *)sipx); sipx->sipx_addr.x_port = fport; - if (ia == NULL) + if (ia == NULL) { + IPX_IFADDR_RLOCK(); ia = ipx_iaonnetof(&sipx->sipx_addr); - if (ia == NULL) + IPX_IFADDR_RUNLOCK(); + } + if (ia == NULL) { + IPX_IFADDR_RLOCK(); ia = ipx_ifaddr; + IPX_IFADDR_RUNLOCK(); + } if (ia == NULL) return (EADDRNOTAVAIL); } |