- if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
- if (m->m_pkthdr.csum_flags & CSUM_TCP_SUM16) {
- u_short pseudo;
- char b[9];
-
- bcopy(ipov->ih_x1, b, sizeof (ipov->ih_x1));
- bzero(ipov->ih_x1, sizeof (ipov->ih_x1));
- ipov->ih_len = (u_short)tlen;
-#if BYTE_ORDER != BIG_ENDIAN
- HTONS(ipov->ih_len);
-#endif
- pseudo = in_cksum(m, sizeof (struct ip));
- bcopy(b, ipov->ih_x1, sizeof (ipov->ih_x1));
-
- th->th_sum = in_addword(pseudo, (m->m_pkthdr.csum_data & 0xFFFF));
- } else {
- 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 +
- ip->ip_len + IPPROTO_TCP));
- }
- th->th_sum ^= 0xffff;
- } else {
- char b[9];
- /*
- * Checksum extended TCP header and data.
- */
- bcopy(ipov->ih_x1, b, sizeof (ipov->ih_x1));
- bzero(ipov->ih_x1, sizeof (ipov->ih_x1));
- ipov->ih_len = (u_short)tlen;
-#if BYTE_ORDER != BIG_ENDIAN
- HTONS(ipov->ih_len);
-#endif
- len = sizeof (struct ip) + tlen;
- th->th_sum = in_cksum(m, len);
- bcopy(b, ipov->ih_x1, sizeof (ipov->ih_x1));
-
- tcp_in_cksum_stats(len);
- }
- if (th->th_sum) {
- tcpstat.tcps_rcvbadsum++;
- if (ifp != NULL && ifp->if_tcp_stat != NULL) {
- atomic_add_64(&ifp->if_tcp_stat->badformat, 1);
+ /* we shouldn't get here for IP with options; hence sizeof (ip) */
+ if (tcp_input_checksum(AF_INET, m, th, sizeof(*ip), ip->ip_len)) {
+ if (lrodebug) {
+ printf("%s: bad xsum and drop m = 0x%llx.\n", __func__,
+ (uint64_t)VM_KERNEL_ADDRPERM(m));