From owner-svn-src-user@FreeBSD.ORG Mon Nov 19 18:04:19 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 0F9503ED; Mon, 19 Nov 2012 18:04:19 +0000 (UTC) (envelope-from andre@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id E5B528FC08; Mon, 19 Nov 2012 18:04:18 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qAJI4Irb014630; Mon, 19 Nov 2012 18:04:18 GMT (envelope-from andre@svn.freebsd.org) Received: (from andre@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qAJI4IXX014601; Mon, 19 Nov 2012 18:04:18 GMT (envelope-from andre@svn.freebsd.org) Message-Id: <201211191804.qAJI4IXX014601@svn.freebsd.org> From: Andre Oppermann Date: Mon, 19 Nov 2012 18:04:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r243291 - in user/andre/tcp_workqueue/sys: net netinet netinet6 netipsec netpfil/ipfw netpfil/pf X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Nov 2012 18:04:19 -0000 Author: andre Date: Mon Nov 19 18:04:17 2012 New Revision: 243291 URL: http://svnweb.freebsd.org/changeset/base/243291 Log: Convert IP, IPv6, UDP, TCP and SCTP to the new checksum offloading semantics on the inbound and outbound path. In short for inbound there are two levels the offloading NIC can set: CSUM_L3_CALC for an IP layer 3 checksum calculated by the NIC; CSUM_L3_VALID set when the calculated checksum matches the one in the packet; CSUM_L4_CALC for an UDP/TCP/SCTP layer 4 checksum calculated by the NIC; CSUM_L4_VALID set when the calculated checksum matche the one in the packet. From this follows that a packet failed checksum verification when only *_CALC is set but not *_VALID. The NIC is expected to deliver a failed packet up the stack anyways for capture by BPF and to record protocol specific checksum mismatch statistics. The old approach with CSUM_DATA_VALID and CSUM_PSEUDO_HDR could not signal a failed packet. A failed packet was delivered into the stack and the protocol had to recalculate the checksum for verification every time to detect that as the absence of CSUM_DATA_VALID didn't signal that the packet was broken. It was only saying that the checksum wasn't calculated by the NIC, which actually wasn't the case. Drag the other stack infrastructure, including packet filters, along as well. Modified: user/andre/tcp_workqueue/sys/net/if_bridge.c user/andre/tcp_workqueue/sys/net/if_ethersubr.c user/andre/tcp_workqueue/sys/net/if_loop.c user/andre/tcp_workqueue/sys/netinet/ip_divert.c user/andre/tcp_workqueue/sys/netinet/ip_fastfwd.c user/andre/tcp_workqueue/sys/netinet/ip_input.c user/andre/tcp_workqueue/sys/netinet/ip_ipsec.c user/andre/tcp_workqueue/sys/netinet/ip_mroute.c user/andre/tcp_workqueue/sys/netinet/ip_output.c user/andre/tcp_workqueue/sys/netinet/sctp_input.c user/andre/tcp_workqueue/sys/netinet/sctp_os_bsd.h user/andre/tcp_workqueue/sys/netinet/sctp_output.c user/andre/tcp_workqueue/sys/netinet/siftr.c user/andre/tcp_workqueue/sys/netinet/tcp_input.c user/andre/tcp_workqueue/sys/netinet/tcp_lro.c user/andre/tcp_workqueue/sys/netinet/tcp_output.c user/andre/tcp_workqueue/sys/netinet/tcp_subr.c user/andre/tcp_workqueue/sys/netinet/tcp_syncache.c user/andre/tcp_workqueue/sys/netinet/tcp_timewait.c user/andre/tcp_workqueue/sys/netinet/udp_usrreq.c user/andre/tcp_workqueue/sys/netinet6/ip6_forward.c user/andre/tcp_workqueue/sys/netinet6/ip6_ipsec.c user/andre/tcp_workqueue/sys/netinet6/ip6_output.c user/andre/tcp_workqueue/sys/netinet6/sctp6_usrreq.c user/andre/tcp_workqueue/sys/netinet6/udp6_usrreq.c user/andre/tcp_workqueue/sys/netipsec/ipsec_pfil.c user/andre/tcp_workqueue/sys/netpfil/ipfw/ip_fw_nat.c user/andre/tcp_workqueue/sys/netpfil/pf/pf.c user/andre/tcp_workqueue/sys/netpfil/pf/pf_ioctl.c Modified: user/andre/tcp_workqueue/sys/net/if_bridge.c ============================================================================== --- user/andre/tcp_workqueue/sys/net/if_bridge.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/net/if_bridge.c Mon Nov 19 18:04:17 2012 (r243291) @@ -3263,8 +3263,8 @@ bridge_ip_checkbasic(struct mbuf **mp) if (ip == NULL) goto bad; } - if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { - sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); + if (m->m_pkthdr.csum_flags & CSUM_L3_CALC) { + sum = !(m->m_pkthdr.csum_flags & CSUM_L3_VALID); } else { if (hlen == sizeof(struct ip)) { sum = in_cksum_hdr(ip); Modified: user/andre/tcp_workqueue/sys/net/if_ethersubr.c ============================================================================== --- user/andre/tcp_workqueue/sys/net/if_ethersubr.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/net/if_ethersubr.c Mon Nov 19 18:04:17 2012 (r243291) @@ -299,12 +299,10 @@ ether_output(struct ifnet *ifp, struct m if (lle != NULL && (lle->la_flags & LLE_IFADDR)) { int csum_flags = 0; if (m->m_pkthdr.csum_flags & CSUM_IP) - csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID); - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) - csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); - if (m->m_pkthdr.csum_flags & CSUM_SCTP) - csum_flags |= CSUM_SCTP_VALID; - m->m_pkthdr.csum_flags |= csum_flags; + csum_flags |= (CSUM_L3_CALC|CSUM_L3_VALID); + if (m->m_pkthdr.csum_flags & (CSUM_UDP|CSUM_TCP|CSUM_SCTP)) + csum_flags |= (CSUM_L4_CALC|CSUM_L4_VALID); + m->m_pkthdr.csum_flags = csum_flags; m->m_pkthdr.csum_data = 0xffff; return (if_simloop(ifp, m, dst->sa_family, 0)); } @@ -356,11 +354,9 @@ ether_output(struct ifnet *ifp, struct m int csum_flags = 0; if (m->m_pkthdr.csum_flags & CSUM_IP) - csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID); - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) - csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); - if (m->m_pkthdr.csum_flags & CSUM_SCTP) - csum_flags |= CSUM_SCTP_VALID; + csum_flags |= (CSUM_L3_CALC|CSUM_L3_VALID); + if (m->m_pkthdr.csum_flags & (CSUM_UDP|CSUM_TCP|CSUM_SCTP)) + csum_flags |= (CSUM_L4_CALC|CSUM_L4_VALID); if (m->m_flags & M_BCAST) { struct mbuf *n; @@ -379,16 +375,12 @@ ether_output(struct ifnet *ifp, struct m */ if ((n = m_dup(m, M_DONTWAIT)) != NULL) { n->m_pkthdr.csum_flags |= csum_flags; - if (csum_flags & CSUM_DATA_VALID) - n->m_pkthdr.csum_data = 0xffff; (void)if_simloop(ifp, n, dst->sa_family, hlen); } else ifp->if_iqdrops++; } else if (bcmp(eh->ether_dhost, eh->ether_shost, ETHER_ADDR_LEN) == 0) { m->m_pkthdr.csum_flags |= csum_flags; - if (csum_flags & CSUM_DATA_VALID) - m->m_pkthdr.csum_data = 0xffff; (void) if_simloop(ifp, m, dst->sa_family, hlen); return (0); /* XXX */ } Modified: user/andre/tcp_workqueue/sys/net/if_loop.c ============================================================================== --- user/andre/tcp_workqueue/sys/net/if_loop.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/net/if_loop.c Mon Nov 19 18:04:17 2012 (r243291) @@ -91,12 +91,10 @@ #define LOMTU 16384 #endif -#define LO_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_SCTP) -#define LO_CSUM_FEATURES6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | CSUM_SCTP_IPV6) -#define LO_CSUM_SET (CSUM_DATA_VALID | CSUM_DATA_VALID_IPV6 | \ - CSUM_PSEUDO_HDR | \ - CSUM_IP_CHECKED | CSUM_IP_VALID | \ - CSUM_SCTP_VALID) +#define LO_CSUM_FEATURES (CSUM_IP|CSUM_IP_UDP|CSUM_IP_TCP|CSUM_IP_SCTP) +#define LO_CSUM_FEATURES6 (CSUM_IP6_UDP|CSUM_IP6_TCP|CSUM_IP6_SCTP) +#define LO_CSUM_SET (CSUM_L4_CALC | CSUM_L4_VALID | \ + CSUM_L3_CALC | CSUM_L3_VALID) int loioctl(struct ifnet *, u_long, caddr_t); static void lortrequest(int, struct rtentry *, struct rt_addrinfo *); Modified: user/andre/tcp_workqueue/sys/netinet/ip_divert.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/ip_divert.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/ip_divert.c Mon Nov 19 18:04:17 2012 (r243291) @@ -207,14 +207,14 @@ divert_packet(struct mbuf *m, int incomi ip = mtod(m, struct ip *); /* Delayed checksums are currently not compatible with divert. */ - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m->m_pkthdr.csum_flags & (CSUM_IP_UDP|CSUM_IP_TCP)) { in_delayed_cksum(m); - m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + m->m_pkthdr.csum_flags &= ~(CSUM_IP_UDP|CSUM_IP_TCP); } #ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP) { + if (m->m_pkthdr.csum_flags & CSUM_IP_SCTP) { sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); - m->m_pkthdr.csum_flags &= ~CSUM_SCTP; + m->m_pkthdr.csum_flags &= ~CSUM_IP_SCTP; } #endif bzero(&divsrc, sizeof(divsrc)); Modified: user/andre/tcp_workqueue/sys/netinet/ip_fastfwd.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/ip_fastfwd.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/ip_fastfwd.c Mon Nov 19 18:04:17 2012 (r243291) @@ -230,23 +230,25 @@ ip_fastforward(struct mbuf *m) /* * Checksum correct? */ - if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) - sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); - else { + if ((m->m_pkthdr.csum_flags & (CSUM_L3_CALC | CSUM_L3_VALID)) == + CSUM_L3_CALC) { + IPSTAT_INC(ips_badsum); + goto drop; + } else if (!(m->m_pkthdr.csum_flags & CSUM_L3_VALID)) { if (hlen == sizeof(struct ip)) sum = in_cksum_hdr(ip); else sum = in_cksum(m, hlen); + if (sum) { + IPSTAT_INC(ips_badsum); + goto drop; + } + /* + * Remember that we have checked the IP header and found + * it valid. + */ + m->m_pkthdr.csum_flags |= (CSUM_L3_CALC | CSUM_L3_VALID); } - if (sum) { - IPSTAT_INC(ips_badsum); - goto drop; - } - - /* - * Remember that we have checked the IP header and found it valid. - */ - m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID); ip_len = ntohs(ip->ip_len); @@ -523,7 +525,7 @@ passout: mtu = ifp->if_mtu; if (ip_len <= mtu || - (ifp->if_hwassist & CSUM_IPFRAG && (ip_off & IP_DF) == 0)) { + ((ifp->if_hwassist & CSUM_IP_FRAGO) && (ip_off & IP_DF) == 0)) { /* * Send off the packet via outgoing interface */ Modified: user/andre/tcp_workqueue/sys/netinet/ip_input.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/ip_input.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/ip_input.c Mon Nov 19 18:04:17 2012 (r243291) @@ -435,19 +435,20 @@ ip_input(struct mbuf *m) } } - if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { - sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); - } else { - if (hlen == sizeof(struct ip)) { + if ((m->m_pkthdr.csum_flags & (CSUM_L3_CALC|CSUM_L3_VALID)) == + CSUM_L3_CALC) { + IPSTAT_INC(ips_badsum); + goto bad; + } else if (!(m->m_pkthdr.csum_flags & CSUM_L3_VALID)) { + if (hlen == sizeof(struct ip)) sum = in_cksum_hdr(ip); - } else { + else sum = in_cksum(m, hlen); + if (sum) { + IPSTAT_INC(ips_badsum); + goto bad; } } - if (sum) { - IPSTAT_INC(ips_badsum); - goto bad; - } #ifdef ALTQ if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0) Modified: user/andre/tcp_workqueue/sys/netinet/ip_ipsec.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/ip_ipsec.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/ip_ipsec.c Mon Nov 19 18:04:17 2012 (r243291) @@ -327,16 +327,16 @@ ip_ipsec_output(struct mbuf **m, struct * Do delayed checksums now because we send before * this is done in the normal processing path. */ - if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if ((*m)->m_pkthdr.csum_flags & (CSUM_IP_UDP|CSUM_IP_TCP)) { in_delayed_cksum(*m); - (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + (*m)->m_pkthdr.csum_flags &= ~(CSUM_IP_UDP|CSUM_IP_TCP); } #ifdef SCTP - if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) { + if ((*m)->m_pkthdr.csum_flags & CSUM_IP_SCTP) { struct ip *ip = mtod(*m, struct ip *); sctp_delayed_cksum(*m, (uint32_t)(ip->ip_hl << 2)); - (*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP; + (*m)->m_pkthdr.csum_flags &= ~CSUM_IP_SCTP; } #endif Modified: user/andre/tcp_workqueue/sys/netinet/ip_mroute.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/ip_mroute.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/ip_mroute.c Mon Nov 19 18:04:17 2012 (r243291) @@ -2375,9 +2375,9 @@ pim_register_prepare(struct ip *ip, stru int mtu; /* Take care of delayed checksums */ - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m->m_pkthdr.csum_flags & (CSUM_IP_UDP|CSUM_IP_TCP)) { in_delayed_cksum(m); - m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + m->m_pkthdr.csum_flags &= ~(CSUM_IP_UDP|CSUM_IP_TCP); } /* Modified: user/andre/tcp_workqueue/sys/netinet/ip_output.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/ip_output.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/ip_output.c Mon Nov 19 18:04:17 2012 (r243291) @@ -518,41 +518,31 @@ sendit: m->m_flags |= M_FASTFWD_OURS; if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + /* Pretend that the checksum was verified by hw. */ + if (m->m_pkthdr.csum_flags & CSUM_IP) m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - m->m_pkthdr.csum_data = 0xffff; - } - m->m_pkthdr.csum_flags |= - CSUM_IP_CHECKED | CSUM_IP_VALID; -#ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; -#endif + CSUM_L3_CALC | CSUM_L3_VALID; + if (m->m_pkthdr.csum_flags & + (CSUM_UDP|CSUM_TCP|CSUM_SCTP)) + m->m_pkthdr.csum_flags |= + CSUM_L4_CALC | CSUM_L4_VALID; error = netisr_queue(NETISR_IP, m); goto done; - } else { - if (ia != NULL) - ifa_free(&ia->ia_ifa); - goto again; /* Redo the routing table lookup. */ } + if (ia != NULL) + ifa_free(&ia->ia_ifa); + goto again; /* Redo the routing table lookup. */ } /* See if local, if yes, send it to netisr with IP_FASTFWD_OURS. */ if (m->m_flags & M_FASTFWD_OURS) { if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { - m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - m->m_pkthdr.csum_data = 0xffff; - } -#ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; -#endif - m->m_pkthdr.csum_flags |= - CSUM_IP_CHECKED | CSUM_IP_VALID; + /* Pretend that the checksum was verified by hw. */ + if (m->m_pkthdr.csum_flags & CSUM_IP) + m->m_pkthdr.csum_flags |= CSUM_L3_CALC | CSUM_L3_VALID; + if (m->m_pkthdr.csum_flags & (CSUM_UDP|CSUM_TCP|CSUM_SCTP)) + m->m_pkthdr.csum_flags |= CSUM_L4_CALC | CSUM_L4_VALID; error = netisr_queue(NETISR_IP, m); goto done; @@ -583,14 +573,15 @@ passout: m->m_pkthdr.csum_flags |= CSUM_IP; m->m_pkthdr.csum_l3hlen += ip_len; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA & ~ifp->if_hwassist) { + if (m->m_pkthdr.csum_flags & (CSUM_IP_UDP|CSUM_IP_TCP) & + ~ifp->if_hwassist) { in_delayed_cksum(m); - m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + m->m_pkthdr.csum_flags &= ~(CSUM_IP_UDP|CSUM_IP_TCP); } #ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP & ~ifp->if_hwassist) { + else if (m->m_pkthdr.csum_flags & CSUM_IP_SCTP & ~ifp->if_hwassist) { sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2)); - m->m_pkthdr.csum_flags &= ~CSUM_SCTP; + m->m_pkthdr.csum_flags &= ~CSUM_IP_SCTP; } #endif @@ -599,8 +590,8 @@ passout: * care of the fragmentation for us, we can just send directly. */ if (ip_len <= mtu || - (m->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_TSO) != 0 || - ((ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_IPFRAG))) { + (m->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_IP_TSO) != 0 || + ((ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_IP_FRAGO))) { ip->ip_sum = 0; if (m->m_pkthdr.csum_flags & CSUM_IP & ~ifp->if_hwassist) { ip->ip_sum = in_cksum(m, hlen); @@ -609,12 +600,12 @@ passout: /* * Record statistics for this interface address. - * With CSUM_TSO the byte/packet count will be slightly + * With CSUM_IP_TSO the byte/packet count will be slightly * incorrect because we count the IP+TCP headers only * once instead of for every generated packet. */ if (!(flags & IP_FORWARDING) && ia) { - if (m->m_pkthdr.csum_flags & CSUM_TSO) + if (m->m_pkthdr.csum_flags & CSUM_IP_TSO) ia->ia_ifa.if_opackets += m->m_pkthdr.len / m->m_pkthdr.tso_segsz; else @@ -636,7 +627,7 @@ passout: } /* Balk when DF bit is set or the interface didn't support TSO. */ - if ((ip_off & IP_DF) || (m->m_pkthdr.csum_flags & CSUM_TSO)) { + if ((ip_off & IP_DF) || (m->m_pkthdr.csum_flags & CSUM_IP_TSO)) { error = EMSGSIZE; IPSTAT_INC(ips_cantfrag); goto bad; @@ -724,14 +715,14 @@ ip_fragment(struct ip *ip, struct mbuf * * If the interface will not calculate checksums on * fragmented packets, then do it here. */ - if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (m0->m_pkthdr.csum_flags & (CSUM_IP_UDP|CSUM_IP_TCP)) { in_delayed_cksum(m0); - m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + m0->m_pkthdr.csum_flags &= ~(CSUM_IP_UDP|CSUM_IP_TCP); } #ifdef SCTP - if (m0->m_pkthdr.csum_flags & CSUM_SCTP) { + if (m0->m_pkthdr.csum_flags & CSUM_IP_SCTP) { sctp_delayed_cksum(m0, hlen); - m0->m_pkthdr.csum_flags &= ~CSUM_SCTP; + m0->m_pkthdr.csum_flags &= ~CSUM_IP_SCTP; } #endif if (len > PAGE_SIZE) { @@ -872,7 +863,7 @@ in_delayed_cksum(struct mbuf *m) offset = ip->ip_hl << 2 ; ip_len = ntohs(ip->ip_len); csum = in_cksum_skip(m, ip_len, offset); - if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0) + if (m->m_pkthdr.csum_flags & CSUM_IP_UDP && csum == 0) csum = 0xffff; offset += m->m_pkthdr.csum_data; /* checksum offset */ @@ -1296,11 +1287,11 @@ ip_mloopback(struct ifnet *ifp, struct m copym = m_pullup(copym, hlen); if (copym != NULL) { /* If needed, compute the checksum and mark it as valid. */ - if (copym->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if (copym->m_pkthdr.csum_flags & (CSUM_IP_UDP|CSUM_IP_TCP)) { in_delayed_cksum(copym); - copym->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + copym->m_pkthdr.csum_flags &= ~(CSUM_IP_UDP|CSUM_IP_TCP); copym->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + CSUM_L4_CALC | CSUM_L4_VALID; copym->m_pkthdr.csum_data = 0xffff; } /* Modified: user/andre/tcp_workqueue/sys/netinet/sctp_input.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/sctp_input.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/sctp_input.c Mon Nov 19 18:04:17 2012 (r243291) @@ -6064,9 +6064,15 @@ sctp_input_with_port(struct mbuf *i_pak, #if defined(SCTP_WITH_NO_CSUM) SCTP_STAT_INCR(sctps_recvnocrc); #else - if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { + if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + (CSUM_L4_CALC | CSUM_L4_VALID)) { SCTP_STAT_INCR(sctps_recvhwcrc); compute_crc = 0; + } else if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + CSUM_L4_CALC) { + SCTP_STAT_INCR(sctps_badsum); + SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors); + goto out; } else { SCTP_STAT_INCR(sctps_recvswcrc); compute_crc = 1; Modified: user/andre/tcp_workqueue/sys/netinet/sctp_os_bsd.h ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/sctp_os_bsd.h Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/sctp_os_bsd.h Mon Nov 19 18:04:17 2012 (r243291) @@ -366,8 +366,8 @@ typedef struct callout sctp_os_timer_t; #define SCTP_RELEASE_HEADER(m) #define SCTP_RELEASE_PKT(m) sctp_m_freem(m) #define SCTP_ENABLE_UDP_CSUM(m) do { \ - m->m_pkthdr.csum_flags = CSUM_UDP; \ - m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); \ + m->m_pkthdr.csum_flags = CSUM_IP_UDP; \ + m->m_pkthdr.csum_l4hlen = sizeof(struct udphdr); \ } while (0) #define SCTP_GET_PKT_VRFID(m, vrf_id) ((vrf_id = SCTP_DEFAULT_VRFID) != SCTP_DEFAULT_VRFID) Modified: user/andre/tcp_workqueue/sys/netinet/sctp_output.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/sctp_output.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/sctp_output.c Mon Nov 19 18:04:17 2012 (r243291) @@ -4129,7 +4129,7 @@ sctp_lowlevel_chunk_output(struct sctp_i #if defined(SCTP_WITH_NO_CSUM) SCTP_STAT_INCR(sctps_sendnocrc); #else - m->m_pkthdr.csum_flags = CSUM_SCTP; + m->m_pkthdr.csum_flags = CSUM_IP_SCTP; m->m_pkthdr.csum_l4hlen = sizeof(struct sctphdr); SCTP_STAT_INCR(sctps_sendhwcrc); #endif @@ -4478,7 +4478,7 @@ sctp_lowlevel_chunk_output(struct sctp_i #if defined(SCTP_WITH_NO_CSUM) SCTP_STAT_INCR(sctps_sendnocrc); #else - m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6; + m->m_pkthdr.csum_flags = CSUM_IP6_SCTP; m->m_pkthdr.csum_l4hlen = sizeof(struct sctphdr); SCTP_STAT_INCR(sctps_sendhwcrc); #endif @@ -11005,7 +11005,7 @@ sctp_send_resp_msg(struct sockaddr *src, #if defined(SCTP_WITH_NO_CSUM) SCTP_STAT_INCR(sctps_sendnocrc); #else - mout->m_pkthdr.csum_flags = CSUM_SCTP; + mout->m_pkthdr.csum_flags = CSUM_IP_SCTP; mout->m_pkthdr.csum_l4hlen = sizeof(struct sctphdr); SCTP_STAT_INCR(sctps_sendhwcrc); #endif @@ -11035,7 +11035,7 @@ sctp_send_resp_msg(struct sockaddr *src, #if defined(SCTP_WITH_NO_CSUM) SCTP_STAT_INCR(sctps_sendnocrc); #else - mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6; + mout->m_pkthdr.csum_flags = CSUM_IP6_SCTP; mout->m_pkthdr.csum_l4hlen = sizeof(struct sctphdr); SCTP_STAT_INCR(sctps_sendhwcrc); #endif Modified: user/andre/tcp_workqueue/sys/netinet/siftr.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/siftr.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/siftr.c Mon Nov 19 18:04:17 2012 (r243291) @@ -904,7 +904,7 @@ siftr_chkpkt(void *arg, struct mbuf **m, siftr_siftdata(pn, inp, tp, INP_IPV4, dir, inp_locally_locked); if (siftr_generate_hashes) { - if ((*m)->m_pkthdr.csum_flags & CSUM_TCP) { + if ((*m)->m_pkthdr.csum_flags & CSUM_IP_TCP) { /* * For outbound packets, the TCP checksum isn't * calculated yet. This is a problem for our packet @@ -915,7 +915,7 @@ siftr_chkpkt(void *arg, struct mbuf **m, * software. We unset the CSUM_TCP flag so the lower * layers don't recalc it. */ - (*m)->m_pkthdr.csum_flags &= ~CSUM_TCP; + (*m)->m_pkthdr.csum_flags &= ~CSUM_IP_TCP; /* * Calculate the TCP checksum in software and assign Modified: user/andre/tcp_workqueue/sys/netinet/tcp_input.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_input.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/tcp_input.c Mon Nov 19 18:04:17 2012 (r243291) @@ -614,16 +614,13 @@ tcp_input(struct mbuf *m, int off0) ip6 = mtod(m, struct ip6_hdr *); th = (struct tcphdr *)((caddr_t)ip6 + off0); tlen = sizeof(*ip6) + ntohs(ip6->ip6_plen) - off0; - if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { - 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) { + + if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + CSUM_L4_CALC) { + TCPSTAT_INC(tcps_rcvbadsum); + goto drop; + } else if (!(m->m_pkthdr.csum_flags & CSUM_L4_VALID) && + in6_cksum(m, IPPROTO_TCP, off0, tlen)) { TCPSTAT_INC(tcps_rcvbadsum); goto drop; } @@ -666,16 +663,11 @@ tcp_input(struct mbuf *m, int off0) th = (struct tcphdr *)((caddr_t)ip + off0); tlen = ntohs(ip->ip_len) - off0; - 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 = in_pseudo(ip->ip_src.s_addr, - ip->ip_dst.s_addr, - htonl(m->m_pkthdr.csum_data + tlen + - IPPROTO_TCP)); - th->th_sum ^= 0xffff; - } else { + if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + CSUM_L4_CALC) { + TCPSTAT_INC(tcps_rcvbadsum); + goto drop; + } else if (!(m->m_pkthdr.csum_flags & CSUM_L4_VALID)) { struct ipovly *ipov = (struct ipovly *)ip; /* @@ -685,10 +677,11 @@ tcp_input(struct mbuf *m, int off0) bzero(ipov->ih_x1, sizeof(ipov->ih_x1)); ipov->ih_len = htons(tlen); th->th_sum = in_cksum(m, len); - } - if (th->th_sum) { - TCPSTAT_INC(tcps_rcvbadsum); - goto drop; + + if (th->th_sum) { + TCPSTAT_INC(tcps_rcvbadsum); + goto drop; + } } /* Re-initialization for later version check */ ip->ip_v = IPVERSION; @@ -3610,7 +3603,7 @@ tcp_mss(struct tcpcb *tp, int offer) SOCKBUF_UNLOCK(&so->so_rcv); /* Check the interface for TSO capabilities. */ - if (mtuflags & CSUM_TSO) + if (mtuflags & CSUM_IP_TSO) tp->t_flags |= TF_TSO; } Modified: user/andre/tcp_workqueue/sys/netinet/tcp_lro.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_lro.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/tcp_lro.c Mon Nov 19 18:04:17 2012 (r243291) @@ -211,8 +211,8 @@ tcp_lro_flush(struct lro_ctrl *lc, struc ip6 = le->le_ip6; ip6->ip6_plen = p_len; th = (struct tcphdr *)(ip6 + 1); - le->m_head->m_pkthdr.csum_flags = CSUM_DATA_VALID | - CSUM_PSEUDO_HDR; + le->m_head->m_pkthdr.csum_flags = CSUM_L4_CALC | + CSUM_L4_VALID; le->p_len += ETHER_HDR_LEN + sizeof(*ip6); break; } @@ -242,8 +242,8 @@ tcp_lro_flush(struct lro_ctrl *lc, struc #endif ip4->ip_len = p_len; th = (struct tcphdr *)(ip4 + 1); - le->m_head->m_pkthdr.csum_flags = CSUM_DATA_VALID | - CSUM_PSEUDO_HDR | CSUM_IP_CHECKED | CSUM_IP_VALID; + le->m_head->m_pkthdr.csum_flags = CSUM_L4_CALC | + CSUM_L4_VALID | CSUM_L3_CALC | CSUM_L3_VALID; le->p_len += ETHER_HDR_LEN; break; } @@ -310,7 +310,6 @@ static int tcp_lro_rx_ipv4(struct lro_ctrl *lc, struct mbuf *m, struct ip *ip4, struct tcphdr **th) { - int csum_flags; uint16_t csum; if (ip4->ip_p != IPPROTO_TCP) @@ -325,18 +324,17 @@ tcp_lro_rx_ipv4(struct lro_ctrl *lc, str return (TCP_LRO_CANNOT); /* Legacy IP has a header checksum that needs to be correct. */ - csum_flags = m->m_pkthdr.csum_flags; - if (csum_flags & CSUM_IP_CHECKED) { - if (__predict_false((csum_flags & CSUM_IP_VALID) == 0)) { - lc->lro_bad_csum++; - return (TCP_LRO_CANNOT); - } - } else { + if ((m->m_pkthdr.csum_flags & (CSUM_L3_CALC | CSUM_L3_VALID)) == + CSUM_L3_CALC) { + lc->lro_bad_csum++; + return (TCP_LRO_CANNOT); + } else if (!(m->m_pkthdr.csum_flags & CSUM_L3_VALID)) { csum = in_cksum_hdr(ip4); if (__predict_false((csum ^ 0xffff) != 0)) { lc->lro_bad_csum++; return (TCP_LRO_CANNOT); } + m->m_pkthdr.csum_flags |= (CSUM_L3_CALC | CSUM_L3_VALID); } /* Find the TCP header (we assured there are no IP options). */ Modified: user/andre/tcp_workqueue/sys/netinet/tcp_output.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_output.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/tcp_output.c Mon Nov 19 18:04:17 2012 (r243291) @@ -1085,7 +1085,7 @@ send: * ip6_plen is not need to be filled now, and will be filled * in ip6_output. */ - m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; + m->m_pkthdr.csum_flags = CSUM_IP6_TCP; th->th_sum = in6_cksum_pseudo(ip6, sizeof(struct tcphdr) + optlen + len, IPPROTO_TCP, 0); } @@ -1095,7 +1095,7 @@ send: #endif #ifdef INET { - m->m_pkthdr.csum_flags = CSUM_TCP; + m->m_pkthdr.csum_flags = CSUM_IP_TCP; th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(sizeof(struct tcphdr) + IPPROTO_TCP + len + optlen)); @@ -1113,7 +1113,10 @@ send: if (tso) { KASSERT(len > tp->t_maxopd - optlen, ("%s: len <= tso_segsz", __func__)); - m->m_pkthdr.csum_flags |= CSUM_TSO; + if (isipv6) + m->m_pkthdr.csum_flags |= CSUM_IP6_TSO; + else + m->m_pkthdr.csum_flags |= CSUM_IP_TSO; m->m_pkthdr.tso_segsz = tp->t_maxopd - optlen; } Modified: user/andre/tcp_workqueue/sys/netinet/tcp_subr.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_subr.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/tcp_subr.c Mon Nov 19 18:04:17 2012 (r243291) @@ -623,12 +623,10 @@ tcp_respond(struct tcpcb *tp, void *ipge nth->th_win = htons((u_short)win); nth->th_urp = 0; - m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); + m->m_pkthdr.csum_l4hlen = sizeof(struct tcphdr); #ifdef INET6 if (isipv6) { - m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; - nth->th_sum = in6_cksum_pseudo(ip6, - tlen - sizeof(struct ip6_hdr), IPPROTO_TCP, 0); + m->m_pkthdr.csum_flags = CSUM_IP6_TCP; ip6->ip6_hlim = in6_selecthlim(tp != NULL ? tp->t_inpcb : NULL, NULL); } @@ -638,9 +636,7 @@ tcp_respond(struct tcpcb *tp, void *ipge #endif #ifdef INET { - m->m_pkthdr.csum_flags = CSUM_TCP; - 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_IP_TCP; } #endif /* INET */ #ifdef TCPDEBUG @@ -1744,8 +1740,8 @@ tcp_maxmtu(struct in_conninfo *inc, int /* Report additional interface capabilities. */ if (flags != NULL) { if (ifp->if_capenable & IFCAP_TSO4 && - ifp->if_hwassist & CSUM_TSO) - *flags |= CSUM_TSO; + ifp->if_hwassist & CSUM_IP_TSO) + *flags |= CSUM_IP_TSO; } RTFREE(sro.ro_rt); } @@ -1781,8 +1777,8 @@ tcp_maxmtu6(struct in_conninfo *inc, int /* Report additional interface capabilities. */ if (flags != NULL) { if (ifp->if_capenable & IFCAP_TSO6 && - ifp->if_hwassist & CSUM_TSO) - *flags |= CSUM_TSO; + ifp->if_hwassist & CSUM_IP6_TSO) + *flags |= CSUM_IP6_TSO; } RTFREE(sro6.ro_rt); } Modified: user/andre/tcp_workqueue/sys/netinet/tcp_syncache.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_syncache.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/tcp_syncache.c Mon Nov 19 18:04:17 2012 (r243291) @@ -1509,12 +1509,10 @@ syncache_respond(struct syncache *sc) optlen = 0; M_SETFIB(m, sc->sc_inc.inc_fibnum); - m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); + m->m_pkthdr.csum_l4hlen = sizeof(struct tcphdr) + optlen; #ifdef INET6 if (sc->sc_inc.inc_flags & INC_ISIPV6) { - m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; - th->th_sum = in6_cksum_pseudo(ip6, tlen + optlen - hlen, - IPPROTO_TCP, 0); + m->m_pkthdr.csum_flags = CSUM_IP6_TCP; ip6->ip6_hlim = in6_selecthlim(NULL, NULL); error = ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); } @@ -1524,9 +1522,7 @@ syncache_respond(struct syncache *sc) #endif #ifdef INET { - m->m_pkthdr.csum_flags = CSUM_TCP; - 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_IP_TCP; #ifdef TCP_OFFLOAD if (ADDED_BY_TOE(sc)) { struct toedev *tod = sc->sc_tod; Modified: user/andre/tcp_workqueue/sys/netinet/tcp_timewait.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/tcp_timewait.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/tcp_timewait.c Mon Nov 19 18:04:17 2012 (r243291) @@ -575,12 +575,10 @@ tcp_twrespond(struct tcptw *tw, int flag th->th_flags = flags; th->th_win = htons(tw->last_win); - m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); + m->m_pkthdr.csum_l4hlen = sizeof(struct tcphdr) + optlen; #ifdef INET6 if (isipv6) { - m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; - th->th_sum = in6_cksum_pseudo(ip6, - sizeof(struct tcphdr) + optlen, IPPROTO_TCP, 0); + m->m_pkthdr.csum_flags = CSUM_IP6_TCP; ip6->ip6_hlim = in6_selecthlim(inp, NULL); error = ip6_output(m, inp->in6p_outputopts, NULL, (tw->tw_so_options & SO_DONTROUTE), NULL, NULL, inp); @@ -591,9 +589,7 @@ tcp_twrespond(struct tcptw *tw, int flag #endif #ifdef INET { - m->m_pkthdr.csum_flags = CSUM_TCP; - 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_IP_TCP; ip->ip_len = htons(m->m_pkthdr.len); if (V_path_mtu_discovery) ip->ip_off |= htons(IP_DF); Modified: user/andre/tcp_workqueue/sys/netinet/udp_usrreq.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet/udp_usrreq.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet/udp_usrreq.c Mon Nov 19 18:04:17 2012 (r243291) @@ -410,19 +410,15 @@ udp_input(struct mbuf *m, int off) /* * Checksum extended UDP header and data. + * NB: UDP doesn't require the checksum to be present. */ if (uh->uh_sum) { - u_short uh_sum; + u_short uh_sum = 0; - if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { - if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) - uh_sum = m->m_pkthdr.csum_data; - else - uh_sum = in_pseudo(ip->ip_src.s_addr, - ip->ip_dst.s_addr, htonl((u_short)len + - m->m_pkthdr.csum_data + IPPROTO_UDP)); - uh_sum ^= 0xffff; - } else { + if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + CSUM_L4_CALC) { + uh_sum = 0x1; /* Failed checksum check. */ + } else if (!(m->m_pkthdr.csum_flags & CSUM_L4_VALID)) { char b[9]; bcopy(((struct ipovly *)ip)->ih_x1, b, 9); @@ -1226,7 +1222,7 @@ udp_output(struct inpcb *inp, struct mbu faddr.s_addr = INADDR_BROADCAST; ui->ui_sum = in_pseudo(ui->ui_src.s_addr, faddr.s_addr, htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP)); - m->m_pkthdr.csum_flags = CSUM_UDP; + m->m_pkthdr.csum_flags = CSUM_IP_UDP; m->m_pkthdr.csum_l4hlen = sizeof(struct udphdr); } else ui->ui_sum = 0; @@ -1387,8 +1383,8 @@ udp4_espdecap(struct inpcb *inp, struct * We cannot yet update the cksums so clear any * h/w cksum flags as they are no longer valid. */ - if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) - m->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID|CSUM_PSEUDO_HDR); + if (m->m_pkthdr.csum_flags & CSUM_L4_CALC) + m->m_pkthdr.csum_flags &= ~(CSUM_L4_CALC|CSUM_L4_VALID); (void) ipsec4_common_input(m, iphlen, ip->ip_p); return (NULL); /* NB: consumed, bypass processing. */ Modified: user/andre/tcp_workqueue/sys/netinet6/ip6_forward.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet6/ip6_forward.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet6/ip6_forward.c Mon Nov 19 18:04:17 2012 (r243291) @@ -577,14 +577,16 @@ skip_routing: m->m_flags |= M_FASTFWD_OURS; if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { + if (m->m_pkthdr.csum_flags & + (CSUM_IP6_UDP|CSUM_IP6_TCP)) { m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; + CSUM_L4_CALC | CSUM_L4_VALID; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; + if (m->m_pkthdr.csum_flags & CSUM_IP6_SCTP) + m->m_pkthdr.csum_flags |= + CSUM_L4_CALC | CSUM_L4_VALID; #endif error = netisr_queue(NETISR_IPV6, m); goto out; @@ -596,14 +598,13 @@ skip_routing: if (m->m_flags & M_FASTFWD_OURS) { if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { - m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; + if (m->m_pkthdr.csum_flags & (CSUM_IP6_UDP|CSUM_IP6_TCP)) { + m->m_pkthdr.csum_flags |= CSUM_L4_CALC | CSUM_L4_VALID; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; + if (m->m_pkthdr.csum_flags & CSUM_IP6_SCTP) + m->m_pkthdr.csum_flags |= CSUM_L4_CALC | CSUM_L4_VALID; #endif error = netisr_queue(NETISR_IPV6, m); goto out; Modified: user/andre/tcp_workqueue/sys/netinet6/ip6_ipsec.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet6/ip6_ipsec.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet6/ip6_ipsec.c Mon Nov 19 18:04:17 2012 (r243291) @@ -288,11 +288,11 @@ ip6_ipsec_output(struct mbuf **m, struct * For IPv6 we do delayed checksums in ip6_output.c. */ #ifdef INET - if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + if ((*m)->m_pkthdr.csum_flags & (CSUM_IP_UDP|CSUM_IP_TCP)) { ipseclog((LOG_DEBUG, "%s: we do not support IPv4 over IPv6", __func__)); in_delayed_cksum(*m); - (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + (*m)->m_pkthdr.csum_flags &= ~(CSUM_IP_UDP|CSUM_IP_TCP); } #endif Modified: user/andre/tcp_workqueue/sys/netinet6/ip6_output.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet6/ip6_output.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet6/ip6_output.c Mon Nov 19 18:04:17 2012 (r243291) @@ -307,15 +307,15 @@ ip6_output(struct mbuf *m0, struct ip6_p /* * Do delayed checksums now, as we may send before returning. */ - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { + if (m->m_pkthdr.csum_flags & (CSUM_IP6_UDP|CSUM_IP6_TCP)) { plen = m->m_pkthdr.len - sizeof(*ip6); in6_delayed_cksum(m, plen, sizeof(struct ip6_hdr)); - m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; + m->m_pkthdr.csum_flags &= ~(CSUM_IP6_UDP|CSUM_IP6_TCP); } #ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) { + if (m->m_pkthdr.csum_flags & CSUM_IP6_SCTP) { sctp_delayed_cksum(m, sizeof(struct ip6_hdr)); - m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; + m->m_pkthdr.csum_flags &= ~CSUM_IP6_SCTP; } #endif case 0: /* No IPSec */ @@ -898,14 +898,16 @@ again: m->m_flags |= M_FASTFWD_OURS; if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { + if (m->m_pkthdr.csum_flags & + (CSUM_IP6_UDP|CSUM_IP6_TCP)) { m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; + CSUM_L4_CALC | CSUM_L4_VALID; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; + m->m_pkthdr.csum_flags |= + CSUM_L4_CALC | CSUM_L4_VALID; #endif error = netisr_queue(NETISR_IPV6, m); goto done; @@ -917,14 +919,14 @@ again: if (m->m_flags & M_FASTFWD_OURS) { if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { + if (m->m_pkthdr.csum_flags & (CSUM_IP6_UDP|CSUM_IP6_TCP)) { m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID_IPV6 | CSUM_PSEUDO_HDR; + CSUM_L4_CALC | CSUM_L4_VALID; m->m_pkthdr.csum_data = 0xffff; } #ifdef SCTP if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; + m->m_pkthdr.csum_flags |= CSUM_L4_CALC | CSUM_L4_VALID; #endif error = netisr_queue(NETISR_IPV6, m); goto done; @@ -972,13 +974,13 @@ passout: * XXX-BZ Need a framework to know when the NIC can handle it, even * with ext. hdrs. */ - if (sw_csum & CSUM_DELAY_DATA_IPV6) { - sw_csum &= ~CSUM_DELAY_DATA_IPV6; + if (sw_csum & (CSUM_IP6_UDP|CSUM_IP6_TCP)) { + sw_csum &= ~(CSUM_IP6_UDP|CSUM_IP6_TCP); in6_delayed_cksum(m, plen, sizeof(struct ip6_hdr)); } #ifdef SCTP - if (sw_csum & CSUM_SCTP_IPV6) { - sw_csum &= ~CSUM_SCTP_IPV6; + if (sw_csum & CSUM_IP6_SCTP) { + sw_csum &= ~CSUM_IP6_SCTP; sctp_delayed_cksum(m, sizeof(struct ip6_hdr)); } #endif @@ -1091,14 +1093,14 @@ passout: * fragmented packets, then do it here. * XXX-BZ handle the hw offloading case. Need flags. */ - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { + if (m->m_pkthdr.csum_flags & (CSUM_IP6_UDP|CSUM_IP6_TCP)) { in6_delayed_cksum(m, plen, hlen); - m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; + m->m_pkthdr.csum_flags &= ~(CSUM_IP6_UDP|CSUM_IP6_TCP); } #ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) { + if (m->m_pkthdr.csum_flags & CSUM_IP6_SCTP) { sctp_delayed_cksum(m, hlen); - m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; + m->m_pkthdr.csum_flags &= ~CSUM_IP6_SCTP; } #endif mnext = &m->m_nextpkt; Modified: user/andre/tcp_workqueue/sys/netinet6/sctp6_usrreq.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet6/sctp6_usrreq.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet6/sctp6_usrreq.c Mon Nov 19 18:04:17 2012 (r243291) @@ -169,9 +169,15 @@ sctp6_input(struct mbuf **i_pak, int *of #if defined(SCTP_WITH_NO_CSUM) SCTP_STAT_INCR(sctps_recvnocrc); #else - if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { + if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + (CSUM_L4_CALC | CSUM_L4_VALID)) { SCTP_STAT_INCR(sctps_recvhwcrc); compute_crc = 0; + } else if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + CSUM_L4_CALC) { + SCTP_STAT_INCR(sctps_badsum); + SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors); + goto out; } else { SCTP_STAT_INCR(sctps_recvswcrc); compute_crc = 1; Modified: user/andre/tcp_workqueue/sys/netinet6/udp6_usrreq.c ============================================================================== --- user/andre/tcp_workqueue/sys/netinet6/udp6_usrreq.c Mon Nov 19 17:33:45 2012 (r243290) +++ user/andre/tcp_workqueue/sys/netinet6/udp6_usrreq.c Mon Nov 19 18:04:17 2012 (r243291) @@ -183,7 +183,7 @@ udp6_input(struct mbuf **mp, int *offp, int plen, ulen; struct sockaddr_in6 fromsa; struct m_tag *fwd_tag; - uint16_t uh_sum; + uint16_t uh_sum = 0; ifp = m->m_pkthdr.rcvif; ip6 = mtod(m, struct ip6_hdr *); @@ -228,14 +228,10 @@ udp6_input(struct mbuf **mp, int *offp, goto badunlocked; } - if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) { - if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) - uh_sum = m->m_pkthdr.csum_data; - else - uh_sum = in6_cksum_pseudo(ip6, ulen, - IPPROTO_UDP, m->m_pkthdr.csum_data); - uh_sum ^= 0xffff; - } else + if ((m->m_pkthdr.csum_flags & (CSUM_L4_CALC|CSUM_L4_VALID)) == + CSUM_L4_CALC) { + uh_sum = 1; + } else if (!(m->m_pkthdr.csum_flags & CSUM_L4_VALID)) uh_sum = in6_cksum(m, IPPROTO_UDP, off, ulen); if (uh_sum != 0) { @@ -780,8 +776,8 @@ udp6_output(struct inpcb *inp, struct mb ip6->ip6_dst = *faddr; udp6->uh_sum = in6_cksum_pseudo(ip6, plen, IPPROTO_UDP, 0); - m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; - m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); + m->m_pkthdr.csum_flags = CSUM_IP6_UDP; + m->m_pkthdr.csum_l4hlen = sizeof(struct udphdr); flags = 0; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***