summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-09-30 08:27:58 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-09-30 08:27:58 +0000
commit6147bafceacc66b432a63c0a5a405bfaef4fa7d8 (patch)
tree05a5cba2d0f3ac017264d2ce801e4223741de1c7
parentc85e35b29d77a3789af622d51c51ffa014c152fa (diff)
Stop using the RB-tree in ifa_ifwithaddr() and make it lookup over
all the per-interface lists of addresses. Teaks and ok bluhm@, ok kspillner@, claudio@
-rw-r--r--sys/net/if.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 3b54d7abaee..96b24d57bc8 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.300 2014/08/25 14:00:34 florian Exp $ */
+/* $OpenBSD: if.c,v 1.301 2014/09/30 08:27:57 mpi Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -837,29 +837,43 @@ if_congestion_clear(void *arg)
free(to, M_TEMP, 0);
}
+#define equal(a1, a2) \
+ (bcmp((caddr_t)(a1), (caddr_t)(a2), \
+ ((struct sockaddr *)(a1))->sa_len) == 0)
+
/*
* Locate an interface based on a complete address.
*/
-/*ARGSUSED*/
struct ifaddr *
ifa_ifwithaddr(struct sockaddr *addr, u_int rtableid)
{
- struct ifaddr_item *ifai, key;
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+ u_int rdomain;
- bzero(&key, sizeof(key));
- key.ifai_addr = addr;
- key.ifai_rdomain = rtable_l2(rtableid);
+ rdomain = rtable_l2(rtableid);
+ TAILQ_FOREACH(ifp, &ifnet, if_list) {
+ if (ifp->if_rdomain != rdomain)
+ continue;
- ifai = RB_FIND(ifaddr_items, &ifaddr_items, &key);
- if (ifai)
- return (ifai->ifai_ifa);
+ 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);
+
+ /* IPv6 doesn't have broadcast */
+ if ((ifp->if_flags & IFF_BROADCAST) &&
+ ifa->ifa_broadaddr &&
+ ifa->ifa_broadaddr->sa_len != 0 &&
+ equal(ifa->ifa_broadaddr, addr))
+ return (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.
*/