Skip to content

Commit

Permalink
i40e/i40evf: Handle IPv6 extension headers in checksum offload
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexander Duyck authored and Jeff Kirsher committed Feb 18, 2016
1 parent a006472 commit a3fd9d8
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
14 changes: 13 additions & 1 deletion drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2402,7 +2402,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);
Expand All @@ -2419,7 +2421,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 */
Expand Down Expand Up @@ -2469,8 +2476,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 */
Expand Down
14 changes: 13 additions & 1 deletion drivers/net/ethernet/intel/i40evf/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit a3fd9d8

Please sign in to comment.