summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_icmp.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/ip_icmp.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/ip_icmp.c')
-rw-r--r--sys/netinet/ip_icmp.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 5664516..f2071af 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -461,7 +461,6 @@ icmp_input(m, off)
goto reflect;
case ICMP_MASKREQ:
-#define satosin(sa) ((struct sockaddr_in *)(sa))
if (icmpmaskrepl == 0)
break;
/*
@@ -584,8 +583,9 @@ static void
icmp_reflect(m)
struct mbuf *m;
{
- register struct ip *ip = mtod(m, struct ip *);
- register struct in_ifaddr *ia;
+ struct ip *ip = mtod(m, struct ip *);
+ struct ifaddr *ifa;
+ struct in_ifaddr *ia;
struct in_addr t;
struct mbuf *opts = 0;
int optlen = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof(struct ip);
@@ -604,23 +604,30 @@ icmp_reflect(m)
* or anonymous), use the address which corresponds
* to the incoming interface.
*/
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
+ LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash)
if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr)
- break;
- if (ia->ia_ifp && (ia->ia_ifp->if_flags & IFF_BROADCAST) &&
- t.s_addr == satosin(&ia->ia_broadaddr)->sin_addr.s_addr)
- break;
- }
+ goto match;
+ if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
+ TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+ ia = ifatoia(ifa);
+ if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==
+ t.s_addr)
+ goto match;
+ }
+ }
+ KASSERT(m->m_pkthdr.rcvif != NULL, ("icmp_reflect: NULL rcvif"));
icmpdst.sin_addr = t;
- if ((ia == (struct in_ifaddr *)0) && m->m_pkthdr.rcvif)
- ia = (struct in_ifaddr *)ifaof_ifpforaddr(
- (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);
+ ia = (struct in_ifaddr *)ifaof_ifpforaddr(
+ (struct sockaddr *)&icmpdst, m->m_pkthdr.rcvif);
/*
* The following happens if the packet was not addressed to us,
* and was received on an interface with no IP address.
*/
- if (ia == (struct in_ifaddr *)0)
+ if (ia == NULL)
ia = TAILQ_FIRST(&in_ifaddrhead);
+match:
t = IA_SIN(ia)->sin_addr;
ip->ip_src = t;
ip->ip_ttl = ip_defttl;
OpenPOWER on IntegriCloud