net: mvpp2: Extract the correct ethtype from the skb for tx csum offload
[ Upstream commit 35f3625c21852ad839f20c91c7d81c4c1101e207 ] When offloading the L3 and L4 csum computation on TX, we need to extract the l3_proto from the ethtype, independently of the presence of a vlan tag. The actual driver uses skb->protocol as-is, resulting in packets with the wrong L4 checksum being sent when there's a vlan tag in the packet header and checksum offloading is enabled. This commit makes use of vlan_protocol_get() to get the correct ethtype regardless the presence of a vlan tag. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e0fff89962
commit
2b2c9306e3
@ -29,6 +29,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <uapi/linux/ppp_defs.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
@ -4268,7 +4269,7 @@ static void mvpp2_txq_desc_put(struct mvpp2_tx_queue *txq)
|
||||
}
|
||||
|
||||
/* Set Tx descriptors fields relevant for CSUM calculation */
|
||||
static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto,
|
||||
static u32 mvpp2_txq_desc_csum(int l3_offs, __be16 l3_proto,
|
||||
int ip_hdr_len, int l4_proto)
|
||||
{
|
||||
u32 command;
|
||||
@ -5032,14 +5033,15 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
int ip_hdr_len = 0;
|
||||
u8 l4_proto;
|
||||
__be16 l3_proto = vlan_get_protocol(skb);
|
||||
|
||||
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 */
|
||||
@ -5051,7 +5053,7 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
return mvpp2_txq_desc_csum(skb_network_offset(skb),
|
||||
skb->protocol, ip_hdr_len, l4_proto);
|
||||
l3_proto, ip_hdr_len, l4_proto);
|
||||
}
|
||||
|
||||
return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user