aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6/ip6_output.c
diff options
context:
space:
mode:
authorAndre Oppermann <andre@FreeBSD.org>2003-11-20 20:07:39 +0000
committerAndre Oppermann <andre@FreeBSD.org>2003-11-20 20:07:39 +0000
commit97d8d152c28bb596e1c310d9842db5d0314207b2 (patch)
treef947a08d66395dd498056038f0c360783fa281c7 /sys/netinet6/ip6_output.c
parent26d02ca7babf8bb8d1e2b9c8cb3e18ec0fcd1317 (diff)
downloadsrc-97d8d152c28bb596e1c310d9842db5d0314207b2.tar.gz
src-97d8d152c28bb596e1c310d9842db5d0314207b2.zip
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)
Notes
Notes: svn path=/head/; revision=122922
Diffstat (limited to 'sys/netinet6/ip6_output.c')
-rw-r--r--sys/netinet6/ip6_output.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index b95b1976bd7a..30728518dddd 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -96,6 +96,7 @@
#include <netinet/icmp6.h>
#include <netinet6/ip6_var.h>
#include <netinet/in_pcb.h>
+#include <netinet/tcp_var.h>
#include <netinet6/nd6.h>
#ifdef IPSEC
@@ -661,7 +662,7 @@ skip_ipsec2:;
/* XXX rt not locked */
ia = ifatoia6(ro->ro_rt->rt_ifa);
ifp = ro->ro_rt->rt_ifp;
- ro->ro_rt->rt_use++;
+ ro->ro_rt->rt_rmx.rmx_pksent++;
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
dst = (struct sockaddr_in6 *)ro->ro_rt->rt_gateway;
m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
@@ -757,7 +758,7 @@ skip_ipsec2:;
}
ia = ifatoia6(ro->ro_rt->rt_ifa);
ifp = ro->ro_rt->rt_ifp;
- ro->ro_rt->rt_use++;
+ ro->ro_rt->rt_rmx.rmx_pksent++;
RT_UNLOCK(ro->ro_rt);
}
@@ -1387,11 +1388,20 @@ ip6_getpmtu(ro_pmtu, ro, ifp, dst, mtup, alwaysfragp)
}
if (ro_pmtu->ro_rt) {
u_int32_t ifmtu;
+ struct in_conninfo inc;
+
+ bzero(&inc, sizeof(inc));
+ inc.inc_flags = 1; /* IPv6 */
+ inc.inc6_faddr = *dst;
if (ifp == NULL)
ifp = ro_pmtu->ro_rt->rt_ifp;
ifmtu = IN6_LINKMTU(ifp);
- mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
+ mtu = tcp_hc_getmtu(&inc);
+ if (mtu)
+ mtu = min(mtu, ro_pmtu->ro_rt->rt_rmx.rmx_mtu);
+ else
+ mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
if (mtu == 0)
mtu = ifmtu;
else if (mtu < IPV6_MMTU) {
@@ -1415,8 +1425,7 @@ ip6_getpmtu(ro_pmtu, ro, ifp, dst, mtup, alwaysfragp)
* field isn't locked).
*/
mtu = ifmtu;
- if (!(ro_pmtu->ro_rt->rt_rmx.rmx_locks & RTV_MTU))
- ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu;
+ ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu;
}
} else if (ifp) {
mtu = IN6_LINKMTU(ifp);
@@ -1993,7 +2002,9 @@ do { \
{
u_long pmtu = 0;
struct ip6_mtuinfo mtuinfo;
- struct route_in6 *ro = (struct route_in6 *)&in6p->in6p_route;
+ struct route_in6 sro;
+
+ bzero(&sro, sizeof(sro));
if (!(so->so_state & SS_ISCONNECTED))
return (ENOTCONN);
@@ -2002,8 +2013,10 @@ do { \
* routing, or optional information to specify
* the outgoing interface.
*/
- error = ip6_getpmtu(ro, NULL, NULL,
+ error = ip6_getpmtu(&sro, NULL, NULL,
&in6p->in6p_faddr, &pmtu, NULL);
+ if (sro.ro_rt)
+ RTFREE(sro.ro_rt);
if (error)
break;
if (pmtu > IPV6_MAXPACKET)