Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c54cdc31 authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller
Browse files

ixgbe/ixgbevf: Don't use lco_csum to compute IPv4 checksum



In the case of IPIP and SIT tunnel frames the outer transport header
offset is actually set to the same offset as the inner transport header.
This results in the lco_csum call not doing any checksum computation over
the inner IPv4/v6 header data.

In order to account for that I am updating the code so that we determine
the location to start the checksum ourselves based on the location of the
IPv4 header and the length.

Fixes: b83e3010 ("ixgbe/ixgbevf: Add support for GSO partial")
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 516165a1
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -7277,11 +7277,15 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,


	/* initialize outer IP header fields */
	/* initialize outer IP header fields */
	if (ip.v4->version == 4) {
	if (ip.v4->version == 4) {
		unsigned char *csum_start = skb_checksum_start(skb);
		unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);

		/* IP header will have to cancel out any data that
		/* IP header will have to cancel out any data that
		 * is not a part of the outer IP header
		 * is not a part of the outer IP header
		 */
		 */
		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
		ip.v4->check = csum_fold(csum_partial(trans_start,
						  csum_unfold(l4.tcp->check)));
						      csum_start - trans_start,
						      0));
		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;


		ip.v4->tot_len = 0;
		ip.v4->tot_len = 0;
+6 −2
Original line number Original line Diff line number Diff line
@@ -3329,11 +3329,15 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,


	/* initialize outer IP header fields */
	/* initialize outer IP header fields */
	if (ip.v4->version == 4) {
	if (ip.v4->version == 4) {
		unsigned char *csum_start = skb_checksum_start(skb);
		unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);

		/* IP header will have to cancel out any data that
		/* IP header will have to cancel out any data that
		 * is not a part of the outer IP header
		 * is not a part of the outer IP header
		 */
		 */
		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
		ip.v4->check = csum_fold(csum_partial(trans_start,
						  csum_unfold(l4.tcp->check)));
						      csum_start - trans_start,
						      0));
		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;


		ip.v4->tot_len = 0;
		ip.v4->tot_len = 0;