Use queue(9) instead of hand-crafted link lists for the global IPX

address list (ipx_ifaddr -> ipx_ifaddrhead), and generally adopt the
naming and usage conventions found in netinet.

MFC after:	6 weeks
This commit is contained in:
Robert Watson 2009-06-24 20:57:50 +00:00
parent 73591c462d
commit 574644abac
5 changed files with 53 additions and 51 deletions

View File

@ -85,7 +85,7 @@ __FBSDID("$FreeBSD$");
* The IPX-layer address list is protected by ipx_ifaddr_rw.
*/
struct rwlock ipx_ifaddr_rw;
struct ipx_ifaddr *ipx_ifaddr;
struct ipx_ifaddrhead ipx_ifaddrhead;
static void ipx_ifscrub(struct ifnet *ifp, struct ipx_ifaddr *ia);
static int ipx_ifinit(struct ifnet *ifp, struct ipx_ifaddr *ia,
@ -100,7 +100,7 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
{
struct ifreq *ifr = (struct ifreq *)data;
struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data;
struct ipx_ifaddr *ia, *ia_temp, *oia;
struct ipx_ifaddr *ia;
struct ifaddr *ifa;
int dstIsNew, hostIsNew;
int error, priv;
@ -112,9 +112,10 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
return (EADDRNOTAVAIL);
IPX_IFADDR_RLOCK();
for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next)
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if (ia->ia_ifp == ifp)
break;
}
if (ia != NULL)
ifa_ref(&ia->ia_ifa);
IPX_IFADDR_RUNLOCK();
@ -164,7 +165,9 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
IPX_IFADDR_RLOCK();
if (ifra->ifra_addr.sipx_family == AF_IPX) {
for (oia = ia; ia != NULL; ia = ia->ia_next) {
struct ipx_ifaddr *oia;
for (oia = ia; ia; ia = TAILQ_NEXT(ia, ia_link)) {
if (ia->ia_ifp == ifp &&
ipx_neteq(ia->ia_addr.sipx_addr,
ifra->ifra_addr.sipx_addr))
@ -205,15 +208,9 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
ia->ia_broadaddr.sipx_addr.x_host =
ipx_broadhost;
}
ifa_ref(&ia->ia_ifa); /* ipx_ifaddr */
ifa_ref(&ia->ia_ifa); /* ipx_ifaddrhead */
IPX_IFADDR_WLOCK();
if ((ia_temp = ipx_ifaddr) != NULL) {
for (; ia_temp->ia_next != NULL;
ia_temp = ia_temp->ia_next)
;
ia_temp->ia_next = ia;
} else
ipx_ifaddr = ia;
TAILQ_INSERT_TAIL(&ipx_ifaddrhead, ia, ia_link);
IPX_IFADDR_WUNLOCK();
ifa_ref(&ia->ia_ifa); /* if_addrhead */
@ -262,18 +259,9 @@ ipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
ifa_free(ifa); /* if_addrhead */
IPX_IFADDR_WLOCK();
if (ia == (ia_temp = ipx_ifaddr)) {
ipx_ifaddr = ia->ia_next;
} else {
while (ia_temp->ia_next && (ia_temp->ia_next != ia))
ia_temp = ia_temp->ia_next;
if (ia_temp->ia_next)
ia_temp->ia_next = ia->ia_next;
else
panic("Didn't unlink ipxifadr from list\n");
}
TAILQ_REMOVE(&ipx_ifaddrhead, ia, ia_link);
IPX_IFADDR_WUNLOCK();
ifa_free(&ia->ia_ifa); /* ipx_ifaddr */
ifa_free(&ia->ia_ifa); /* ipx_ifaddrhead */
goto out;
case SIOCAIFADDR:
@ -395,7 +383,7 @@ ipx_iaonnetof(struct ipx_addr *dst)
IPX_IFADDR_LOCK_ASSERT();
for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next) {
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if ((ifp = ia->ia_ifp) != NULL) {
if (ifp->if_flags & IFF_POINTOPOINT) {
compare = &satoipx_addr(ia->ia_dstaddr);

View File

@ -75,7 +75,7 @@ struct ipx_ifaddr {
struct ifaddr ia_ifa; /* protocol-independent info */
#define ia_ifp ia_ifa.ifa_ifp
#define ia_flags ia_ifa.ifa_flags
struct ipx_ifaddr *ia_next; /* next in list of ipx addresses */
TAILQ_ENTRY(ipx_ifaddr) ia_link; /* list of IPv6 addresses */
struct sockaddr_ipx ia_addr; /* reserve space for my address */
struct sockaddr_ipx ia_dstaddr; /* space for my broadcast address */
#define ia_broadaddr ia_dstaddr
@ -88,6 +88,12 @@ struct ipx_aliasreq {
struct sockaddr_ipx ifra_broadaddr;
#define ifra_dstaddr ifra_broadaddr
};
/*
* List of ipx_ifaddr's.
*/
TAILQ_HEAD(ipx_ifaddrhead, ipx_ifaddr);
/*
* Given a pointer to an ipx_ifaddr (ifaddr),
* return a pointer to the addr as a sockadd_ipx.
@ -106,7 +112,7 @@ struct ipx_aliasreq {
#ifdef _KERNEL
extern struct rwlock ipx_ifaddr_rw;
extern struct ipx_ifaddr *ipx_ifaddr;
extern struct ipx_ifaddrhead ipx_ifaddrhead;
#define IPX_IFADDR_LOCK_INIT() rw_init(&ipx_ifaddr_rw, "ipx_ifaddr_rw")
#define IPX_IFADDR_LOCK_ASSERT() rw_assert(&ipx_ifaddr_rw, RA_LOCKED)

View File

@ -1,7 +1,7 @@
/*-
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California.
* Copyright (c) 2004-2005 Robert N. M. Watson
* Copyright (c) 2004-2009 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -146,6 +146,7 @@ ipx_init(void)
LIST_INIT(&ipxpcb_list);
LIST_INIT(&ipxrawpcb_list);
TAILQ_INIT(&ipx_ifaddrhead);
IPX_LIST_LOCK_INIT();
IPX_IFADDR_LOCK_INIT();
@ -175,7 +176,7 @@ ipxintr(struct mbuf *m)
* If no IPX addresses have been set yet but the interfaces
* are receiving, can't do anything with incoming packets yet.
*/
if (ipx_ifaddr == NULL) {
if (TAILQ_EMPTY(&ipx_ifaddrhead)) {
m_freem(m);
return;
}
@ -257,13 +258,14 @@ ipxintr(struct mbuf *m)
* received from, treat it as ours.
*/
IPX_IFADDR_RLOCK();
for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next)
if((ia->ia_ifa.ifa_ifp == m->m_pkthdr.rcvif) &&
ipx_neteq(ia->ia_addr.sipx_addr,
ipx->ipx_dna)) {
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if ((ia->ia_ifa.ifa_ifp == m->m_pkthdr.rcvif)
&& ipx_neteq(ia->ia_addr.sipx_addr,
ipx->ipx_dna)) {
IPX_IFADDR_RUNLOCK();
goto ours;
}
}
IPX_IFADDR_RUNLOCK();
/*
@ -286,11 +288,12 @@ ipxintr(struct mbuf *m)
*/
} else {
IPX_IFADDR_RLOCK();
for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next)
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if (ipx_hosteq(ipx->ipx_dna, ia->ia_addr.sipx_addr) &&
(ipx_neteq(ipx->ipx_dna, ia->ia_addr.sipx_addr) ||
ipx_neteqnn(ipx->ipx_dna.x_net, ipx_zeronet)))
break;
}
IPX_IFADDR_RUNLOCK();
if (ia == NULL) {
ipx_forward(m);

View File

@ -179,7 +179,7 @@ ipx_output_type20(struct mbuf *m)
{
struct ipx *ipx;
union ipx_net *nbnet;
struct ipx_ifaddr *ia, *tia = NULL;
struct ipx_ifaddr *ia, *tia;
int error = 0;
struct mbuf *m1;
int i;
@ -204,19 +204,21 @@ ipx_output_type20(struct mbuf *m)
/*
* Now see if we have already seen this.
*/
tia = NULL;
IPX_IFADDR_RLOCK();
for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next)
if(ia->ia_ifa.ifa_ifp == m->m_pkthdr.rcvif) {
if(tia == NULL)
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if (ia->ia_ifa.ifa_ifp == m->m_pkthdr.rcvif) {
if (tia == NULL)
tia = ia;
for (i=0;i<ipx->ipx_tc;i++,nbnet++)
if(ipx_neteqnn(ia->ia_addr.sipx_addr.x_net,
*nbnet)) {
for (i=0; i < ipx->ipx_tc; i++, nbnet++) {
if (ipx_neteqnn(ia->ia_addr.sipx_addr.x_net,
*nbnet)) {
IPX_IFADDR_RUNLOCK();
goto bad;
}
}
}
}
/*
* Don't route the packet if the interface where it come from
@ -250,12 +252,12 @@ ipx_output_type20(struct mbuf *m)
dst.sipx_len = 12;
dst.sipx_addr.x_host = ipx_broadhost;
for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next)
if(ia->ia_ifa.ifa_ifp != m->m_pkthdr.rcvif) {
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if (ia->ia_ifa.ifa_ifp != m->m_pkthdr.rcvif) {
nbnet = (union ipx_net *)(ipx + 1);
for (i=0;i<ipx->ipx_tc;i++,nbnet++)
if(ipx_neteqnn(ia->ia_addr.sipx_addr.x_net,
*nbnet))
for (i=0; i < ipx->ipx_tc; i++, nbnet++)
if (ipx_neteqnn(ia->ia_addr.sipx_addr.x_net,
*nbnet))
goto skip_this;
/*
@ -276,6 +278,7 @@ ipx_output_type20(struct mbuf *m)
}
skip_this: ;
}
}
IPX_IFADDR_RUNLOCK();
bad:

View File

@ -1,7 +1,7 @@
/*-
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California.
* Copyright (c) 2004-2006 Robert N. M. Watson
* Copyright (c) 2004-2009 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -223,11 +223,12 @@ 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)
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if (ia->ia_ifp == ifp) {
ifa_ref(&ia->ia_ifa);
break;
}
}
IPX_IFADDR_RUNLOCK();
}
if (ia == NULL) {
@ -245,7 +246,7 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td)
}
if (ia == NULL) {
IPX_IFADDR_RLOCK();
ia = ipx_ifaddr;
ia = TAILQ_FIRST(&ipx_ifaddrhead);
if (ia != NULL)
ifa_ref(&ia->ia_ifa);
IPX_IFADDR_RUNLOCK();
@ -269,11 +270,12 @@ 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)
TAILQ_FOREACH(ia, &ipx_ifaddrhead, ia_link) {
if (ia->ia_ifp == ifp) {
ifa_ref(&ia->ia_ifa);
break;
}
}
IPX_IFADDR_RUNLOCK();
}
if (ia == NULL) {
@ -291,7 +293,7 @@ ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td)
}
if (ia == NULL) {
IPX_IFADDR_RLOCK();
ia = ipx_ifaddr;
ia = TAILQ_FIRST(&ipx_ifaddrhead);
if (ia != NULL)
ifa_ref(&ia->ia_ifa);
IPX_IFADDR_RUNLOCK();