| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- From 04c825484d6ecdcc8ce09b350235c9077eaca6e3 Mon Sep 17 00:00:00 2001
- From: John Crispin <[email protected]>
- 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 <[email protected]>
- ---
- 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)
|