All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic.
@ 2014-08-23  2:17 vyasevich
  2014-08-23  2:17 ` [PATCH 1/8] e1000e: Fix TSO with non-accelerated vlans vyasevich
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev
  Cc: Vladislav Yasevich, Jeff Kirsher, Jesse Brandeburg, Bruce Allan,
	Carolyn Wyborny, Don Skidmore, Greg Rose, Alex Duyck,
	John Ronciak, Mitch Williams, Linux NICS, e1000-devel,
	Rasesh Mody, Thadeu Lima de Souza Cascardo, Thomas Petazzoni,
	Shahed Shaikh, Jitendra Kalsaria, Ron Mercer, linux-driver,
	Chris Metcalf

From: Vladislav Yasevich <vyasevic@redhat.com>

I've recently ran across something rather interesting when testing vlans
from inside VMs.  In some scenarios I was getting awfull thruput.
Some debugging uncovered a very scary packet corruption.  I was
seeing packets that had original TSO length as IP total length
and their ip checksum was 0.  This was with e1000e driver.

A bit more debugging uncovered an assumption made by that driver
that skb->protocol will contain l3 protocol information.  This
was not the case in my setup since I manually turned off vlan
tx acceleration for the device.  This caused the driver to not
initialize the tso information correctly and resulted in
corrupt TSO frames on the wire.

I decided to do some auditing of the usage of skb->protocols
in the drivers.  Out of all the drivers, the included 8 appear
to be effected.  They all allow user to control vlan acceleration
settings, all support TSO on vlan devices, and all use
skb->protocol to decide how to encode TSO information.  Some
also have similar problems when initializing hw checksum information.
On such device, it is simple enough to reproduce the issue.
Simply turn off TX VLAN acceleration on the device, create a vlan,
and run you favorite network performance tool.

There is 1 driver I ran across that I belive will trigger a BUG
in the system when used with vlans.  That driver is tile/tilepro.c
I have not changed it in this patch set and would hope that
the maintainer has time to look at it.

Thanks
-vlad

Vladislav Yasevich (8):
  e1000e: Fix TSO with non-accelerated vlans
  e1000: Fix TSO for non-accelerated vlan traffic
  bna: Support TSO and partial checksum with non-accelerated vlans.
  ehea: Fix TSO and hw checksums with non-accelerated vlan packets.
  i40e: Fix TSO and hw checksums for non-accelerated vlan packets.
  i40evf: Fix TSO and hw checksums for non-accelerated vlan packets.
  mvneta: Fix TSO and checksum for non-acceleration vlan traffic
  qlge: Fix TSO for non-accelerated vlan traffic

 drivers/net/ethernet/brocade/bna/bnad.c       |  7 ++++---
 drivers/net/ethernet/ibm/ehea/ehea_main.c     |  2 +-
 drivers/net/ethernet/intel/e1000/e1000_main.c | 19 +++++++++++--------
 drivers/net/ethernet/intel/e1000e/netdev.c    | 21 +++++++++------------
 drivers/net/ethernet/intel/i40e/i40e_txrx.c   |  2 +-
 drivers/net/ethernet/intel/i40evf/i40e_txrx.c |  2 +-
 drivers/net/ethernet/marvell/mvneta.c         |  7 ++++---
 drivers/net/ethernet/qlogic/qlge/qlge_main.c  |  5 +++--
 8 files changed, 34 insertions(+), 31 deletions(-)

-- 
1.9.3

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/8] e1000e: Fix TSO with non-accelerated vlans
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
@ 2014-08-23  2:17 ` vyasevich
  2014-08-23  2:17 ` [PATCH 2/8] e1000: Fix TSO for non-accelerated vlan traffic vyasevich
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev
  Cc: Vladislav Yasevich, Linux NICS, e1000-devel, Bruce Allan,
	Jesse Brandeburg, John Ronciak

From: Vladislav Yasevich <vyasevic@redhat.com>

This device claims  TSO support for vlans.  It also allows a
user to control vlan acceleration offloading.  As such, it is
possible to turn off vlan acceleration and configure a vlan
which will continue to support TSO.

In such situation the packet passed down the the device will contain
a vlan header and skb->protocol will be set to ETH_P_8021Q.
The device assumes that skb->protocol contains network protocol
value and uses that value to set up TSO information.  This results
in corrupted frames sent on the wire.  Corruptions include
incorrect IP total length and invalid IP checksum.

This patch extract the protocol value correctly and corrects TSO
for non-accelerated traffic.

CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Bruce Allan <bruce.w.allan@intel.com>
CC: Carolyn Wyborny <carolyn.wyborny@intel.com>
CC: Don Skidmore <donald.c.skidmore@intel.com>
CC: Greg Rose <gregory.v.rose@intel.com>
CC: Alex Duyck <alexander.h.duyck@intel.com>
CC: John Ronciak <john.ronciak@intel.com>
CC: Mitch Williams <mitch.a.williams@intel.com>
CC: Linux NICS <linux.nics@intel.com>
CC: e1000-devel@lists.sourceforge.net
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/intel/e1000e/netdev.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 65c3aef..247335d 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -5164,7 +5164,8 @@ link_up:
 #define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
 #define E1000_TX_FLAGS_VLAN_SHIFT	16
 
-static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
+static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb,
+		     __be16 protocol)
 {
 	struct e1000_context_desc *context_desc;
 	struct e1000_buffer *buffer_info;
@@ -5183,7 +5184,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
 
 	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 	mss = skb_shinfo(skb)->gso_size;
-	if (skb->protocol == htons(ETH_P_IP)) {
+	if (protocol == htons(ETH_P_IP)) {
 		struct iphdr *iph = ip_hdr(skb);
 		iph->tot_len = 0;
 		iph->check = 0;
@@ -5231,7 +5232,8 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
 	return 1;
 }
 
-static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
+static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb,
+			  __be16 protocol)
 {
 	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct e1000_context_desc *context_desc;
@@ -5239,16 +5241,10 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
 	unsigned int i;
 	u8 css;
 	u32 cmd_len = E1000_TXD_CMD_DEXT;
-	__be16 protocol;
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL)
 		return false;
 
-	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
-		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
-	else
-		protocol = skb->protocol;
-
 	switch (protocol) {
 	case cpu_to_be16(ETH_P_IP):
 		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
@@ -5546,6 +5542,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 	int count = 0;
 	int tso;
 	unsigned int f;
+	__be16 protocol = vlan_get_protocol(skb);
 
 	if (test_bit(__E1000_DOWN, &adapter->state)) {
 		dev_kfree_skb_any(skb);
@@ -5620,7 +5617,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
 	first = tx_ring->next_to_use;
 
-	tso = e1000_tso(tx_ring, skb);
+	tso = e1000_tso(tx_ring, skb, protocol);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
@@ -5628,14 +5625,14 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
 	if (tso)
 		tx_flags |= E1000_TX_FLAGS_TSO;
-	else if (e1000_tx_csum(tx_ring, skb))
+	else if (e1000_tx_csum(tx_ring, skb, protocol))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
 	/* Old method was to assume IPv4 packet by default if TSO was enabled.
 	 * 82571 hardware supports TSO capabilities for IPv6 as well...
 	 * no longer assume, we must.
 	 */
-	if (skb->protocol == htons(ETH_P_IP))
+	if (protocol == htons(ETH_P_IP))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
 	if (unlikely(skb->no_fcs))
-- 
1.9.3


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/8] e1000: Fix TSO for non-accelerated vlan traffic
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
  2014-08-23  2:17 ` [PATCH 1/8] e1000e: Fix TSO with non-accelerated vlans vyasevich
