Index: sys/netinet/tcp_lro.c =================================================================== --- sys/netinet/tcp_lro.c +++ sys/netinet/tcp_lro.c @@ -1510,7 +1510,7 @@ uint32_t *ts_ptr; tcp_seq seq; int error, ip_len, hdr_len, locked = 0; - uint16_t eh_type, tcp_data_len, need_flush; + uint16_t eh_type, tcp_data_len, need_flush, have_tstmp_opt; #ifdef TCPHPTS uint16_t iptos; #endif @@ -1598,15 +1598,19 @@ ts_ptr = (uint32_t *)(th + 1); tcp_data_len -= hdr_len; hdr_len -= sizeof(*th); + if (hdr_len && (__predict_true(hdr_len == TCPOLEN_TSTAMP_APPA) || + (*ts_ptr == ntohl(TCPOPT_NOP<<24|TCPOPT_NOP<<16| + TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)))) + have_tstmp_opt = 1; + else + have_tstmp_opt = 1; if (th->th_flags & TH_SYN) return (TCP_LRO_CANNOT); if ((th->th_flags & ~(TH_ACK | TH_PUSH)) != 0) { need_flush = 1; } else need_flush = 0; - if (hdr_len != 0 && (__predict_false(hdr_len != TCPOLEN_TSTAMP_APPA) || - (*ts_ptr != ntohl(TCPOPT_NOP<<24|TCPOPT_NOP<<16| - TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)))) { + if (hdr_len != 0 && (__predict_false(have_tstmp_opt == 0))) { /* * We have an option besides Timestamps, maybe * it is a sack (most likely) which means we @@ -1832,7 +1836,8 @@ nm = m_getcl(M_NOWAIT, MT_DATA, (M_ACKCMP|M_PKTHDR)); else { nm = m_gethdr(M_NOWAIT, MT_DATA); - nm->m_flags |= M_ACKCMP; + if (nm) + nm->m_flags |= M_ACKCMP; } if (nm) { nm->m_pkthdr.rcvif = lc->ifp; @@ -1918,7 +1923,7 @@ le->next_seq = seq + tcp_data_len; le->ack_seq = th->th_ack; le->window = th->th_win; - if (hdr_len != 0) { + if ((hdr_len != 0) && have_tstmp_opt) { le->timestamp = 1; le->tsval = ntohl(*(ts_ptr + 1)); le->tsecr = *(ts_ptr + 2); @@ -2013,7 +2018,8 @@ nm = m_getcl(M_NOWAIT, MT_DATA, (M_ACKCMP|M_PKTHDR)); else { nm = m_gethdr(M_NOWAIT, MT_DATA); - nm->m_flags |= M_ACKCMP; + if (nm) + nm->m_flags |= M_ACKCMP; } if (nm) { nm->m_pkthdr.rcvif = lc->ifp;