summaryrefslogtreecommitdiff
path: root/target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch')
-rw-r--r--target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch65
1 files changed, 65 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch b/target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch
new file mode 100644
index 0000000..5435962
--- /dev/null
+++ b/target/linux/mediatek/patches-4.9/0041-net-next-dsa-fix-flow-dissection.patch
@@ -0,0 +1,65 @@
+From 04c825484d6ecdcc8ce09b350235c9077eaca6e3 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Wed, 9 Aug 2017 08:20:21 +0200
+Subject: [PATCH 41/57] net-next: dsa: fix flow dissection
+
+RPS and probably other kernel features are currently broken on some if not
+all DSA devices. The root cause of this is that skb_hash will call the
+flow_dissector. At this point the skb still contains the magic switch
+header and the skb->protocol field is not set up to the correct 802.3
+value yet. By the time the tag specific code is called, removing the header
+and =roperly setting the protocol an invalid hash is already set. In the
+case of the mt7530 this will result in all flows always having the same
+hash.
+
+This patch makes the flow dissector honour the nh and protocol offset
+defined by the dsa tag driver thus fixing dissection, hashing and RPS.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ net/core/flow_dissector.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -4,6 +4,7 @@
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
+ #include <linux/if_vlan.h>
++#include <net/dsa.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+ #include <net/gre.h>
+@@ -123,13 +124,23 @@ bool __skb_flow_dissect(const struct sk_
+ bool skip_vlan = false;
+ u8 ip_proto = 0;
+ bool ret;
+-
+ if (!data) {
+ data = skb->data;
+ proto = skb_vlan_tag_present(skb) ?
+ skb->vlan_proto : skb->protocol;
+ nhoff = skb_network_offset(skb);
+ hlen = skb_headlen(skb);
++ if (unlikely(netdev_uses_dsa(skb->dev))) {
++ const struct dsa_device_ops *ops;
++ int offset;
++
++ ops = skb->dev->dsa_ptr->tag_ops;
++ if (ops->flow_dissect &&
++ !ops->flow_dissect(skb, &proto, &offset)) {
++ hlen -= offset;
++ nhoff += offset;
++ }
++ }
+ }
+
+ /* It is ensured by skb_flow_dissector_init() that control key will
+@@ -162,6 +173,7 @@ again:
+ case htons(ETH_P_IP): {
+ const struct iphdr *iph;
+ struct iphdr _iph;
++
+ ip:
+ iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
+ if (!iph || iph->ihl < 5)