svn commit: r238237 - stable/9/sys/netinet
Bjoern A. Zeeb
bz at FreeBSD.org
Sun Jul 8 12:12:35 UTC 2012
Author: bz
Date: Sun Jul 8 12:12:34 2012
New Revision: 238237
URL: http://svn.freebsd.org/changeset/base/238237
Log:
MFC r235961:
Add code to handle pre-checked TCP checksums as indicated by mbuf
flags to save the entire computation for validation if not needed.
In the IPv6 TCP output path only compute the pseudo-header checksum,
set the checksum offset in the mbuf field along the appropriate flag
as done in IPv4.
In tcp_respond() just initialize the IPv6 payload length to 0 as
ip6_output() will properly set it.
Approved by: re
Modified:
stable/9/sys/netinet/tcp_input.c
stable/9/sys/netinet/tcp_output.c
stable/9/sys/netinet/tcp_subr.c
stable/9/sys/netinet/tcp_syncache.c
stable/9/sys/netinet/tcp_timewait.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/netinet/tcp_input.c
==============================================================================
--- stable/9/sys/netinet/tcp_input.c Sun Jul 8 12:01:11 2012 (r238236)
+++ stable/9/sys/netinet/tcp_input.c Sun Jul 8 12:12:34 2012 (r238237)
@@ -610,13 +610,31 @@ tcp_input(struct mbuf *m, int off0)
#ifdef INET6
if (isipv6) {
/* IP6_EXTHDR_CHECK() is already done at tcp6_input(). */
+
+ if (m->m_len < (sizeof(*ip6) + sizeof(*th))) {
+ m = m_pullup(m, sizeof(*ip6) + sizeof(*th));
+ if (m == NULL) {
+ TCPSTAT_INC(tcps_rcvshort);
+ return;
+ }
+ }
+
ip6 = mtod(m, struct ip6_hdr *);
+ th = (struct tcphdr *)((caddr_t)ip6 + off0);
tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0;
- if (in6_cksum(m, IPPROTO_TCP, off0, tlen)) {
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
+ if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
+ th->th_sum = m->m_pkthdr.csum_data;
+ else
+ th->th_sum = in6_cksum_pseudo(ip6, tlen,
+ IPPROTO_TCP, m->m_pkthdr.csum_data);
+ th->th_sum ^= 0xffff;
+ } else
+ th->th_sum = in6_cksum(m, IPPROTO_TCP, off0, tlen);
+ if (th->th_sum) {
TCPSTAT_INC(tcps_rcvbadsum);
goto drop;
}
- th = (struct tcphdr *)((caddr_t)ip6 + off0);
/*
* Be proactive about unspecified IPv6 address in source.
Modified: stable/9/sys/netinet/tcp_output.c
==============================================================================
--- stable/9/sys/netinet/tcp_output.c Sun Jul 8 12:01:11 2012 (r238236)
+++ stable/9/sys/netinet/tcp_output.c Sun Jul 8 12:12:34 2012 (r238237)
@@ -1052,19 +1052,23 @@ send:
* checksum extended header and data.
*/
m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
+ m->m_pkthdr.csum_flags = CSUM_TCP;
+ m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
- if (isipv6)
+ if (isipv6) {
/*
* ip6_plen is not need to be filled now, and will be filled
* in ip6_output.
*/
- th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr),
- sizeof(struct tcphdr) + optlen + len);
+ th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) +
+ optlen + len, IPPROTO_TCP, 0);
+ }
+#endif
+#if defined(INET6) && defined(INET)
else
-#endif /* INET6 */
+#endif
+#ifdef INET
{
- m->m_pkthdr.csum_flags = CSUM_TCP;
- m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen));
@@ -1072,6 +1076,7 @@ send:
KASSERT(ip->ip_v == IPVERSION,
("%s: IP version incorrect: %d", __func__, ip->ip_v));
}
+#endif
/*
* Enable TSO and specify the size of the segments.
Modified: stable/9/sys/netinet/tcp_subr.c
==============================================================================
--- stable/9/sys/netinet/tcp_subr.c Sun Jul 8 12:01:11 2012 (r238236)
+++ stable/9/sys/netinet/tcp_subr.c Sun Jul 8 12:12:34 2012 (r238237)
@@ -573,8 +573,7 @@ tcp_respond(struct tcpcb *tp, void *ipge
ip6->ip6_flow = 0;
ip6->ip6_vfc = IPV6_VERSION;
ip6->ip6_nxt = IPPROTO_TCP;
- ip6->ip6_plen = htons((u_short)(sizeof (struct tcphdr) +
- tlen));
+ ip6->ip6_plen = 0; /* Set in ip6_output(). */
tlen += sizeof (struct ip6_hdr) + sizeof (struct tcphdr);
}
#endif
@@ -619,12 +618,13 @@ tcp_respond(struct tcpcb *tp, void *ipge
else
nth->th_win = htons((u_short)win);
nth->th_urp = 0;
+
+ m->m_pkthdr.csum_flags = CSUM_TCP;
+ m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (isipv6) {
- nth->th_sum = 0;
- nth->th_sum = in6_cksum(m, IPPROTO_TCP,
- sizeof(struct ip6_hdr),
- tlen - sizeof(struct ip6_hdr));
+ nth->th_sum = in6_cksum_pseudo(ip6,
+ tlen - sizeof(struct ip6_hdr), IPPROTO_TCP, 0);
ip6->ip6_hlim = in6_selecthlim(tp != NULL ? tp->t_inpcb :
NULL, NULL);
}
@@ -636,8 +636,6 @@ tcp_respond(struct tcpcb *tp, void *ipge
{
nth->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons((u_short)(tlen - sizeof(struct ip) + ip->ip_p)));
- m->m_pkthdr.csum_flags = CSUM_TCP;
- m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
}
#endif /* INET */
#ifdef TCPDEBUG
Modified: stable/9/sys/netinet/tcp_syncache.c
==============================================================================
--- stable/9/sys/netinet/tcp_syncache.c Sun Jul 8 12:01:11 2012 (r238236)
+++ stable/9/sys/netinet/tcp_syncache.c Sun Jul 8 12:12:34 2012 (r238237)
@@ -1472,11 +1472,12 @@ syncache_respond(struct syncache *sc)
optlen = 0;
M_SETFIB(m, sc->sc_inc.inc_fibnum);
+ m->m_pkthdr.csum_flags = CSUM_TCP;
+ m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (sc->sc_inc.inc_flags & INC_ISIPV6) {
- th->th_sum = 0;
- th->th_sum = in6_cksum(m, IPPROTO_TCP, hlen,
- tlen + optlen - hlen);
+ th->th_sum = in6_cksum_pseudo(ip6, tlen + optlen - hlen,
+ IPPROTO_TCP, 0);
ip6->ip6_hlim = in6_selecthlim(NULL, NULL);
error = ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
}
@@ -1488,8 +1489,6 @@ syncache_respond(struct syncache *sc)
{
th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(tlen + optlen - hlen + IPPROTO_TCP));
- m->m_pkthdr.csum_flags = CSUM_TCP;
- m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
error = ip_output(m, sc->sc_ipopts, NULL, 0, NULL, NULL);
}
#endif
Modified: stable/9/sys/netinet/tcp_timewait.c
==============================================================================
--- stable/9/sys/netinet/tcp_timewait.c Sun Jul 8 12:01:11 2012 (r238236)
+++ stable/9/sys/netinet/tcp_timewait.c Sun Jul 8 12:12:34 2012 (r238237)
@@ -574,10 +574,12 @@ tcp_twrespond(struct tcptw *tw, int flag
th->th_flags = flags;
th->th_win = htons(tw->last_win);
+ m->m_pkthdr.csum_flags = CSUM_TCP;
+ m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
#ifdef INET6
if (isipv6) {
- th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr),
- sizeof(struct tcphdr) + optlen);
+ th->th_sum = in6_cksum_pseudo(ip6,
+ sizeof(struct tcphdr) + optlen, IPPROTO_TCP, 0);
ip6->ip6_hlim = in6_selecthlim(inp, NULL);
error = ip6_output(m, inp->in6p_outputopts, NULL,
(tw->tw_so_options & SO_DONTROUTE), NULL, NULL, inp);
@@ -590,8 +592,6 @@ tcp_twrespond(struct tcptw *tw, int flag
{
th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(sizeof(struct tcphdr) + optlen + IPPROTO_TCP));
- m->m_pkthdr.csum_flags = CSUM_TCP;
- m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum);
ip->ip_len = m->m_pkthdr.len;
if (V_path_mtu_discovery)
ip->ip_off |= IP_DF;
More information about the svn-src-stable-9
mailing list