diff options
author | jlemon <jlemon@FreeBSD.org> | 2001-09-29 04:34:11 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2001-09-29 04:34:11 +0000 |
commit | 3164f24b5544749a98ad715c69b320a68f5e5316 (patch) | |
tree | 9043eb0a3862514449a171c6cb63e1c0ef78e293 /sys/netinet/in.c | |
parent | 17d77e934622c40b38b3ea7e9d9486bf6c67f15f (diff) | |
download | FreeBSD-src-3164f24b5544749a98ad715c69b320a68f5e5316.zip FreeBSD-src-3164f24b5544749a98ad715c69b320a68f5e5316.tar.gz |
Add a hash table that contains the list of internet addresses, and use
this in place of the in_ifaddr list when appropriate. This improves
performance on hosts which have a large number of IP aliases.
Diffstat (limited to 'sys/netinet/in.c')
-rw-r--r-- | sys/netinet/in.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index d56d28e..a6643df 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -193,6 +193,7 @@ in_control(so, cmd, data, ifp, td) register struct ifreq *ifr = (struct ifreq *)data; register struct in_ifaddr *ia = 0, *iap; register struct ifaddr *ifa; + struct in_addr dst; struct in_ifaddr *oia; struct in_aliasreq *ifra = (struct in_aliasreq *)data; struct sockaddr_in oldaddr; @@ -215,21 +216,25 @@ in_control(so, cmd, data, ifp, td) * Find address for this interface, if it exists. * * If an alias address was specified, find that one instead of - * the first one on the interface. + * the first one on the interface, if possible. */ - if (ifp) - TAILQ_FOREACH(iap, &in_ifaddrhead, ia_link) - if (iap->ia_ifp == ifp) { - if (((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr == - iap->ia_addr.sin_addr.s_addr) { + if (ifp) { + dst = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; + LIST_FOREACH(iap, INADDR_HASH(dst.s_addr), ia_hash) + if (iap->ia_ifp == ifp && + iap->ia_addr.sin_addr.s_addr == dst.s_addr) { + ia = iap; + break; + } + if (ia == NULL) + TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + iap = ifatoia(ifa); + if (iap->ia_addr.sin_family == AF_INET) { ia = iap; break; - } else if (ia == NULL) { - ia = iap; - if (ifr->ifr_addr.sa_family != AF_INET) - break; } } + } switch (cmd) { @@ -423,9 +428,9 @@ in_control(so, cmd, data, ifp, td) ifa = &ia->ia_ifa; TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); - oia = ia; - TAILQ_REMOVE(&in_ifaddrhead, oia, ia_link); - IFAFREE(&oia->ia_ifa); + TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link); + LIST_REMOVE(ia, ia_hash); + IFAFREE(&ia->ia_ifa); splx(s); break; @@ -650,6 +655,7 @@ in_ifinit(ifp, ia, sin, scrub) oldaddr = ia->ia_addr; ia->ia_addr = *sin; + LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash); /* * Give the interface a chance to initialize * if this is its first address, |