I received a fair number of positive test reports and would like to commit this, aka looking for oks.
* Henning Brauer <[email protected]> [2010-09-28 11:48]: > hello? > > * Henning Brauer <[email protected]> [2010-09-24 10:35]: > > I'd really like more and heacy testing on this. has the potential for > > a great speedup on boxes with many IPs. > > > > * Henning Brauer <[email protected]> [2010-09-23 13:51]: > > > oups, one superfluous check forgotten to remove. > > > > > > note to self: in main tree on anakin (ryan sez it's the next level of > > > krautcomputing) > > > > > > Index: net/if.c > > > =================================================================== > > > RCS file: /cvs/src/sys/net/if.c,v > > > retrieving revision 1.225 > > > diff -u -p -r1.225 if.c > > > --- net/if.c 27 Aug 2010 17:08:01 -0000 1.225 > > > +++ net/if.c 23 Sep 2010 11:43:14 -0000 > > > @@ -157,6 +157,7 @@ int if_group_egress_build(void); > > > int ifai_cmp(struct ifaddr_item *, struct ifaddr_item *); > > > void ifa_item_insert(struct sockaddr *, struct ifaddr *, struct > > > ifnet *); > > > void ifa_item_remove(struct sockaddr *, struct ifaddr *, struct > > > ifnet *); > > > +void ifa_print_rb(void); /* XXX debug */ > > > RB_HEAD(ifaddr_items, ifaddr_item) ifaddr_items = > > > RB_INITIALIZER(&ifaddr_items); > > > RB_PROTOTYPE(ifaddr_items, ifaddr_item, ifai_entry, ifai_cmp); > > > RB_GENERATE(ifaddr_items, ifaddr_item, ifai_entry, ifai_cmp); > > > @@ -722,9 +723,11 @@ if_clone_destroy(const char *name) > > > return (EINVAL); > > > > > > ifp = ifunit(name); > > > - if (ifp == NULL) > > > - return (ENXIO); > > > + if (ifp == NULL) { > > > +ifa_print_rb(); > > > > > > + return (ENXIO); > > > +} > > > if (ifc->ifc_destroy == NULL) > > > return (EOPNOTSUPP); > > > > > > @@ -880,32 +883,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; > > > + > > > + bzero(&key, sizeof(key)); > > > + key.ifai_addr = addr; > > > + key.ifai_rdomain = rtable_l2(rdomain); > > > + > > > + 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) > > > > > > - 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); > > > - } > > > - } > > > - return (NULL); > > > -} > > > - > > > /* > > > * Locate the point to point interface with a given destination address. > > > */ > > > @@ -2188,12 +2181,26 @@ ifa_add(struct ifnet *ifp, struct ifaddr > > > 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 > > > @@ -2251,6 +2258,31 @@ ifa_item_remove(struct sockaddr *sa, str > > > } else > > > ifai_last->ifai_next = ifai->ifai_next; > > > pool_put(&ifaddr_item_pl, ifai); > > > +} > > > + > > > +void > > > +ifa_print_rb(void) > > > +{ > > > + struct ifaddr_item *ifai, *p; > > > + RB_FOREACH(p, ifaddr_items, &ifaddr_items) { > > > + for (ifai = p; ifai; ifai = ifai->ifai_next) { > > > + switch (ifai->ifai_addr->sa_family) { > > > + case AF_INET: > > > + printf("%s", inet_ntoa((satosin( > > > + ifai->ifai_addr))->sin_addr)); > > > + break; > > > + case AF_INET6: > > > + printf("%s", ip6_sprintf(&(satosin6( > > > + ifai->ifai_addr))->sin6_addr)); > > > + break; > > > + case AF_LINK: > > > + printf("%s", > > > + ether_sprintf(ifai->ifai_addr->sa_data)); > > > + break; > > > + } > > > + printf(" on %s\n", ifai->ifai_ifa->ifa_ifp->if_xname); > > > + } > > > + } > > > } > > > > > > void > > > Index: net/if.h > > > =================================================================== > > > RCS file: /cvs/src/sys/net/if.h,v > > > retrieving revision 1.118 > > > diff -u -p -r1.118 if.h > > > --- net/if.h 27 Aug 2010 17:08:01 -0000 1.118 > > > +++ net/if.h 23 Sep 2010 11:43:14 -0000 > > > @@ -848,5 +848,7 @@ int looutput(struct ifnet *, > > > void lortrequest(int, struct rtentry *, struct rt_addrinfo *); > > > void ifa_add(struct ifnet *, struct ifaddr *); > > > void ifa_del(struct ifnet *, struct ifaddr *); > > > +void ifa_update_broadaddr(struct ifnet *, struct ifaddr *, > > > + struct sockaddr *); > > > #endif /* _KERNEL */ > > > #endif /* _NET_IF_H_ */ > > > Index: net/if_spppsubr.c > > > =================================================================== > > > RCS file: /cvs/src/sys/net/if_spppsubr.c,v > > > retrieving revision 1.82 > > > diff -u -p -r1.82 if_spppsubr.c > > > --- net/if_spppsubr.c 13 Sep 2010 08:53:06 -0000 1.82 > > > +++ net/if_spppsubr.c 23 Sep 2010 11:43:14 -0000 > > > @@ -4743,7 +4743,7 @@ sppp_set_ip_addrs(struct sppp *sp, u_int > > > *dest = new_dst; /* fix dstaddr in place */ > > > } > > > } > > > - if (!(error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0))) > > > + if (!(error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0, 0))) > > > dohooks(ifp->if_addrhooks, 0); > > > if (debug && error) { > > > log(LOG_DEBUG, SPP_FMT "sppp_set_ip_addrs: in_ifinit " > > > @@ -4795,7 +4795,7 @@ sppp_clear_ip_addrs(struct sppp *sp) > > > if (sp->ipcp.flags & IPCP_HISADDR_DYN) > > > /* replace peer addr in place */ > > > dest->sin_addr.s_addr = sp->ipcp.saved_hisaddr; > > > - if (!in_ifinit(ifp, ifatoia(ifa), &new_sin, 0)) > > > + if (!in_ifinit(ifp, ifatoia(ifa), &new_sin, 0, 0)) > > > dohooks(ifp->if_addrhooks, 0); > > > sppp_update_gw(ifp); > > > } > > > Index: netinet/in.c > > > =================================================================== > > > RCS file: /cvs/src/sys/netinet/in.c,v > > > retrieving revision 1.60 > > > diff -u -p -r1.60 in.c > > > --- netinet/in.c 13 Jan 2010 10:45:21 -0000 1.60 > > > +++ netinet/in.c 23 Sep 2010 11:43:14 -0000 > > > @@ -271,7 +271,6 @@ in_control(so, cmd, data, ifp) > > > LIST_INIT(&ia->ia_multiaddrs); > > > if ((ifp->if_flags & IFF_LOOPBACK) == 0) > > > in_interfaces++; > > > - ifa_add(ifp, (struct ifaddr *)ia); > > > splx(s); > > > > > > newifaddr = 1; > > > @@ -351,12 +350,14 @@ in_control(so, cmd, data, ifp) > > > case SIOCSIFBRDADDR: > > > if ((ifp->if_flags & IFF_BROADCAST) == 0) > > > return (EINVAL); > > > - ia->ia_broadaddr = *satosin(&ifr->ifr_broadaddr); > > > + ifa_update_broadaddr(ifp, (struct ifaddr *)ia, > > > + &ifr->ifr_broadaddr); > > > break; > > > > > > case SIOCSIFADDR: > > > s = splsoftnet(); > > > - error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1); > > > + error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1, > > > + newifaddr); > > > if (!error) > > > dohooks(ifp->if_addrhooks, 0); > > > else if (newifaddr) { > > > @@ -381,7 +382,7 @@ in_control(so, cmd, data, ifp) > > > ifra->ifra_addr = ia->ia_addr; > > > hostIsNew = 0; > > > } else if (ifra->ifra_addr.sin_addr.s_addr == > > > - ia->ia_addr.sin_addr.s_addr) > > > + ia->ia_addr.sin_addr.s_addr && !newifaddr) > > > hostIsNew = 0; > > > } > > > if (ifra->ifra_mask.sin_len) { > > > @@ -396,13 +397,19 @@ in_control(so, cmd, data, ifp) > > > ia->ia_dstaddr = ifra->ifra_dstaddr; > > > maskIsNew = 1; /* We lie; but the effect's the same */ > > > } > > > + if ((ifp->if_flags & IFF_BROADCAST) && > > > + (ifra->ifra_broadaddr.sin_family == AF_INET)) { > > > + if (newifaddr) > > > + ia->ia_broadaddr = ifra->ifra_broadaddr; > > > + else > > > + ifa_update_broadaddr(ifp, (struct ifaddr *)ia, > > > + sintosa(&ifra->ifra_broadaddr)); > > > + } > > > if (ifra->ifra_addr.sin_family == AF_INET && > > > (hostIsNew || maskIsNew)) { > > > - error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); > > > + error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0, > > > + newifaddr); > > > } > > > - if ((ifp->if_flags & IFF_BROADCAST) && > > > - (ifra->ifra_broadaddr.sin_family == AF_INET)) > > > - ia->ia_broadaddr = ifra->ifra_broadaddr; > > > if (!error) > > > dohooks(ifp->if_addrhooks, 0); > > > else if (newifaddr) { > > > @@ -652,18 +659,22 @@ in_ifscrub(ifp, ia) > > > * and routing table entry. > > > */ > > > int > > > -in_ifinit(ifp, ia, sin, scrub) > > > +in_ifinit(ifp, ia, sin, scrub, newaddr) > > > struct ifnet *ifp; > > > struct in_ifaddr *ia; > > > struct sockaddr_in *sin; > > > int scrub; > > > + int newaddr; > > > { > > > u_int32_t i = sin->sin_addr.s_addr; > > > struct sockaddr_in oldaddr; > > > int s = splnet(), flags = RTF_UP, error; > > > > > > + if (!newaddr) > > > + ifa_del(ifp, (struct ifaddr *)ia); > > > oldaddr = ia->ia_addr; > > > ia->ia_addr = *sin; > > > + > > > /* > > > * Give the interface a chance to initialize > > > * if this is its first address, > > > @@ -719,6 +730,7 @@ in_ifinit(ifp, ia, sin, scrub) > > > flags |= RTF_HOST; > > > } > > > error = in_addprefix(ia, flags); > > > + > > > /* > > > * If the interface supports multicast, join the "all hosts" > > > * multicast group on that interface. > > > @@ -729,6 +741,9 @@ in_ifinit(ifp, ia, sin, scrub) > > > addr.s_addr = INADDR_ALLHOSTS_GROUP; > > > ia->ia_allhosts = in_addmulti(&addr, ifp); > > > } > > > + > > > + ifa_add(ifp, (struct ifaddr *)ia); > > > + > > > return (error); > > > } > > > > > > Index: netinet/in_var.h > > > =================================================================== > > > RCS file: /cvs/src/sys/netinet/in_var.h,v > > > retrieving revision 1.15 > > > diff -u -p -r1.15 in_var.h > > > --- netinet/in_var.h 13 Jan 2010 07:05:28 -0000 1.15 > > > +++ netinet/in_var.h 23 Sep 2010 11:43:14 -0000 > > > @@ -207,7 +207,7 @@ do { > > > \ > > > } while (/* CONSTCOND */ 0) > > > > > > int in_ifinit(struct ifnet *, > > > - struct in_ifaddr *, struct sockaddr_in *, int); > > > + struct in_ifaddr *, struct sockaddr_in *, int, int); > > > struct in_multi *in_addmulti(struct in_addr *, struct ifnet *); > > > void in_delmulti(struct in_multi *); > > > void in_ifscrub(struct ifnet *, struct in_ifaddr *); > > > > > > > > > -- > > > Henning Brauer, [email protected], [email protected] > > > BS Web Services, http://bsws.de > > > Full-Service ISP - Secure Hosting, Mail and DNS Services > > > Dedicated Servers, Rootservers, Application Hosting > > > > > > > -- > > Henning Brauer, [email protected], [email protected] > > BS Web Services, http://bsws.de > > Full-Service ISP - Secure Hosting, Mail and DNS Services > > Dedicated Servers, Rootservers, Application Hosting > > > > -- > Henning Brauer, [email protected], [email protected] > BS Web Services, http://bsws.de > Full-Service ISP - Secure Hosting, Mail and DNS Services > Dedicated Servers, Rootservers, Application Hosting > -- Henning Brauer, [email protected], [email protected] BS Web Services, http://bsws.de Full-Service ISP - Secure Hosting, Mail and DNS Services Dedicated Servers, Rootservers, Application Hosting
