]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/net-mvpp2-extract-the-correct-ethtype-from-the-skb-for-tx-csum-offload.patch
Linux 4.9.135
[thirdparty/kernel/stable-queue.git] / queue-4.4 / net-mvpp2-extract-the-correct-ethtype-from-the-skb-for-tx-csum-offload.patch
1 From foo@baz Tue Oct 16 16:15:55 CEST 2018
2 From: Maxime Chevallier <maxime.chevallier@bootlin.com>
3 Date: Fri, 5 Oct 2018 09:04:40 +0200
4 Subject: net: mvpp2: Extract the correct ethtype from the skb for tx csum offload
5
6 From: Maxime Chevallier <maxime.chevallier@bootlin.com>
7
8 [ Upstream commit 35f3625c21852ad839f20c91c7d81c4c1101e207 ]
9
10 When offloading the L3 and L4 csum computation on TX, we need to extract
11 the l3_proto from the ethtype, independently of the presence of a vlan
12 tag.
13
14 The actual driver uses skb->protocol as-is, resulting in packets with
15 the wrong L4 checksum being sent when there's a vlan tag in the packet
16 header and checksum offloading is enabled.
17
18 This commit makes use of vlan_protocol_get() to get the correct ethtype
19 regardless the presence of a vlan tag.
20
21 Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit")
22 Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
23 Signed-off-by: David S. Miller <davem@davemloft.net>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25 ---
26 drivers/net/ethernet/marvell/mvpp2.c | 10 ++++++----
27 1 file changed, 6 insertions(+), 4 deletions(-)
28
29 --- a/drivers/net/ethernet/marvell/mvpp2.c
30 +++ b/drivers/net/ethernet/marvell/mvpp2.c
31 @@ -29,6 +29,7 @@
32 #include <linux/clk.h>
33 #include <linux/hrtimer.h>
34 #include <linux/ktime.h>
35 +#include <linux/if_vlan.h>
36 #include <uapi/linux/ppp_defs.h>
37 #include <net/ip.h>
38 #include <net/ipv6.h>
39 @@ -4268,7 +4269,7 @@ static void mvpp2_txq_desc_put(struct mv
40 }
41
42 /* Set Tx descriptors fields relevant for CSUM calculation */
43 -static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto,
44 +static u32 mvpp2_txq_desc_csum(int l3_offs, __be16 l3_proto,
45 int ip_hdr_len, int l4_proto)
46 {
47 u32 command;
48 @@ -5032,14 +5033,15 @@ static u32 mvpp2_skb_tx_csum(struct mvpp
49 if (skb->ip_summed == CHECKSUM_PARTIAL) {
50 int ip_hdr_len = 0;
51 u8 l4_proto;
52 + __be16 l3_proto = vlan_get_protocol(skb);
53
54 - if (skb->protocol == htons(ETH_P_IP)) {
55 + if (l3_proto == htons(ETH_P_IP)) {
56 struct iphdr *ip4h = ip_hdr(skb);
57
58 /* Calculate IPv4 checksum and L4 checksum */
59 ip_hdr_len = ip4h->ihl;
60 l4_proto = ip4h->protocol;
61 - } else if (skb->protocol == htons(ETH_P_IPV6)) {
62 + } else if (l3_proto == htons(ETH_P_IPV6)) {
63 struct ipv6hdr *ip6h = ipv6_hdr(skb);
64
65 /* Read l4_protocol from one of IPv6 extra headers */
66 @@ -5051,7 +5053,7 @@ static u32 mvpp2_skb_tx_csum(struct mvpp
67 }
68
69 return mvpp2_txq_desc_csum(skb_network_offset(skb),
70 - skb->protocol, ip_hdr_len, l4_proto);
71 + l3_proto, ip_hdr_len, l4_proto);
72 }
73
74 return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE;