Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 May 2019 13:40:51 +0000 (UTC)
From:      Marcin Wojtas <mw@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r348410 - head/sys/dev/ena
Message-ID:  <201905301340.x4UDeplw075259@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mw
Date: Thu May 30 13:40:51 2019
New Revision: 348410
URL: https://svnweb.freebsd.org/changeset/base/348410

Log:
  Fix Tx offloads for fragmented pkt headers in ENA
  
  If the headers of the packets are split into multiple segments of the
  mbuf chain, the previous version of ena_tx_csum which was assuming,
  that all segments will lay in the first mbuf, will eventually fail to
  map the headers properties to meta descriptor.
  
  That will cause Tx checksum offload to do not work and was leading to
  memory corruption. It could even cause the crash of the system.
  
  Submitted by:  Michal Krawczyk <mk@semihalf.com>
  Obtained from: Semihalf
  Sponsored by:  Amazon, Inc.

Modified:
  head/sys/dev/ena/ena.c

Modified: head/sys/dev/ena/ena.c
==============================================================================
--- head/sys/dev/ena/ena.c	Thu May 30 13:39:25 2019	(r348409)
+++ head/sys/dev/ena/ena.c	Thu May 30 13:40:51 2019	(r348410)
@@ -2683,6 +2683,7 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct 
 {
 	struct ena_com_tx_meta *ena_meta;
 	struct ether_vlan_header *eh;
+	struct mbuf *mbuf_next;
 	u32 mss;
 	bool offload;
 	uint16_t etype;
@@ -2690,6 +2691,7 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct 
 	struct ip *ip;
 	int iphlen;
 	struct tcphdr *th;
+	int offset;
 
 	offload = false;
 	ena_meta = &ena_tx_ctx->ena_meta;
@@ -2719,9 +2721,12 @@ ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct 
 		ehdrlen = ETHER_HDR_LEN;
 	}
 
-	ip = (struct ip *)(mbuf->m_data + ehdrlen);
+	mbuf_next = m_getptr(mbuf, ehdrlen, &offset);
+	ip = (struct ip *)(mtodo(mbuf_next, offset));
 	iphlen = ip->ip_hl << 2;
-	th = (struct tcphdr *)((caddr_t)ip + iphlen);
+
+	mbuf_next = m_getptr(mbuf, iphlen + ehdrlen, &offset);
+	th = (struct tcphdr *)(mtodo(mbuf_next, offset));
 
 	if ((mbuf->m_pkthdr.csum_flags & CSUM_IP) != 0) {
 		ena_tx_ctx->l3_csum_enable = 1;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905301340.x4UDeplw075259>