diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2010-11-17 19:34:50 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2010-11-17 19:34:50 +0000 |
commit | e47e2ee1b2f723ee7e12b626c2eeb0e76036c170 (patch) | |
tree | 94b0f98fc923d241e6a12d157149770919dc01f6 /sys/net/if.c | |
parent | fba69b74bcc33f33bfb568967517a2990fa781bd (diff) |
maintain an RB tree of ifaddrs in the system (addresses and broadcast addrs,
the latter is also the dest addr on P2P interfaces) for faster lookups in
the future. walking the linked list of all interfaces in the system to walk
the linked list of addresses on each of them isn't particularily fast,
especially with many interfaces and addresses.
written at n2k10 in australia in january, but had to be backed
out. the offenders have been fixed:
-ipvshit rtsol code calling these functions in interrupt context
(surprised this hasn't caused more havoc)
-various places in the stack added empty ifaddr structs, filling them in later
-sloppy recycling of ifaddrs in some places
finished at j2k10 in japan in september
tested by many, ok sthen krw dlg claudio
Diffstat (limited to 'sys/net/if.c')
-rw-r--r-- | sys/net/if.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 4dfccedc99c..a433da017e2 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.227 2010/11/17 18:51:57 henning Exp $ */ +/* $OpenBSD: if.c,v 1.228 2010/11/17 19:34:49 henning Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -2184,18 +2184,26 @@ ifa_add(struct ifnet *ifp, struct ifaddr *ifa) TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list); else TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list); + ifa_item_insert(ifa->ifa_addr, ifa, ifp); + if (ifp->if_flags & IFF_BROADCAST && ifa->ifa_broadaddr) + ifa_item_insert(ifa->ifa_broadaddr, ifa, ifp); } void ifa_del(struct ifnet *ifp, struct ifaddr *ifa) { TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); + ifa_item_remove(ifa->ifa_addr, ifa, ifp); + if (ifp->if_flags & IFF_BROADCAST && ifa->ifa_broadaddr) + ifa_item_remove(ifa->ifa_broadaddr, ifa, ifp); } void ifa_update_broadaddr(struct ifnet *ifp, struct ifaddr *ifa, struct sockaddr *sa) { + ifa_item_remove(ifa->ifa_broadaddr, ifa, ifp); ifa->ifa_broadaddr = sa; + ifa_item_insert(ifa->ifa_broadaddr, ifa, ifp); } int |