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:
parent
4713c64cd8
commit
bba6f515e1
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user