diff options
author | arybchik <arybchik@FreeBSD.org> | 2015-05-21 09:05:13 +0000 |
---|---|---|
committer | arybchik <arybchik@FreeBSD.org> | 2015-05-21 09:05:13 +0000 |
commit | 037a819653dd8bb6c13f74af78dad6b6a61701dc (patch) | |
tree | b6bfeb4b26ebb4fa5492212864fc0dcba3fbe333 | |
parent | 24b8928a5d1c3110812356011e497e18a22da428 (diff) | |
download | FreeBSD-src-037a819653dd8bb6c13f74af78dad6b6a61701dc.zip FreeBSD-src-037a819653dd8bb6c13f74af78dad6b6a61701dc.tar.gz |
MFC: r282940
sfxge: LRO may be done only if checksums are OK
Also it is cheaper to check Rx descriptor flags than TCP protocol in IP
header.
Sponsored by: Solarflare Communications, Inc.
-rw-r--r-- | sys/dev/sfxge/sfxge_rx.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/sys/dev/sfxge/sfxge_rx.c b/sys/dev/sfxge/sfxge_rx.c index cbb52af..673de43 100644 --- a/sys/dev/sfxge/sfxge_rx.c +++ b/sys/dev/sfxge/sfxge_rx.c @@ -681,15 +681,18 @@ sfxge_lro(struct sfxge_rxq *rxq, struct sfxge_rx_sw_desc *rx_buf) */ if (l3_proto == htons(ETHERTYPE_IP)) { struct ip *iph = nh; - if ((iph->ip_p - IPPROTO_TCP) | - (iph->ip_hl - (sizeof(*iph) >> 2u)) | + + KASSERT(iph->ip_p == IPPROTO_TCP, + ("IPv4 protocol is not TCP, but packet marker is set")); + if ((iph->ip_hl - (sizeof(*iph) >> 2u)) | (iph->ip_off & htons(IP_MF | IP_OFFMASK))) goto deliver_now; th = (struct tcphdr *)(iph + 1); } else if (l3_proto == htons(ETHERTYPE_IPV6)) { struct ip6_hdr *iph = nh; - if (iph->ip6_nxt != IPPROTO_TCP) - goto deliver_now; + + KASSERT(iph->ip6_nxt == IPPROTO_TCP, + ("IPv6 next header is not TCP, but packet marker is set")); l2_id |= SFXGE_LRO_L2_ID_IPV6; th = (struct tcphdr *)(iph + 1); } else { @@ -834,7 +837,9 @@ sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop) /* Pass packet up the stack or into LRO (pipelined) */ if (prev != NULL) { - if (lro_enabled) + if (lro_enabled && + ((prev->flags & (EFX_PKT_TCP | EFX_CKSUM_TCPUDP)) == + (EFX_PKT_TCP | EFX_CKSUM_TCPUDP))) sfxge_lro(rxq, prev); else sfxge_rx_deliver(sc, prev); @@ -853,7 +858,9 @@ discard: /* Pass last packet up the stack or into LRO */ if (prev != NULL) { - if (lro_enabled) + if (lro_enabled && + ((prev->flags & (EFX_PKT_TCP | EFX_CKSUM_TCPUDP)) == + (EFX_PKT_TCP | EFX_CKSUM_TCPUDP))) sfxge_lro(rxq, prev); else sfxge_rx_deliver(sc, prev); |