Re: [RFC v2 6/6] flow_dissector: Parse batman-adv unicast headers
From: Tom Herbert
Date: Tue Dec 05 2017 - 12:19:55 EST
On Tue, Dec 5, 2017 at 6:35 AM, Sven Eckelmann
<sven.eckelmann@xxxxxxxxxxxx> wrote:
> 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@xxxxxxxxxxxx>
> ---
> net/core/flow_dissector.c | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> index 15ce30063765..784cc07fc58e 100644
> --- a/net/core/flow_dissector.c
> +++ b/net/core/flow_dissector.c
> @@ -24,6 +24,7 @@
> #include <linux/tcp.h>
> #include <net/flow_dissector.h>
> #include <scsi/fc/fc_fcoe.h>
> +#include <uapi/linux/batadv.h>
>
> static void dissector_set_key(struct flow_dissector *flow_dissector,
> enum flow_dissector_key_id key_id)
> @@ -696,6 +697,35 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
>
> break;
> }
> + case htons(ETH_P_BATMAN): {
> + struct {
> + struct batadv_unicast_packet batadv_unicast;
> + struct ethhdr eth;
> + } *hdr, _hdr;
> +
> + hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen,
> + &_hdr);
> + if (!hdr) {
> + fdret = FLOW_DISSECT_RET_OUT_BAD;
> + break;
> + }
> +
> + if (hdr->batadv_unicast.version != BATADV_COMPAT_VERSION) {
> + fdret = FLOW_DISSECT_RET_OUT_BAD;
> + break;
> + }
> +
> + if (hdr->batadv_unicast.packet_type != BATADV_UNICAST) {
> + fdret = FLOW_DISSECT_RET_OUT_BAD;
> + break;
> + }
> +
> + proto = hdr->eth.h_proto;
> + nhoff += sizeof(*hdr);
> +
> + fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
> + break;
> + }
> case htons(ETH_P_8021AD):
> case htons(ETH_P_8021Q): {
> const struct vlan_hdr *vlan;
> --
> 2.11.0
>
Switch statements with cases having many LOC is hard to read and
__skb_flow_dissect is aleady quite convoluted to begin with.
I suggest putting this in a static function similar to how MPLS and
GRE are handled.
Tom