Page MenuHomeFreeBSD

D31155.diff
No OneTemporary

D31155.diff

diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c
--- a/sys/netinet/tcp_lro.c
+++ b/sys/netinet/tcp_lro.c
@@ -101,6 +101,7 @@
counter_u64_t tcp_would_have_but;
counter_u64_t tcp_comp_total;
counter_u64_t tcp_uncomp_total;
+counter_u64_t tcp_bad_csums;
static unsigned tcp_lro_entries = TCP_LRO_ENTRIES;
SYSCTL_UINT(_net_inet_tcp_lro, OID_AUTO, entries,
@@ -128,6 +129,8 @@
&tcp_comp_total, "Number of mbufs queued with M_ACKCMP flags set");
SYSCTL_COUNTER_U64(_net_inet_tcp_lro, OID_AUTO, without_m_ackcmp, CTLFLAG_RD,
&tcp_uncomp_total, "Number of mbufs queued without M_ACKCMP");
+SYSCTL_COUNTER_U64(_net_inet_tcp_lro, OID_AUTO, lro_badcsum, CTLFLAG_RD,
+ &tcp_bad_csums, "Number of packets that the common code saw with bad csums");
void
tcp_lro_reg_mbufq(void)
@@ -1740,7 +1743,17 @@
if (__predict_false(V_ip6_forwarding != 0))
return (TCP_LRO_CANNOT);
#endif
-
+ if (((m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) !=
+ ((CSUM_DATA_VALID | CSUM_PSEUDO_HDR))) ||
+ (m->m_pkthdr.csum_data != 0xffff)) {
+ /*
+ * The checksum either did not have hardware offload
+ * or it was a bad checksum. We can't LRO such
+ * a packet.
+ */
+ counter_u64_add(tcp_bad_csums, 1);
+ return (TCP_LRO_CANNOT);
+ }
/* We expect a contiguous header [eh, ip, tcp]. */
pa = tcp_lro_parser(m, &po, &pi, true);
if (__predict_false(pa == NULL))
@@ -1858,9 +1871,19 @@
{
int error;
+ if (((m->m_pkthdr.csum_flags & (CSUM_DATA_VALID | CSUM_PSEUDO_HDR)) !=
+ ((CSUM_DATA_VALID | CSUM_PSEUDO_HDR))) ||
+ (m->m_pkthdr.csum_data != 0xffff)) {
+ /*
+ * The checksum either did not have hardware offload
+ * or it was a bad checksum. We can't LRO such
+ * a packet.
+ */
+ counter_u64_add(tcp_bad_csums, 1);
+ return (TCP_LRO_CANNOT);
+ }
/* get current time */
binuptime(&lc->lro_last_queue_time);
-
CURVNET_SET(lc->ifp->if_vnet);
error = tcp_lro_rx_common(lc, m, csum, true);
CURVNET_RESTORE();
@@ -1880,8 +1903,7 @@
}
/* check if packet is not LRO capable */
- if (__predict_false(mb->m_pkthdr.csum_flags == 0 ||
- (lc->ifp->if_capenable & IFCAP_LRO) == 0)) {
+ if (__predict_false((lc->ifp->if_capenable & IFCAP_LRO) == 0)) {
/* input packet to network layer */
(*lc->ifp->if_input) (lc->ifp, mb);
return;
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1520,6 +1520,7 @@
tcp_would_have_but = counter_u64_alloc(M_WAITOK);
tcp_comp_total = counter_u64_alloc(M_WAITOK);
tcp_uncomp_total = counter_u64_alloc(M_WAITOK);
+ tcp_bad_csums = counter_u64_alloc(M_WAITOK);
#ifdef TCPPCAP
tcp_pcap_init();
#endif
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1022,6 +1022,7 @@
extern counter_u64_t tcp_would_have_but;
extern counter_u64_t tcp_comp_total;
extern counter_u64_t tcp_uncomp_total;
+extern counter_u64_t tcp_bad_csums;
#ifdef NETFLIX_EXP_DETECTION
/* Various SACK attack thresholds */

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 12, 8:50 PM (20 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15772818
Default Alt Text
D31155.diff (2 KB)

Event Timeline