diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2010-01-13 02:29:52 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2010-01-13 02:29:52 +0000 |
commit | b4cd1361312466f832bc9d56594026e48ec3655b (patch) | |
tree | 64c3a6baf794db8095a190ecf61114821a13e5f6 /sys/net | |
parent | c170799ceb503222b1020d85d656017a45011d46 (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.c | 34 |
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. */ |