summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in.c
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2001-09-29 04:34:11 +0000
committerjlemon <jlemon@FreeBSD.org>2001-09-29 04:34:11 +0000
commit3164f24b5544749a98ad715c69b320a68f5e5316 (patch)
tree9043eb0a3862514449a171c6cb63e1c0ef78e293 /sys/netinet/in.c
parent17d77e934622c40b38b3ea7e9d9486bf6c67f15f (diff)
downloadFreeBSD-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.c32
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,
OpenPOWER on IntegriCloud