diff options
author | andre <andre@FreeBSD.org> | 2003-11-20 20:07:39 +0000 |
---|---|---|
committer | andre <andre@FreeBSD.org> | 2003-11-20 20:07:39 +0000 |
commit | 6164d7c280688f20cf827e8374984c6e0175fab0 (patch) | |
tree | f947a08d66395dd498056038f0c360783fa281c7 /sys/netinet6/in6_src.c | |
parent | 6dca20de0718f19b3cdc5a7d5ebb71cd54b2374e (diff) | |
download | FreeBSD-src-6164d7c280688f20cf827e8374984c6e0175fab0.zip FreeBSD-src-6164d7c280688f20cf827e8374984c6e0175fab0.tar.gz |
Introduce tcp_hostcache and remove the tcp specific metrics from
the routing table. Move all usage and references in the tcp stack
from the routing table metrics to the tcp hostcache.
It caches measured parameters of past tcp sessions to provide better
initial start values for following connections from or to the same
source or destination. Depending on the network parameters to/from
the remote host this can lead to significant speedups for new tcp
connections after the first one because they inherit and shortcut
the learning curve.
tcp_hostcache is designed for multiple concurrent access in SMP
environments with high contention and is hash indexed by remote
ip address.
It removes significant locking requirements from the tcp stack with
regard to the routing table.
Reviewed by: sam (mentor), bms
Reviewed by: -net, -current, core@kame.net (IPv6 parts)
Approved by: re (scottl)
Diffstat (limited to 'sys/netinet6/in6_src.c')
-rw-r--r-- | sys/netinet6/in6_src.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index d584956..88ace1c 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -211,7 +211,6 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp) != 0) { return (NULL); } - /* * determine the appropriate zone id of the source based on * the zone of the destination and the outgoing interface. @@ -449,12 +448,19 @@ in6_selectif(dstsock, opts, mopts, ro, retifp) struct route_in6 *ro; struct ifnet **retifp; { - int error, clone; + int error; + struct route_in6 sro; struct rtentry *rt = NULL; - clone = IN6_IS_ADDR_MULTICAST(&dstsock->sin6_addr) ? 0 : 1; + if (ro == NULL) { + bzero(&sro, sizeof(sro)); + ro = &sro; + } + if ((error = in6_selectroute(dstsock, opts, mopts, ro, retifp, - &rt, clone)) != 0) { + &rt, 0)) != 0) { + if (rt && rt == sro.ro_rt) + RTFREE(rt); return (error); } @@ -476,7 +482,11 @@ in6_selectif(dstsock, opts, mopts, ro, retifp) * We thus reject the case here. */ if (rt && (rt->rt_flags & (RTF_REJECT | RTF_BLACKHOLE))) { - return (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); + int flags = (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); + + if (rt && rt == sro.ro_rt) + RTFREE(rt); + return (flags); } /* @@ -489,6 +499,8 @@ in6_selectif(dstsock, opts, mopts, ro, retifp) if (rt && rt->rt_ifa && rt->rt_ifa->ifa_ifp) *retifp = rt->rt_ifa->ifa_ifp; + if (rt && rt == sro.ro_rt) + RTFREE(rt); return (0); } @@ -623,6 +635,7 @@ in6_selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone) sa6 = (struct sockaddr_in6 *)&ro->ro_dst; *sa6 = *dstsock; sa6->sin6_scope_id = 0; + if (clone) { rtalloc((struct route *)ro); } else { @@ -695,7 +708,7 @@ in6_selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone) * 2. (If the outgoing interface is detected) the current * hop limit of the interface specified by router advertisement. * 3. The system default hoplimit. -*/ + */ int in6_selecthlim(in6p, ifp) struct in6pcb *in6p; @@ -705,8 +718,24 @@ in6_selecthlim(in6p, ifp) return (in6p->in6p_hops); else if (ifp) return (ND_IFINFO(ifp)->chlim); - else - return (ip6_defhlim); + else if (in6p && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { + struct route_in6 ro6; + struct ifnet *lifp; + + bzero(&ro6, sizeof(ro6)); + ro6.ro_dst.sin6_family = AF_INET6; + ro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6); + ro6.ro_dst.sin6_addr = in6p->in6p_faddr; + rtalloc((struct route *)&ro6); + if (ro6.ro_rt) { + lifp = ro6.ro_rt->rt_ifp; + RTFREE(ro6.ro_rt); + if (lifp) + return (ND_IFINFO(lifp)->chlim); + } else + return (ip6_defhlim); + } + return (ip6_defhlim); } /* |