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