@ 2014-08-23  2:17 ` vyasevich
  2014-08-23  2:17 ` [PATCH 3/8] bna: Support TSO and partial checksum with non-accelerated vlans vyasevich
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev
  Cc: Vladislav Yasevich, Jeff Kirsher, Jesse Brandeburg, Bruce Allan,
	Carolyn Wyborny, Don Skidmore, Greg Rose, Alex Duyck,
	John Ronciak, Mitch Williams, Linux NICS, e1000-devel

From: Vladislav Yasevich <vyasevic@redhat.com>

This device claims TSO and checksum support for vlans.  It also
allows a user to control vlan acceleration offloading.  As such,
it is possible to turn off vlan acceleration and configure a vlan
which will continue to support TSO.

In such situation the packet passed down the the device will contain
a vlan header and skb->protocol will be set to ETH_P_8021Q.
The device assumes that skb->protocol contains network protocol
value and uses that value to set up TSO and checksum information.
This will results in corrupted frames sent on the wire.

This patch extract the protocol value correctly and corrects TSO
for non-accelerated traffic.

CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Bruce Allan <bruce.w.allan@intel.com>
CC: Carolyn Wyborny <carolyn.wyborny@intel.com>
CC: Don Skidmore <donald.c.skidmore@intel.com>
CC: Greg Rose <gregory.v.rose@intel.com>
CC: Alex Duyck <alexander.h.duyck@intel.com>
CC: John Ronciak <john.ronciak@intel.com>
CC: Mitch Williams <mitch.a.williams@intel.com>
CC: Linux NICS <linux.nics@intel.com>
CC: e1000-devel@lists.sourceforge.net
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/intel/e1000/e1000_main.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index cbc330b..ad3d5d1 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -2674,7 +2674,8 @@ set_itr_now:
 #define E1000_TX_FLAGS_VLAN_SHIFT	16
 
 static int e1000_tso(struct e1000_adapter *adapter,
-		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
+		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
+		     __be16 protocol)
 {
 	struct e1000_context_desc *context_desc;
 	struct e1000_buffer *buffer_info;
@@ -2692,7 +2693,7 @@ static int e1000_tso(struct e1000_adapter *adapter,
 
 		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 		mss = skb_shinfo(skb)->gso_size;
-		if (skb->protocol == htons(ETH_P_IP)) {
+		if (protocol == htons(ETH_P_IP)) {
 			struct iphdr *iph = ip_hdr(skb);
 			iph->tot_len = 0;
 			iph->check = 0;
@@ -2702,7 +2703,7 @@ static int e1000_tso(struct e1000_adapter *adapter,
 								 0);
 			cmd_length = E1000_TXD_CMD_IP;
 			ipcse = skb_transport_offset(skb) - 1;
-		} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		} else if (skb_is_gso_v6(skb)) {
 			ipv6_hdr(skb)->payload_len = 0;
 			tcp_hdr(skb)->check =
 				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
@@ -2745,7 +2746,8 @@ static int e1000_tso(struct e1000_adapter *adapter,
 }
 
 static bool e1000_tx_csum(struct e1000_adapter *adapter,
-			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
+			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
+			  __be16 protocol)
 {
 	struct e1000_context_desc *context_desc;
 	struct e1000_buffer *buffer_info;
@@ -2756,7 +2758,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter,
 	if (skb->ip_summed != CHECKSUM_PARTIAL)
 		return false;
 
-	switch (skb->protocol) {
+	switch (protocol) {
 	case cpu_to_be16(ETH_P_IP):
 		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
 			cmd_len |= E1000_TXD_CMD_TCP;
@@ -3097,6 +3099,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 	int count = 0;
 	int tso;
 	unsigned int f;
+	__be16 protocol = vlan_get_protocol(skb);
 
 	/* This goes back to the question of how to logically map a Tx queue
 	 * to a flow.  Right now, performance is impacted slightly negatively
@@ -3210,7 +3213,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
 	first = tx_ring->next_to_use;
 
-	tso = e1000_tso(adapter, tx_ring, skb);
+	tso = e1000_tso(adapter, tx_ring, skb, protocol);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
@@ -3220,10 +3223,10 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 		if (likely(hw->mac_type != e1000_82544))
 			tx_ring->last_tx_tso = true;
 		tx_flags |= E1000_TX_FLAGS_TSO;
-	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
+	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb, protocol)))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
-	if (likely(skb->protocol == htons(ETH_P_IP)))
+	if (protocol == htons(ETH_P_IP))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
 	if (unlikely(skb->no_fcs))
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] bna: Support TSO and partial checksum with non-accelerated vlans.
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
  2014-08-23  2:17 ` [PATCH 1/8] e1000e: Fix TSO with non-accelerated vlans vyasevich
  2014-08-23  2:17 ` [PATCH 2/8] e1000: Fix TSO for non-accelerated vlan traffic vyasevich
@ 2014-08-23  2:17 ` vyasevich
  2014-08-23  2:17 ` [PATCH 4/8] ehea: Fix TSO and hw checksums with non-accelerated vlan packets vyasevich
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev; +Cc: Vladislav Yasevich, Rasesh Mody

From: Vladislav Yasevich <vyasevic@redhat.com>

This device claims TSO and checksum support for vlans.  It also
allows a user to control vlan acceleration offloading.  As such,
it is possible to turn off vlan acceleration and configure a vlan
which will continue to support TSO.

In such situation the packet passed down the the device will contain
a vlan header and skb->protocol will be set to ETH_P_8021Q.
The device assumes that skb->protocol contains network protocol
value and uses that value to set up TSO information.  This results
in corrupted frames sent on the wire.

This patch extract the protocol value correctly and corrects TSO
and checksums for non-accelerated traffic.

CC: Rasesh Mody <rmody@brocade.com>
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/brocade/bna/bnad.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index ff8cae5..ffc92a4 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -2506,7 +2506,7 @@ bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
 	 * For TSO, the TCP checksum field is seeded with pseudo-header sum
 	 * excluding the length field.
 	 */
-	if (skb->protocol == htons(ETH_P_IP)) {
+	if (vlan_get_protocol(skb) == htons(ETH_P_IP)) {
 		struct iphdr *iph = ip_hdr(skb);
 
 		/* Do we really need these? */
@@ -2870,12 +2870,13 @@ bnad_txq_wi_prepare(struct bnad *bnad, struct bna_tcb *tcb,
 		}
 
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			__be16 net_proto = vlan_get_protocol(skb);
 			u8 proto = 0;
 
-			if (skb->protocol == htons(ETH_P_IP))
+			if (net_proto == htons(ETH_P_IP))
 				proto = ip_hdr(skb)->protocol;
 #ifdef NETIF_F_IPV6_CSUM
-			else if (skb->protocol == htons(ETH_P_IPV6)) {
+			else if (net_proto == htons(ETH_P_IPV6)) {
 				/* nexthdr may not be TCP immediately. */
 				proto = ipv6_hdr(skb)->nexthdr;
 			}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] ehea: Fix TSO and hw checksums with non-accelerated vlan packets.
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
                   ` (2 preceding siblings ...)
  2014-08-23  2:17 ` [PATCH 3/8] bna: Support TSO and partial checksum with non-accelerated vlans vyasevich
@ 2014-08-23  2:17 ` vyasevich
  2014-08-23  2:17 ` [PATCH 5/8] i40e: Fix TSO and hw checksums for " vyasevich
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev; +Cc: Vladislav Yasevich, Thadeu Lima de Souza Cascardo

From: Vladislav Yasevich <vyasevic@redhat.com>

The driver claims that it can do TSO and IP checksums on vlan
devices and also allows user to control vlan acceleration offloading.
This makes it possible to push traffic to this driver that has TSO or
partial checksums set, but also have a non-accelearted vlan
header.  In this case, the driver will fail to correctly
identify such traffic and will not correctly perform
segmentation and checksum calculation.

Fix this by using vlan_get_protocol() helper instead of
assuming skb->protocol always has this information.

CC: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
index a0b418e..566b17d 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -1994,7 +1994,7 @@ static void xmit_common(struct sk_buff *skb, struct ehea_swqe *swqe)
 {
 	swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT | EHEA_SWQE_CRC;
 
-	if (skb->protocol != htons(ETH_P_IP))
+	if (vlan_get_protocol(skb) != htons(ETH_P_IP))
 		return;
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] i40e: Fix TSO and hw checksums for non-accelerated vlan packets.
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
                   ` (3 preceding siblings ...)
  2014-08-23  2:17 ` [PATCH 4/8] ehea: Fix TSO and hw checksums with non-accelerated vlan packets vyasevich
@ 2014-08-23  2:17 ` vyasevich
  2014-08-23 18:43   ` David Miller
  2014-08-23  2:17 ` [PATCH 6/8] i40evf: " vyasevich
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev
  Cc: Vladislav Yasevich, Jeff Kirsher, Jesse Brandeburg, Bruce Allan,
	Carolyn Wyborny, Don Skidmore, Greg Rose, Alex Duyck,
	John Ronciak, Mitch Williams, Linux NICS, e1000-devel

From: Vladislav Yasevich <vyasevic@redhat.com>

This device claims TSO and checksum support for vlans.  It also
allows a user to control vlan acceleration offloading.  As such,
it is possible to turn off vlan acceleration and configure a vlan
which will continue to support TSO and hw checksums.

In such situation the packet passed down the the device will contain
a vlan header and skb->protocol will be set to ETH_P_8021Q.
The device assumes that skb->protocol contains network protocol
value and uses that value to set up TSO and checksum information.
This results in corrupted frames sent on the wire.

This patch extract the protocol value correctly and corrects TSO
and checksums for non-accelerated traffic.

Fix this by using vlan_get_protocol() helper.

CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Bruce Allan <bruce.w.allan@intel.com>
CC: Carolyn Wyborny <carolyn.wyborny@intel.com>
CC: Don Skidmore <donald.c.skidmore@intel.com>
CC: Greg Rose <gregory.v.rose@intel.com>
CC: Alex Duyck <alexander.h.duyck@intel.com>
CC: John Ronciak <john.ronciak@intel.com>
CC: Mitch Williams <mitch.a.williams@intel.com>
CC: Linux NICS <linux.nics@intel.com>
CC: e1000-devel@lists.sourceforge.net
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index a51aa37..3247057 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -2295,7 +2295,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
 		goto out_drop;
 
 	/* obtain protocol of skb */
-	protocol = skb->protocol;
+	protocol = get_vlan_protocol(skb);
 
 	/* record the location of the first descriptor for this packet */
 	first = &tx_ring->tx_bi[tx_ring->next_to_use];
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/8] i40evf: Fix TSO and hw checksums for non-accelerated vlan packets.
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
                   ` (4 preceding siblings ...)
  2014-08-23  2:17 ` [PATCH 5/8] i40e: Fix TSO and hw checksums for " vyasevich
@ 2014-08-23  2:17 ` vyasevich
  2014-08-23  2:17 ` [PATCH 7/8] mvneta: Fix TSO and checksum for non-acceleration vlan traffic vyasevich
  2014-08-23  2:17 ` [PATCH 8/8] qlge: Fix TSO for non-accelerated " vyasevich
  7 siblings, 0 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev
  Cc: Vladislav Yasevich, Jeff Kirsher, Jesse Brandeburg, Bruce Allan,
	Carolyn Wyborny, Don Skidmore, Greg Rose, Alex Duyck,
	John Ronciak, Mitch Williams, Linux NICS, e1000-devel

From: Vladislav Yasevich <vyasevic@redhat.com>

This device claims TSO and checksum support for vlans.  It also
allows a user to control vlan acceleration offloading.  As such,
it is possible to turn off vlan acceleration and configure a vlan
which will continue to support TSO and hw checksums.

In such situation the packet passed down the the device will contain
a vlan header and skb->protocol will be set to ETH_P_8021Q.
The device assumes that skb->protocol contains network protocol
value and uses that value to set up TSO and checksum information.
This results in corrupted frames sent on the wire.

This patch extract the protocol value correctly and corrects TSO
and checksums for non-accelerated traffic.

Fix this by using vlan_get_protocol() helper.

CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Bruce Allan <bruce.w.allan@intel.com>
CC: Carolyn Wyborny <carolyn.wyborny@intel.com>
CC: Don Skidmore <donald.c.skidmore@intel.com>
CC: Greg Rose <gregory.v.rose@intel.com>
CC: Alex Duyck <alexander.h.duyck@intel.com>
CC: John Ronciak <john.ronciak@intel.com>
CC: Mitch Williams <mitch.a.williams@intel.com>
CC: Linux NICS <linux.nics@intel.com>
CC: e1000-devel@lists.sourceforge.net
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 79bf96c..95a3ec2 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -1597,7 +1597,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
 		goto out_drop;
 
 	/* obtain protocol of skb */
-	protocol = skb->protocol;
+	protocol = vlan_get_protocol(skb);
 
 	/* record the location of the first descriptor for this packet */
 	first = &tx_ring->tx_bi[tx_ring->next_to_use];
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] mvneta: Fix TSO and checksum for non-acceleration vlan traffic
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
                   ` (5 preceding siblings ...)
  2014-08-23  2:17 ` [PATCH 6/8] i40evf: " vyasevich
@ 2014-08-23  2:17 ` vyasevich
  2014-08-23  2:17 ` [PATCH 8/8] qlge: Fix TSO for non-accelerated " vyasevich
  7 siblings, 0 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev; +Cc: Vladislav Yasevich, Thomas Petazzoni

From: Vladislav Yasevich <vyasevic@redhat.com>

This driver doesn't appear to support vlan acceleration at
all.  However, it does claim to support TSO and IP checksums
for vlan devices.  Thus any configured vlan device would
end up passing down partial checksums or TSO frames.

The driver also uses the value from skb->protocol to
determine TSO and checksum offload information, but assumes
that skb->protocol holds the l3 protocol information.
As a result, vlan traffic with partial checksums or TSO
will fail those checks and TSO will not happen.

Fix this by using vlan_get_protocol() helper.

CC: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/marvell/mvneta.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index c9f1d1b..133f8c6 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1371,15 +1371,16 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb)
 {
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		int ip_hdr_len = 0;
+		__be16 l3_proto = vlan_get_protocol(skb);
 		u8 l4_proto;
 
-		if (skb->protocol == htons(ETH_P_IP)) {
+		if (l3_proto == htons(ETH_P_IP)) {
 			struct iphdr *ip4h = ip_hdr(skb);
 
 			/* Calculate IPv4 checksum and L4 checksum */
 			ip_hdr_len = ip4h->ihl;
 			l4_proto = ip4h->protocol;
-		} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		} else if (l3_proto == htons(ETH_P_IPV6)) {
 			struct ipv6hdr *ip6h = ipv6_hdr(skb);
 
 			/* Read l4_protocol from one of IPv6 extra headers */
@@ -1390,7 +1391,7 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb)
 			return MVNETA_TX_L4_CSUM_NOT;
 
 		return mvneta_txq_desc_csum(skb_network_offset(skb),
-				skb->protocol, ip_hdr_len, l4_proto);
+					    l3_proto, ip_hdr_len, l4_proto);
 	}
 
 	return MVNETA_TX_L4_CSUM_NOT;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] qlge: Fix TSO for non-accelerated vlan traffic
  2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
                   ` (6 preceding siblings ...)
  2014-08-23  2:17 ` [PATCH 7/8] mvneta: Fix TSO and checksum for non-acceleration vlan traffic vyasevich
@ 2014-08-23  2:17 ` vyasevich
  7 siblings, 0 replies; 11+ messages in thread
From: vyasevich @ 2014-08-23  2:17 UTC (permalink / raw)
  To: netdev
  Cc: Vladislav Yasevich, Shahed Shaikh, Jitendra Kalsaria, Ron Mercer,
	linux-driver

From: Vladislav Yasevich <vyasevic@redhat.com>

This device claims TSO support for vlans.  It also allows a user to
control vlan acceleration offloading.  As such, it is possible to turn
off vlan acceleration and configure a vlan which will continue to send
TSO traffic.

In such situation the packet passed down the the device will contain
a vlan header and skb->protocol will be set to ETH_P_8021Q.
The device assumes that skb->protocol contains network protocol
value and uses that value to set up TSO information.
This results in corrupted frames sent on the wire.

This patch extracts the protocol value correctly by using a
vlan_get_protocol() helper and corrects corrupt TSO frames.

CC: Shahed Shaikh <shahed.shaikh@qlogic.com>
CC: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
CC: Ron Mercer <ron.mercer@qlogic.com>
CC: linux-driver@qlogic.com
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 drivers/net/ethernet/qlogic/qlge/qlge_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 188626e..3e96f26 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -2556,6 +2556,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
 
 	if (skb_is_gso(skb)) {
 		int err;
+		__be16 l3_proto = vlan_get_protocol(skb);
 
 		err = skb_cow_head(skb, 0);
 		if (err < 0)
@@ -2572,7 +2573,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
 				<< OB_MAC_TRANSPORT_HDR_SHIFT);
 		mac_iocb_ptr->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
 		mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_LSO;
-		if (likely(skb->protocol == htons(ETH_P_IP))) {
+		if (likely(l3_proto == htons(ETH_P_IP))) {
 			struct iphdr *iph = ip_hdr(skb);
 			iph->check = 0;
 			mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP4;
@@ -2580,7 +2581,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
 								 iph->daddr, 0,
 								 IPPROTO_TCP,
 								 0);
-		} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		} else if (l3_proto == htons(ETH_P_IPV6)) {
 			mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP6;
 			tcp_hdr(skb)->check =
 			    ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 5/8] i40e: Fix TSO and hw checksums for non-accelerated vlan packets.
  2014-08-23  2:17 ` [PATCH 5/8] i40e: Fix TSO and hw checksums for " vyasevich
@ 2014-08-23 18:43   ` David Miller
  2014-08-24  1:13     ` Vlad Yasevich
  0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2014-08-23 18:43 UTC (permalink / raw)
  To: vyasevich
  Cc: netdev, vyasevic, jeffrey.t.kirsher, jesse.brandeburg,
	bruce.w.allan, carolyn.wyborny, donald.c.skidmore,
	gregory.v.rose, alexander.h.duyck, john.ronciak,
	mitch.a.williams, linux.nics, e1000-devel

From: vyasevich@gmail.com
Date: Fri, 22 Aug 2014 22:17:07 -0400

> @@ -2295,7 +2295,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
>  		goto out_drop;
>  
>  	/* obtain protocol of skb */
> -	protocol = skb->protocol;
> +	protocol = get_vlan_protocol(skb);

I don't think this even compiles.

It's "vlan_get_protocol" not "get_vlan_protocol".

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 5/8] i40e: Fix TSO and hw checksums for non-accelerated vlan packets.
  2014-08-23 18:43   ` David Miller
@ 2014-08-24  1:13     ` Vlad Yasevich
  0 siblings, 0 replies; 11+ messages in thread
From: Vlad Yasevich @ 2014-08-24  1:13 UTC (permalink / raw)
  To: David Miller
  Cc: vyasevic, linux.nics, e1000-devel, netdev, bruce.w.allan,
	jesse.brandeburg, john.ronciak

On 08/23/2014 02:43 PM, David Miller wrote:
> From: vyasevich@gmail.com
> Date: Fri, 22 Aug 2014 22:17:07 -0400
> 
>> @@ -2295,7 +2295,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
>>  		goto out_drop;
>>  
>>  	/* obtain protocol of skb */
>> -	protocol = skb->protocol;
>> +	protocol = get_vlan_protocol(skb);
> 
> I don't think this even compiles.
> 
> It's "vlan_get_protocol" not "get_vlan_protocol".
> 

Yes.  I notice this one as well this morning, but didn't have time to fix.

Apologies.

-vlad

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-08-24  1:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-23  2:17 [PATCH 0/8] Fix TSO and checksum issues with non-accelerated vlan traffic vyasevich
2014-08-23  2:17 ` [PATCH 1/8] e1000e: Fix TSO with non-accelerated vlans vyasevich
2014-08-23  2:17 ` [PATCH 2/8] e1000: Fix TSO for non-accelerated vlan traffic vyasevich
2014-08-23  2:17 ` [PATCH 3/8] bna: Support TSO and partial checksum with non-accelerated vlans vyasevich
2014-08-23  2:17 ` [PATCH 4/8] ehea: Fix TSO and hw checksums with non-accelerated vlan packets vyasevich
2014-08-23  2:17 ` [PATCH 5/8] i40e: Fix TSO and hw checksums for " vyasevich
2014-08-23 18:43   ` David Miller
2014-08-24  1:13     ` Vlad Yasevich
2014-08-23  2:17 ` [PATCH 6/8] i40evf: " vyasevich
2014-08-23  2:17 ` [PATCH 7/8] mvneta: Fix TSO and checksum for non-acceleration vlan traffic vyasevich
2014-08-23  2:17 ` [PATCH 8/8] qlge: Fix TSO for non-accelerated " vyasevich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.