summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2010-01-13 02:29:52 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2010-01-13 02:29:52 +0000
commitb4cd1361312466f832bc9d56594026e48ec3655b (patch)
tree64c3a6baf794db8095a190ecf61114821a13e5f6 /sys/net
parentc170799ceb503222b1020d85d656017a45011d46 (diff)
make ifa_ifwithaddr use the shiny new ifaddr RB tree instead of traversing
the list of all interfaces and traversing the list of all addresses on each interface. if bugs show up with addressing this is the #1 backout candidate, something i missed might fuck with ifaddrs behind our back, although i looked & tested hard. 10x to naddy for inet6 testing. ok theo ryan dlg
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c34
1 files changed, 12 insertions, 22 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 2e9ab953721..dfa550cd014 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.206 2010/01/13 02:26:49 henning Exp $ */
+/* $OpenBSD: if.c,v 1.207 2010/01/13 02:29:51 henning Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -875,32 +875,22 @@ if_congestion_clear(void *arg)
struct ifaddr *
ifa_ifwithaddr(struct sockaddr *addr, u_int rdomain)
{
- struct ifnet *ifp;
- struct ifaddr *ifa;
+ struct ifaddr_item *ifai, key;
-#define equal(a1, a2) \
- (bcmp((caddr_t)(a1), (caddr_t)(a2), \
- ((struct sockaddr *)(a1))->sa_len) == 0)
+ bzero(&key, sizeof(key));
+ key.ifai_addr = addr;
+ key.ifai_rdomain = rtable_l2(rdomain);
- rdomain = rtable_l2(rdomain);
- TAILQ_FOREACH(ifp, &ifnet, if_list) {
- if (ifp->if_rdomain != rdomain)
- continue;
- TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
- if (ifa->ifa_addr->sa_family != addr->sa_family)
- continue;
- if (equal(addr, ifa->ifa_addr))
- return (ifa);
- if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
- /* IP6 doesn't have broadcast */
- ifa->ifa_broadaddr->sa_len != 0 &&
- equal(ifa->ifa_broadaddr, addr))
- return (ifa);
- }
- }
+ ifai = RB_FIND(ifaddr_items, &ifaddr_items, &key);
+ if (ifai)
+ return (ifai->ifai_ifa);
return (NULL);
}
+#define equal(a1, a2) \
+ (bcmp((caddr_t)(a1), (caddr_t)(a2), \
+ ((struct sockaddr *)(a1))->sa_len) == 0)
+
/*
* Locate the point to point interface with a given destination address.
*/