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: 3f51850 ("ethernet: Add new driver for Marvell Armada 375 network unit")
Signed-off-by: Maxime Chevallier <[email protected]>
---
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 38cc01beea79..4bd5b251e3c7 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -1737,7 +1737,7 @@ static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto,
command |= (ip_hdr_len << MVPP2_TXD_IP_HLEN_SHIFT);
command |= MVPP2_TXD_IP_CSUM_DISABLE;
- if (l3_proto == htons(ETH_P_IP)) {
+ if (l3_proto == ETH_P_IP) {
command &= ~MVPP2_TXD_IP_CSUM_DISABLE; /* enable IPv4 csum */
command &= ~MVPP2_TXD_L3_IP6; /* enable IPv4 */
} else {
@@ -2600,14 +2600,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;
+ int l3_proto = ntohs(vlan_get_protocol(skb));
- if (skb->protocol == htons(ETH_P_IP)) {
+ if (l3_proto == 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 == ETH_P_IPV6) {
struct ipv6hdr *ip6h = ipv6_hdr(skb);
/* Read l4_protocol from one of IPv6 extra headers */
@@ -2619,7 +2620,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;
--
2.11.0
I'm not sure that kind of ntohs() using is good for the Performance.
htons(ETH_P_IP) is CONSTANT swapped Big/LittleEndian by COMPILER whilst the
ntohs(vlan_get_protocol(skb)) is run-time short/byte-swap for every packet.
Yan Markman
-----Original Message-----
From: Maxime Chevallier [mailto:[email protected]]
Sent: Thursday, October 04, 2018 11:03 AM
To: [email protected]
Cc: Maxime Chevallier <[email protected]>; [email protected]; [email protected]; Antoine Tenart <[email protected]>; [email protected]; [email protected]; [email protected]; Nadav Haklai <[email protected]>; Stefan Chulski <[email protected]>; Yan Markman <[email protected]>; [email protected]
Subject: [EXT] [PATCH net] net: mvpp2: Extract the correct ethtype from the skb for tx csum offload
External Email
----------------------------------------------------------------------
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: 3f51850 ("ethernet: Add new driver for Marvell Armada 375 network unit")
Signed-off-by: Maxime Chevallier <[email protected]>
---
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 38cc01beea79..4bd5b251e3c7 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -1737,7 +1737,7 @@ static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto,
command |= (ip_hdr_len << MVPP2_TXD_IP_HLEN_SHIFT);
command |= MVPP2_TXD_IP_CSUM_DISABLE;
- if (l3_proto == htons(ETH_P_IP)) {
+ if (l3_proto == ETH_P_IP) {
command &= ~MVPP2_TXD_IP_CSUM_DISABLE; /* enable IPv4 csum */
command &= ~MVPP2_TXD_L3_IP6; /* enable IPv4 */
} else {
@@ -2600,14 +2600,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;
+ int l3_proto = ntohs(vlan_get_protocol(skb));
- if (skb->protocol == htons(ETH_P_IP)) {
+ if (l3_proto == 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 == ETH_P_IPV6) {
struct ipv6hdr *ip6h = ipv6_hdr(skb);
/* Read l4_protocol from one of IPv6 extra headers */ @@ -2619,7 +2620,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;
--
2.11.0
Hello!
On 10/4/2018 11:03 AM, Maxime Chevallier wrote:
> 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.
^ of?
> Fixes: 3f51850 ("ethernet: Add new driver for Marvell Armada 375 network unit")
12 hex digits needed here.
> Signed-off-by: Maxime Chevallier <[email protected]>
[...]
MBR, Sergei
Hello Sergei,
On Thu, 4 Oct 2018 12:50:17 +0300
Sergei Shtylyov <[email protected]> wrote:
>Hello!
>
>On 10/4/2018 11:03 AM, Maxime Chevallier wrote:
>
>> 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.
> ^ of?
>
>> Fixes: 3f51850 ("ethernet: Add new driver for Marvell Armada 375 network unit")
>
> 12 hex digits needed here.
Sorry about that, I'll resend with a proper Fixes tag.
Thanks,
Maxime