diff options
Diffstat (limited to 'sys/netipx/ipx_pcb.c')
-rw-r--r-- | sys/netipx/ipx_pcb.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/sys/netipx/ipx_pcb.c b/sys/netipx/ipx_pcb.c index 4c8eba0..77fbfe8 100644 --- a/sys/netipx/ipx_pcb.c +++ b/sys/netipx/ipx_pcb.c @@ -158,7 +158,6 @@ noname: int ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) { - struct ipx_ifaddr *ia; struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)nam; struct ipx_addr *dst; struct route *ro; @@ -167,8 +166,6 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) IPX_LIST_LOCK_ASSERT(); IPX_LOCK_ASSERT(ipxp); - ia = NULL; - if (sipx->sipx_family != AF_IPX) return (EAFNOSUPPORT); if (sipx->sipx_port == 0 || ipx_nullhost(sipx->sipx_addr)) @@ -213,6 +210,8 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) rtalloc_ign(ro, 0); } if (ipx_neteqnn(ipxp->ipxp_laddr.x_net, ipx_zeronet)) { + struct ipx_ifaddr *ia = NULL; + /* * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. @@ -225,8 +224,10 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) 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) + if (ia->ia_ifp == ifp) { + ifa_ref(&ia->ia_ifa); break; + } IPX_IFADDR_RUNLOCK(); } if (ia == NULL) { @@ -235,16 +236,28 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) 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) + if (ia != NULL) + ifa_ref(&ia->ia_ifa); + IPX_IFADDR_RUNLOCK(); + } + if (ia == NULL) { + IPX_IFADDR_RLOCK(); ia = ipx_ifaddr; + if (ia != NULL) + ifa_ref(&ia->ia_ifa); + IPX_IFADDR_RUNLOCK(); + } if (ia == NULL) return (EADDRNOTAVAIL); } ipxp->ipxp_laddr.x_net = satoipx_addr(ia->ia_addr).x_net; + ifa_free(&ia->ia_ifa); } if (ipx_nullhost(ipxp->ipxp_laddr)) { + struct ipx_ifaddr *ia = NULL; /* * If route is known or can be allocated now, * our src addr is taken from the i/f, else punt. @@ -257,8 +270,10 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) 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) + if (ia->ia_ifp == ifp) { + ifa_ref(&ia->ia_ifa); break; + } IPX_IFADDR_RUNLOCK(); } if (ia == NULL) { @@ -270,17 +285,22 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td) if (ia == NULL) { IPX_IFADDR_RLOCK(); ia = ipx_iaonnetof(&sipx->sipx_addr); + if (ia != NULL) + ifa_ref(&ia->ia_ifa); IPX_IFADDR_RUNLOCK(); } if (ia == NULL) { IPX_IFADDR_RLOCK(); ia = ipx_ifaddr; + if (ia != NULL) + ifa_ref(&ia->ia_ifa); IPX_IFADDR_RUNLOCK(); } if (ia == NULL) return (EADDRNOTAVAIL); } ipxp->ipxp_laddr.x_host = satoipx_addr(ia->ia_addr).x_host; + ifa_free(&ia->ia_ifa); } if (ipx_pcblookup(&sipx->sipx_addr, ipxp->ipxp_lport, 0)) return (EADDRINUSE); |