summaryrefslogtreecommitdiffstats
path: root/sys/netipx/ipx_pcb.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-06-21 21:04:12 +0000
committerrwatson <rwatson@FreeBSD.org>2009-06-21 21:04:12 +0000
commit9e88f817eec82327026cdbd1ec18229191f6482d (patch)
treeab15f66e2608189ce25106a3bf1b8202ed4a4dac /sys/netipx/ipx_pcb.c
parentd092e8e13d0d2c4c93ccc14801eb033e16b09bb1 (diff)
downloadFreeBSD-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.c20
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);
}
OpenPOWER on IntegriCloud