aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorAnjali Singhai <anjali.singhai@intel.com>2014-12-18 21:58:16 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-01-06 20:15:03 -0500
commitdf23075fc82578a8d9cd617148fba3b90755ffb5 (patch)
tree93e459826fd36e04da21278d1358b86eed7cbe62 /drivers/net/ethernet/intel
parentf6385979d6dd670ce2dd93d4684579dd1d1d2435 (diff)
i40e: Fix bug with TCP over IPv6 over VXLAN
The driver was examining the outer protocol layer to set the inner protocol layer checksum offload. In the case of TCP over IPV6 over an IPv4 based VXLAN the inner checksum offloads would be set to look for IPv4/UDP instead of IPv6/TCP. This code fixes that so that the driver will look at the proper layer for encapsulation offload settings. Signed-off-by: Anjali Singhai <anjali.singhai@intel.com> Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 38c7638076e2..cecb340898fe 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -1883,17 +1883,16 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
1883 if (err < 0) 1883 if (err < 0)
1884 return err; 1884 return err;
1885 1885
1886 if (protocol == htons(ETH_P_IP)) { 1886 iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
1887 iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); 1887 ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb);
1888
1889 if (iph->version == 4) {
1888 tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); 1890 tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);
1889 iph->tot_len = 0; 1891 iph->tot_len = 0;
1890 iph->check = 0; 1892 iph->check = 0;
1891 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 1893 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
1892 0, IPPROTO_TCP, 0); 1894 0, IPPROTO_TCP, 0);
1893 } else if (skb_is_gso_v6(skb)) { 1895 } else if (ipv6h->version == 6) {
1894
1895 ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb)
1896 : ipv6_hdr(skb);
1897 tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); 1896 tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb);
1898 ipv6h->payload_len = 0; 1897 ipv6h->payload_len = 0;
1899 tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, 1898 tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
@@ -1989,13 +1988,9 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
1989 I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM; 1988 I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;
1990 } 1989 }
1991 } else if (tx_flags & I40E_TX_FLAGS_IPV6) { 1990 } else if (tx_flags & I40E_TX_FLAGS_IPV6) {
1992 if (tx_flags & I40E_TX_FLAGS_TSO) { 1991 *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6;
1993 *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; 1992 if (tx_flags & I40E_TX_FLAGS_TSO)
1994 ip_hdr(skb)->check = 0; 1993 ip_hdr(skb)->check = 0;
1995 } else {
1996 *cd_tunneling |=
1997 I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM;
1998 }
1999 } 1994 }
2000 1995
2001 /* Now set the ctx descriptor fields */ 1996 /* Now set the ctx descriptor fields */
@@ -2005,7 +2000,10 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
2005 ((skb_inner_network_offset(skb) - 2000 ((skb_inner_network_offset(skb) -
2006 skb_transport_offset(skb)) >> 1) << 2001 skb_transport_offset(skb)) >> 1) <<
2007 I40E_TXD_CTX_QW0_NATLEN_SHIFT; 2002 I40E_TXD_CTX_QW0_NATLEN_SHIFT;
2008 2003 if (this_ip_hdr->version == 6) {
2004 tx_flags &= ~I40E_TX_FLAGS_IPV4;
2005 tx_flags |= I40E_TX_FLAGS_IPV6;
2006 }
2009 } else { 2007 } else {
2010 network_hdr_len = skb_network_header_len(skb); 2008 network_hdr_len = skb_network_header_len(skb);
2011 this_ip_hdr = ip_hdr(skb); 2009 this_ip_hdr = ip_hdr(skb);