[<prev] [next>] [day] [month] [year] [list]
Message-ID: <2A6E6328DF026B458DBF90B38941F981871A42F1@DGGEML523-MBX.china.huawei.com>
Date: Wed, 27 May 2020 12:59:52 +0000
From: Fengtiantian <fengtiantian@...wei.com>
To: "David S. Miller" <davem@...emloft.net>,
"open list:NETWORKING [GENERAL" <netdev@...r.kernel.org>,
open list <linux-kernel@...r.kernel.org>,
Michał Mirosław <mirq-linux@...e.qmqm.pl>,
"Daniel Borkmann" <daniel@...earbox.net>,
Stanislav Fomichev <sdf@...gle.com>,
"Jiri Pirko" <jiri@...lanox.com>, Arnd Bergmann <arnd@...db.de>,
Hadar Hen Zion <hadarh@...lanox.com>
CC: "Huangweidong (C)" <weidong.huang@...wei.com>,
yuehaibing <yuehaibing@...wei.com>
Subject: [patch] flow_dissector: Fix wrong vlan header offset in
__skb_flow_dissect
We use the openvswitch 2.7.0 and find the issue when ovs use the skb_get_hash() to get the hash of QinQ skb. Because the
__skb_flow_dissect() get the wrong vlan protocol headers.
Someone report bonding driver has the same issue use the
__skb_flow_dissect() to count hash in bond_xmit_hash:
https://lore.kernel.org/netdev/00a5d09f-a23e-661f-60c0-
75fba6227451@...wei.com/T/.
Because in netif_receive_skb, the skb_network_header points to vlan head, but in dev_hard_start_xmit, the skb_network_header points to IP header. So use the skb_network_offset to get the vlan head is not reliable.
Should we use the skb_mac_offset instead the skb_network_offset to get the vlan head when proto is ETH_P_8021AD or ETH_P_8021Q?
Signed-off-by: Feng tiantian <fengtiantian@...wei.com>
---
net/core/flow_dissector.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 415b95f..9a77d5d 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -629,6 +629,13 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
skb->vlan_proto : skb->protocol;
nhoff = skb_network_offset(skb);
hlen = skb_headlen(skb);
+
+ if (proto == htons(ETH_P_8021AD) ||
+ proto == htons(ETH_P_8021Q)) {
+ if (skb_mac_header_was_set(skb))
+ nhoff = skb_mac_offset(skb) + ETH_HLEN;
+ }
+
#if IS_ENABLED(CONFIG_NET_DSA)
if (unlikely(skb->dev && netdev_uses_dsa(skb->dev))) {
const struct dsa_device_ops *ops;
--
1.8.3.1
Powered by blists - more mailing lists