From 4eae039596e1aea5bbdea0ea1dd8f760958a5e4c Mon Sep 17 00:00:00 2001 From: Christian Weisgerber Date: Wed, 3 Jun 2009 18:22:45 +0000 Subject: add the basic infrastructure to take advantage of TCP and UDP receive checksum offload over IPv6; ok deraadt@ --- sys/netinet/tcp_input.c | 19 +++++++++++++++---- sys/netinet/udp_usrreq.c | 20 ++++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index cd63922fe2b..aee2240007e 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.224 2008/11/02 10:37:29 claudio Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.225 2009/06/03 18:22:44 naddy Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -522,9 +522,20 @@ tcp_input(struct mbuf *m, ...) /* * Checksum extended TCP header and data. */ - if (in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr), tlen)) { - tcpstat.tcps_rcvbadsum++; - goto drop; + if ((m->m_pkthdr.csum_flags & M_TCP_CSUM_IN_OK) == 0) { + if (m->m_pkthdr.csum_flags & M_TCP_CSUM_IN_BAD) { + tcpstat.tcps_inhwcsum++; + tcpstat.tcps_rcvbadsum++; + goto drop; + } + if (in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr), + tlen)) { + tcpstat.tcps_rcvbadsum++; + goto drop; + } + } else { + m->m_pkthdr.csum_flags &= ~M_TCP_CSUM_IN_OK; + tcpstat.tcps_inhwcsum++; } break; #endif diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 59374375801..d93dcd1b26a 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.127 2009/06/02 15:32:19 blambert Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.128 2009/06/03 18:22:44 naddy Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -286,9 +286,21 @@ udp_input(struct mbuf *m, ...) udpstat.udps_nosum++; goto bad; } - if ((uh->uh_sum = in6_cksum(m, IPPROTO_UDP, iphlen, len))) { - udpstat.udps_badsum++; - goto bad; + if ((m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_OK) == 0) { + if (m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_BAD) { + udpstat.udps_badsum++; + udpstat.udps_inhwcsum++; + goto bad; + } + + if ((uh->uh_sum = in6_cksum(m, IPPROTO_UDP, + iphlen, len))) { + udpstat.udps_badsum++; + goto bad; + } + } else { + m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_IN_OK; + udpstat.udps_inhwcsum++; } } else #endif /* INET6 */ -- cgit v1.2.3