aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2019-03-16 18:38:46 +0100
committerFelix Fietkau <nbd@nbd.name>2019-03-16 19:59:02 +0100
commit1f68aac9d7b15013407afca581c5da09b45b9afa (patch)
treeff06654767397b81106b4ff7423ef57ca1bcd6f4 /target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch
parent6869ae2ab57c16b28404f2257c0ad9612cc3a0a2 (diff)
downloadupstream-1f68aac9d7b15013407afca581c5da09b45b9afa.tar.gz
upstream-1f68aac9d7b15013407afca581c5da09b45b9afa.tar.bz2
upstream-1f68aac9d7b15013407afca581c5da09b45b9afa.zip
kernel: backport flow dissector batman-adv support
Improves performance on multicore systems handling batman-adv traffic Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch')
-rw-r--r--target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch108
1 files changed, 108 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch b/target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch
new file mode 100644
index 0000000000..b0b2823cc9
--- /dev/null
+++ b/target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch
@@ -0,0 +1,108 @@
+From: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Date: Thu, 21 Dec 2017 10:17:42 +0100
+Subject: [PATCH] flow_dissector: Parse batman-adv unicast headers
+
+The batman-adv unicast packets contain a full layer 2 frame in encapsulated
+form. The flow dissector must therefore be able to parse the batman-adv
+unicast header to reach the layer 2+3 information.
+
+ +--------------------+
+ | ip(v6)hdr |
+ +--------------------+
+ | inner ethhdr |
+ +--------------------+
+ | batadv unicast hdr |
+ +--------------------+
+ | outer ethhdr |
+ +--------------------+
+
+The obtained information from the upper layer can then be used by RPS to
+schedule the processing on separate cores. This allows better distribution
+of multiple flows from the same neighbor to different cores.
+
+Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Reviewed-by: Jiri Pirko <jiri@mellanox.com>
+Acked-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -22,6 +22,7 @@
+ #include <linux/tcp.h>
+ #include <net/flow_dissector.h>
+ #include <scsi/fc/fc_fcoe.h>
++#include <uapi/linux/batadv_packet.h>
+
+ static void dissector_set_key(struct flow_dissector *flow_dissector,
+ enum flow_dissector_key_id key_id)
+@@ -338,6 +339,57 @@ __skb_flow_dissect_gre(const struct sk_b
+ return FLOW_DISSECT_RET_PROTO_AGAIN;
+ }
+
++/**
++ * __skb_flow_dissect_batadv() - dissect batman-adv header
++ * @skb: sk_buff to with the batman-adv header
++ * @key_control: flow dissectors control key
++ * @data: raw buffer pointer to the packet, if NULL use skb->data
++ * @p_proto: pointer used to update the protocol to process next
++ * @p_nhoff: pointer used to update inner network header offset
++ * @hlen: packet header length
++ * @flags: any combination of FLOW_DISSECTOR_F_*
++ *
++ * ETH_P_BATMAN packets are tried to be dissected. Only
++ * &struct batadv_unicast packets are actually processed because they contain an
++ * inner ethernet header and are usually followed by actual network header. This
++ * allows the flow dissector to continue processing the packet.
++ *
++ * Return: FLOW_DISSECT_RET_PROTO_AGAIN when &struct batadv_unicast was found,
++ * FLOW_DISSECT_RET_OUT_GOOD when dissector should stop after encapsulation,
++ * otherwise FLOW_DISSECT_RET_OUT_BAD
++ */
++static enum flow_dissect_ret
++__skb_flow_dissect_batadv(const struct sk_buff *skb,
++ struct flow_dissector_key_control *key_control,
++ void *data, __be16 *p_proto, int *p_nhoff, int hlen,
++ unsigned int flags)
++{
++ struct {
++ struct batadv_unicast_packet batadv_unicast;
++ struct ethhdr eth;
++ } *hdr, _hdr;
++
++ hdr = __skb_header_pointer(skb, *p_nhoff, sizeof(_hdr), data, hlen,
++ &_hdr);
++ if (!hdr)
++ return FLOW_DISSECT_RET_OUT_BAD;
++
++ if (hdr->batadv_unicast.version != BATADV_COMPAT_VERSION)
++ return FLOW_DISSECT_RET_OUT_BAD;
++
++ if (hdr->batadv_unicast.packet_type != BATADV_UNICAST)
++ return FLOW_DISSECT_RET_OUT_BAD;
++
++ *p_proto = hdr->eth.h_proto;
++ *p_nhoff += sizeof(*hdr);
++
++ key_control->flags |= FLOW_DIS_ENCAPSULATION;
++ if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
++ return FLOW_DISSECT_RET_OUT_GOOD;
++
++ return FLOW_DISSECT_RET_PROTO_AGAIN;
++}
++
+ static void
+ __skb_flow_dissect_tcp(const struct sk_buff *skb,
+ struct flow_dissector *flow_dissector,
+@@ -717,6 +769,11 @@ proto_again:
+ nhoff, hlen);
+ break;
+
++ case htons(ETH_P_BATMAN):
++ fdret = __skb_flow_dissect_batadv(skb, key_control, data,
++ &proto, &nhoff, hlen, flags);
++ break;
++
+ default:
+ fdret = FLOW_DISSECT_RET_OUT_BAD;
+ break;