diff options
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.patch | 108 |
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; |