summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
diff options
context:
space:
mode:
authorAlexander Duyck <aduyck@mirantis.com>2016-01-24 21:16:54 -0800
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-02-18 10:49:42 -0800
commita3fd9d8876a589f05725237aced606b995956860 (patch)
treec40122b687886f5a5deb259944d86e86ef082160 /drivers/net/ethernet/intel/i40evf/i40e_txrx.c
parenta0064728f8a34f7a5afd9df86d9cdd8210977c8d (diff)
i40e/i40evf: Handle IPv6 extension headers in checksum offload
This patch adds support for IPv6 extension headers in setting up the Tx checksum. Without this patch extension headers would cause IPv6 traffic to fail as the transport protocol could not be identified. Signed-off-by: Alexander Duyck <aduyck@mirantis.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40evf/i40e_txrx.c')
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 39d5f807f08c3..48ec7631b3dd8 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -1619,7 +1619,9 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
struct udphdr *udp;
unsigned char *hdr;
} l4;
+ unsigned char *exthdr;
u32 l4_tunnel = 0;
+ __be16 frag_off;
u8 l4_proto = 0;
ip.hdr = skb_network_header(skb);
@@ -1636,7 +1638,12 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
l4_proto = ip.v4->protocol;
} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
*cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6;
+
+ exthdr = ip.hdr + sizeof(*ip.v6);
l4_proto = ip.v6->nexthdr;
+ if (l4.hdr != exthdr)
+ ipv6_skip_exthdr(skb, exthdr - skb->data,
+ &l4_proto, &frag_off);
}
/* define outer transport */
@@ -1686,8 +1693,13 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV4;
}
} else if (*tx_flags & I40E_TX_FLAGS_IPV6) {
- l4_proto = ip.v6->nexthdr;
*td_cmd |= I40E_TX_DESC_CMD_IIPT_IPV6;
+
+ exthdr = ip.hdr + sizeof(*ip.v6);
+ l4_proto = ip.v6->nexthdr;
+ if (l4.hdr != exthdr)
+ ipv6_skip_exthdr(skb, exthdr - skb->data,
+ &l4_proto, &frag_off);
}
/* Now set the td_offset for IP header length */