summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authortls <tls@NetBSD.org>1998-02-13 18:21:38 +0000
committertls <tls@NetBSD.org>1998-02-13 18:21:38 +0000
commitc9934a9084072c26dce46dec672ca96af20b1b4e (patch)
treea8301bd074fd52744bde22806c5b526d3aac893c /sys
parent561bc2f4adcfc785278fc189f1a5ef95ff941871 (diff)
Change list of interface IP addresses to a hash. Improves performance on hosts with a large number of IP addresses significantly.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/if_arp.c33
-rw-r--r--sys/netinet/igmp.c8
-rw-r--r--sys/netinet/in.c23
-rw-r--r--sys/netinet/in_pcb.c52
-rw-r--r--sys/netinet/in_var.h53
-rw-r--r--sys/netinet/ip_icmp.c31
-rw-r--r--sys/netinet/ip_input.c32
-rw-r--r--sys/netinet/ip_output.c11
8 files changed, 152 insertions, 91 deletions
diff --git a/sys/netinet/if_arp.c b/sys/netinet/if_arp.c
index be09d1a24cf..ed8cbd91ed1 100644
--- a/sys/netinet/if_arp.c
+++ b/sys/netinet/if_arp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_arp.c,v 1.43 1998/01/05 10:31:44 thorpej Exp $ */
+/* $NetBSD: if_arp.c,v 1.44 1998/02/13 18:21:38 tls Exp $ */
/*
* Copyright (c) 1982, 1986, 1988, 1993
@@ -467,7 +467,7 @@ in_arpinput(m)
register struct ifnet *ifp = m->m_pkthdr.rcvif;
register struct llinfo_arp *la = 0;
register struct rtentry *rt;
- struct in_ifaddr *ia, *maybe_ia = 0;
+ struct in_ifaddr *ia;
struct sockaddr_dl *sdl;
struct sockaddr sa;
struct in_addr isaddr, itaddr, myaddr;
@@ -488,24 +488,27 @@ in_arpinput(m)
/*
* If the source IP address is zero, this is most likely a
- * confused host trying to use IP address zero. (Windoze?)
- * XXX: Should we bother trying to reply to these?
+ * confused host trying to use IP address zero. (Windoze?)
+ * XXX: Should we bother trying to reply to these?
*/
if (in_nullhost(isaddr))
goto out;
- /* Search for a matching interface address. */
- for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
- if (ia->ia_ifp == ifp) {
- maybe_ia = ia;
- if (in_hosteq(itaddr, ia->ia_addr.sin_addr) ||
- in_hosteq(isaddr, ia->ia_addr.sin_addr))
- break;
- }
- if (maybe_ia == 0)
- goto out;
+ /*
+ * Search for a matching interface address
+ * or any address on the interface to use
+ * as a dummy address in the rest of this function
+ */
+ INADDR_TO_IA(itaddr, ia);
+ if (ia == NULL) {
+ INADDR_TO_IA(isaddr, ia);
+ if (ia == NULL) {
+ IFP_TO_IA(ifp, ia);
+ if (ia == NULL) goto out;
+ }
+ }
+ myaddr = ia->ia_addr.sin_addr;
- myaddr = ia ? ia->ia_addr.sin_addr : maybe_ia->ia_addr.sin_addr;
if (!bcmp((caddr_t)ar_sha(ah), LLADDR(ifp->if_sadl),
ifp->if_data.ifi_addrlen))
goto out; /* it's from me, ignore it. */
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index 73a5fa049ae..b0528a6bdf0 100644
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: igmp.c,v 1.17 1998/01/12 03:02:48 scottr Exp $ */
+/* $NetBSD: igmp.c,v 1.18 1998/02/13 18:21:40 tls Exp $ */
/*
* Internet Group Management Protocol (IGMP) routines.
@@ -266,7 +266,7 @@ igmp_input(m, va_alist)
* determine the arrival interface of an incoming packet.
*/
if ((ip->ip_src.s_addr & IN_CLASSA_NET) == 0) {
- IFP_TO_IA(ifp, ia);
+ IFP_TO_IA(ifp, ia); /* XXX */
if (ia)
ip->ip_src.s_addr = ia->ia_subnet;
}
@@ -305,7 +305,7 @@ igmp_input(m, va_alist)
* leave requires knowing that we are the only member of a
* group.
*/
- IFP_TO_IA(ifp, ia);
+ IFP_TO_IA(ifp, ia); /* XXX */
if (ia && in_hosteq(ip->ip_src, ia->ia_addr.sin_addr))
break;
#endif
@@ -333,7 +333,7 @@ igmp_input(m, va_alist)
*/
if ((ip->ip_src.s_addr & IN_CLASSA_NET) == 0) {
#ifndef MROUTING
- IFP_TO_IA(ifp, ia);
+ IFP_TO_IA(ifp, ia); /* XXX */
#endif
if (ia)
ip->ip_src.s_addr = ia->ia_subnet;
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index d926425fa38..99dc7f3bfb9 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in.c,v 1.37 1998/01/12 03:02:49 scottr Exp $ */
+/* $NetBSD: in.c,v 1.38 1998/02/13 18:21:40 tls Exp $ */
/*
* Copyright (c) 1982, 1986, 1991, 1993
@@ -150,7 +150,7 @@ in_setmaxmtu()
if ((ifp->if_flags & (IFF_UP|IFF_LOOPBACK)) != IFF_UP)
continue;
if (ifp->if_mtu > maxmtu)
- maxmtu = ifp->if_mtu;
+ maxmtu = ifp->if_mtu;
}
if (maxmtu)
in_maxmtu = maxmtu;
@@ -181,18 +181,18 @@ in_control(so, cmd, data, ifp, p)
* Find address for this interface, if it exists.
*/
if (ifp)
- for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
- if (ia->ia_ifp == ifp)
- break;
+ IFP_TO_IA(ifp, ia);
switch (cmd) {
case SIOCAIFADDR:
case SIOCDIFADDR:
if (ifra->ifra_addr.sin_family == AF_INET)
- for (; ia != 0; ia = ia->ia_list.tqe_next) {
+ for (ia = IN_IFADDR_HASH(ifra->ifra_addr.sin_addr.s_addr).lh_first;
+ ia != 0; ia = ia->ia_hash.le_next) {
if (ia->ia_ifp == ifp &&
- in_hosteq(ia->ia_addr.sin_addr, ifra->ifra_addr.sin_addr))
+ in_hosteq(ia->ia_addr.sin_addr,
+ ifra->ifra_addr.sin_addr))
break;
}
if (cmd == SIOCDIFADDR && ia == 0)
@@ -330,6 +330,7 @@ in_control(so, cmd, data, ifp, p)
case SIOCDIFADDR:
in_ifscrub(ifp, ia);
+ LIST_REMOVE(ia, ia_hash);
TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
IFAFREE((&ia->ia_ifa));
@@ -389,7 +390,11 @@ in_ifinit(ifp, ia, sin, scrub)
* Set up new addresses.
*/
oldaddr = ia->ia_addr;
+ if (ia->ia_addr.sin_family == AF_INET)
+ LIST_REMOVE(ia, ia_hash);
ia->ia_addr = *sin;
+ LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
+
/*
* Give the interface a chance to initialize
* if this is its first address,
@@ -460,7 +465,11 @@ in_ifinit(ifp, ia, sin, scrub)
return (error);
bad:
splx(s);
+ LIST_REMOVE(ia, ia_hash);
ia->ia_addr = oldaddr;
+ if (ia->ia_addr.sin_family == AF_INET)
+ LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
+ ia, ia_hash);
return (error);
}
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index eb239d682d6..28439876133 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in_pcb.c,v 1.48 1998/02/07 02:44:55 chs Exp $ */
+/* $NetBSD: in_pcb.c,v 1.49 1998/02/13 18:21:41 tls Exp $ */
/*
* Copyright (c) 1982, 1986, 1991, 1993, 1995
@@ -254,16 +254,21 @@ in_pcbconnect(v, nam)
if (in_ifaddr.tqh_first != 0) {
/*
* If the destination address is INADDR_ANY,
- * use the primary local address.
+ * use any local address (likely loopback).
* If the supplied address is INADDR_BROADCAST,
- * and the primary interface supports broadcast,
- * choose the broadcast address for that interface.
+ * use the broadcast address of an interface
+ * which supports broadcast. (loopback does not)
*/
+
if (in_nullhost(sin->sin_addr))
- sin->sin_addr = in_ifaddr.tqh_first->ia_addr.sin_addr;
- else if (sin->sin_addr.s_addr == INADDR_BROADCAST &&
- (in_ifaddr.tqh_first->ia_ifp->if_flags & IFF_BROADCAST))
- sin->sin_addr = in_ifaddr.tqh_first->ia_broadaddr.sin_addr;
+ sin->sin_addr = in_ifaddr.tqh_first->ia_broadaddr.sin_addr;
+ else if (sin->sin_addr.s_addr == INADDR_BROADCAST)
+ for (ia = in_ifaddr.tqh_first; ia != NULL;
+ ia = ia->ia_list.tqe_next)
+ if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
+ sin->sin_addr = ia->ia_broadaddr.sin_addr;
+ break;
+ }
}
/*
* If we haven't bound which network number to use as ours,
@@ -307,19 +312,25 @@ in_pcbconnect(v, nam)
* corresponding to the outgoing interface
* unless it is the loopback (in case a route
* to our address on another net goes to loopback).
+ *
+ * XXX Is this still true? Do we care?
*/
if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
ia = ifatoia(ro->ro_rt->rt_ifa);
if (ia == 0) {
- u_int16_t fport = sin->sin_port;
-
- sin->sin_port = 0;
- ia = ifatoia(ifa_ifwithladdr(sintosa(sin)));
- sin->sin_port = fport;
- if (ia == 0)
- ia = in_ifaddr.tqh_first;
- if (ia == 0)
- return (EADDRNOTAVAIL);
+ u_int16_t fport = sin->sin_port;
+
+ sin->sin_port = 0;
+ ia = ifatoia(ifa_ifwithladdr(sintosa(sin)));
+ sin->sin_port = fport;
+ if (ia == 0)
+ /* Find 1st non-loopback AF_INET address */
+ for (ia = in_ifaddr.tqh_first ; ia != NULL ;
+ ia = ia->ia_list.tqe_next)
+ if (!(ia->ia_ifp->if_flags & IFF_LOOPBACK))
+ break;
+ if (ia == 0)
+ return (EADDRNOTAVAIL);
}
/*
* If the destination address is multicast and an outgoing
@@ -334,10 +345,7 @@ in_pcbconnect(v, nam)
imo = inp->inp_moptions;
if (imo->imo_multicast_ifp != NULL) {
ifp = imo->imo_multicast_ifp;
- for (ia = in_ifaddr.tqh_first; ia != 0;
- ia = ia->ia_list.tqe_next)
- if (ia->ia_ifp == ifp)
- break;
+ IFP_TO_IA(ifp, ia); /* XXX */
if (ia == 0)
return (EADDRNOTAVAIL);
}
@@ -550,7 +558,7 @@ in_rtchange(inp, errno)
* output is attempted.
*/
}
- /* SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */
+ /* XXX SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */
}
struct inpcb *
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 4f954f699bd..3552dffa6ff 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: in_var.h,v 1.20 1998/02/10 01:26:42 perry Exp $ */
+/* $NetBSD: in_var.h,v 1.21 1998/02/13 18:21:42 tls Exp $ */
/*
* Copyright (c) 1985, 1986, 1993
@@ -56,6 +56,7 @@ struct in_ifaddr {
u_int32_t ia_subnet; /* subnet number, including net */
u_int32_t ia_subnetmask; /* mask of subnet part */
struct in_addr ia_netbroadcast; /* to recognize net broadcasts */
+ LIST_ENTRY(in_ifaddr) ia_hash; /* entry in bucket of inet addresses */
TAILQ_ENTRY(in_ifaddr) ia_list; /* list of internet addresses */
struct sockaddr_in ia_addr; /* reserve space for interface name */
struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
@@ -79,13 +80,39 @@ struct in_aliasreq {
#ifdef _KERNEL
-TAILQ_HEAD(in_ifaddrhead, in_ifaddr);
-extern struct in_ifaddrhead in_ifaddr;
+#ifndef IN_IFADDR_HASH_SIZE
+#define IN_IFADDR_HASH_SIZE 293
+#endif
+
+#define IN_IFADDR_HASH(x) in_ifaddrhashtbl[(u_long)(x) % IN_IFADDR_HASH_SIZE]
+
+u_long in_ifaddrhash; /* size of hash table - 1 */
+int in_ifaddrentries; /* total number of addrs */
+LIST_HEAD(in_ifaddrhashhead, in_ifaddr); /* Type of the hash head */
+TAILQ_HEAD(in_ifaddrhead, in_ifaddr); /* Type of the list head */
+
+extern struct in_ifaddrhashhead *in_ifaddrhashtbl; /* Hash table head */
+extern struct in_ifaddrhead in_ifaddr; /* List head (in ip_input) */
+
extern struct ifqueue ipintrq; /* ip packet input queue */
void in_socktrim __P((struct sockaddr_in *));
/*
+ * Macro for finding whether an internet address (in_addr) belongs to one
+ * of our interfaces (in_ifaddr). NULL if the address isn't ours.
+ */
+#define INADDR_TO_IA(addr, ia) \
+ /* struct in_addr addr; */ \
+ /* struct in_ifaddr *ia; */ \
+{ \
+ for (ia = IN_IFADDR_HASH((addr).s_addr).lh_first; \
+ ia != NULL && !in_hosteq(ia->ia_addr.sin_addr, (addr)); \
+ ia = ia->ia_hash.le_next) \
+ continue; \
+}
+
+/*
* Macro for finding the interface (ifnet structure) corresponding to one
* of our IP addresses.
*/
@@ -95,25 +122,25 @@ void in_socktrim __P((struct sockaddr_in *));
{ \
register struct in_ifaddr *ia; \
\
- for (ia = in_ifaddr.tqh_first; \
- ia != NULL && ia->ia_addr.sin_addr.s_addr != (addr).s_addr; \
- ia = ia->ia_list.tqe_next) \
- continue; \
+ INADDR_TO_IA(addr, ia); \
(ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
}
/*
- * Macro for finding the internet address structure (in_ifaddr) corresponding
+ * Macro for finding an internet address structure (in_ifaddr) corresponding
* to a given interface (ifnet structure).
*/
#define IFP_TO_IA(ifp, ia) \
/* struct ifnet *ifp; */ \
/* struct in_ifaddr *ia; */ \
{ \
- for ((ia) = in_ifaddr.tqh_first; \
- (ia) != NULL && (ia)->ia_ifp != (ifp); \
- (ia) = (ia)->ia_list.tqe_next) \
+ register struct ifaddr *ifa; \
+\
+ for (ifa = (ifp)->if_addrlist.tqh_first; \
+ ifa != NULL && ifa->ifa_addr->sa_family != AF_INET; \
+ ifa = ifa->ifa_list.tqe_next) \
continue; \
+ (ia) = ifatoia(ifa); \
}
#endif
@@ -165,12 +192,12 @@ struct in_multistep {
{ \
register struct in_ifaddr *ia; \
\
- IFP_TO_IA((ifp), ia); \
+ IFP_TO_IA((ifp), ia); /* multicast */ \
if (ia == NULL) \
(inm) = NULL; \
else \
for ((inm) = ia->ia_multiaddrs.lh_first; \
- (inm) != NULL && (inm)->inm_addr.s_addr != (addr).s_addr; \
+ (inm) != NULL && !in_hosteq((inm)->inm_addr, (addr)); \
(inm) = inm->inm_list.le_next) \
continue; \
}
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 926795a391a..63ab5ec20db 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_icmp.c,v 1.26 1997/10/29 05:28:44 kml Exp $ */
+/* $NetBSD: ip_icmp.c,v 1.27 1998/02/13 18:21:43 tls Exp $ */
/*
* Copyright (c) 1982, 1986, 1988, 1993
@@ -435,6 +435,7 @@ icmp_reflect(m)
{
register struct ip *ip = mtod(m, struct ip *);
register struct in_ifaddr *ia;
+ register struct ifaddr *ifa;
struct in_addr t;
struct mbuf *opts = 0;
int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
@@ -453,23 +454,35 @@ icmp_reflect(m)
* or anonymous), use the address which corresponds
* to the incoming interface.
*/
- for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) {
- if (in_hosteq(t, ia->ia_addr.sin_addr))
- break;
- if ((ia->ia_ifp->if_flags & IFF_BROADCAST) &&
- in_hosteq(t, ia->ia_broadaddr.sin_addr))
- break;
+ INADDR_TO_IA(t, ia);
+ if (ia == NULL && (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST)) {
+ for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
+ ifa != NULL; ifa = ifa->ifa_list.tqe_next) {
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+ ia = ifatoia(ifa);
+ if (in_hosteq(t, ia->ia_broadaddr.sin_addr))
+ break;
+ }
}
+
icmpdst.sin_addr = t;
if (ia == (struct in_ifaddr *)0)
ia = ifatoia(ifaof_ifpforaddr(sintosa(&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.
+ * and was received on an interface with no IP address:
+ * We find the first AF_INET address on the first non-loopback
+ * interface.
*/
if (ia == (struct in_ifaddr *)0)
- ia = in_ifaddr.tqh_first;
+ for (ia = in_ifaddr.tqh_first; ia != NULL;
+ ia = ia->ia_list.tqe_next) {
+ if (ia->ia_ifp->if_flags & IFF_LOOPBACK)
+ continue;
+ break;
+ }
t = ia->ia_addr.sin_addr;
ip->ip_src = t;
ip->ip_ttl = MAXTTL;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 5e55aa6aa08..d009b4aace9 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_input.c,v 1.56 1998/01/28 02:36:10 thorpej Exp $ */
+/* $NetBSD: ip_input.c,v 1.57 1998/02/13 18:21:44 tls Exp $ */
/*
* Copyright (c) 1982, 1986, 1988, 1993
@@ -113,6 +113,7 @@ extern struct protosw inetsw[];
u_char ip_protox[IPPROTO_MAX];
int ipqmaxlen = IFQ_MAXLEN;
struct in_ifaddrhead in_ifaddr;
+struct in_ifaddrhashhead *in_ifaddrhashtbl;
struct ifqueue ipintrq;
/*
@@ -156,6 +157,8 @@ ip_init()
ip_id = time.tv_sec & 0xffff;
ipintrq.ifq_maxlen = ipqmaxlen;
TAILQ_INIT(&in_ifaddr);
+ in_ifaddrhashtbl =
+ hashinit(IN_IFADDR_HASH_SIZE, M_IFADDR, M_WAITOK, &in_ifaddrhash);
}
struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
@@ -172,6 +175,7 @@ ipintr()
register struct mbuf *m;
register struct ipq *fp;
register struct in_ifaddr *ia;
+ register struct ifaddr *ifa;
struct ipqent *ipqe;
int hlen = 0, mff, len, s;
#ifdef PFIL_HOOKS
@@ -281,12 +285,13 @@ next:
/*
* Check our list of addresses, to see if the packet is for us.
*/
- for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) {
- if (in_hosteq(ip->ip_dst, ia->ia_addr.sin_addr))
- goto ours;
- if (((ip_directedbcast == 0) || (ip_directedbcast &&
- ia->ia_ifp == m->m_pkthdr.rcvif)) &&
- (ia->ia_ifp->if_flags & IFF_BROADCAST)) {
+ INADDR_TO_IA(ip->ip_dst, ia);
+ if (ia != NULL) goto ours;
+ if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
+ for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
+ ifa != NULL; ifa = ifa->ifa_list.tqe_next) {
+ if (ifa->ifa_addr->sa_family != AF_INET) continue;
+ ia = ifatoia(ifa);
if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) ||
in_hosteq(ip->ip_dst, ia->ia_netbroadcast) ||
/*
@@ -296,14 +301,13 @@ next:
ip->ip_dst.s_addr == ia->ia_subnet ||
ip->ip_dst.s_addr == ia->ia_net)
goto ours;
+ /*
+ * An interface with IP address zero accepts
+ * all packets that arrive on that interface.
+ */
+ if (in_nullhost(ia->ia_addr.sin_addr))
+ goto ours;
}
- /*
- * An interface with IP address zero accepts
- * all packets that arrive on that interface.
- */
- if ((ia->ia_ifp == m->m_pkthdr.rcvif) &&
- in_nullhost(ia->ia_addr.sin_addr))
- goto ours;
}
if (IN_MULTICAST(ip->ip_dst.s_addr)) {
struct in_multi *inm;
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 0618d41770c..ca63a5fae4f 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_output.c,v 1.43 1998/02/13 10:23:49 kleink Exp $ */
+/* $NetBSD: ip_output.c,v 1.44 1998/02/13 18:21:45 tls Exp $ */
/*
* Copyright (c) 1982, 1986, 1988, 1990, 1993
@@ -211,17 +211,14 @@ ip_output(m0, va_alist)
goto bad;
}
/*
- * If source address not specified yet, use address
+ * If source address not specified yet, use an address
* of outgoing interface.
*/
if (in_nullhost(ip->ip_src)) {
register struct in_ifaddr *ia;
- for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next)
- if (ia->ia_ifp == ifp) {
- ip->ip_src = ia->ia_addr.sin_addr;
- break;
- }
+ IFP_TO_IA(ifp, ia);
+ ip->ip_src = ia->ia_addr.sin_addr;
}
IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);