274-flow_dissector-Parse-batman-adv-unicast-headers.patch 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. From: Sven Eckelmann <sven.eckelmann@openmesh.com>
  2. Date: Thu, 21 Dec 2017 10:17:42 +0100
  3. Subject: [PATCH] flow_dissector: Parse batman-adv unicast headers
  4. The batman-adv unicast packets contain a full layer 2 frame in encapsulated
  5. form. The flow dissector must therefore be able to parse the batman-adv
  6. unicast header to reach the layer 2+3 information.
  7. +--------------------+
  8. | ip(v6)hdr |
  9. +--------------------+
  10. | inner ethhdr |
  11. +--------------------+
  12. | batadv unicast hdr |
  13. +--------------------+
  14. | outer ethhdr |
  15. +--------------------+
  16. The obtained information from the upper layer can then be used by RPS to
  17. schedule the processing on separate cores. This allows better distribution
  18. of multiple flows from the same neighbor to different cores.
  19. Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
  20. Reviewed-by: Jiri Pirko <jiri@mellanox.com>
  21. Acked-by: Willem de Bruijn <willemb@google.com>
  22. Signed-off-by: David S. Miller <davem@davemloft.net>
  23. ---
  24. --- a/net/core/flow_dissector.c
  25. +++ b/net/core/flow_dissector.c
  26. @@ -22,6 +22,7 @@
  27. #include <linux/tcp.h>
  28. #include <net/flow_dissector.h>
  29. #include <scsi/fc/fc_fcoe.h>
  30. +#include <uapi/linux/batadv_packet.h>
  31. static void dissector_set_key(struct flow_dissector *flow_dissector,
  32. enum flow_dissector_key_id key_id)
  33. @@ -338,6 +339,57 @@ __skb_flow_dissect_gre(const struct sk_b
  34. return FLOW_DISSECT_RET_PROTO_AGAIN;
  35. }
  36. +/**
  37. + * __skb_flow_dissect_batadv() - dissect batman-adv header
  38. + * @skb: sk_buff to with the batman-adv header
  39. + * @key_control: flow dissectors control key
  40. + * @data: raw buffer pointer to the packet, if NULL use skb->data
  41. + * @p_proto: pointer used to update the protocol to process next
  42. + * @p_nhoff: pointer used to update inner network header offset
  43. + * @hlen: packet header length
  44. + * @flags: any combination of FLOW_DISSECTOR_F_*
  45. + *
  46. + * ETH_P_BATMAN packets are tried to be dissected. Only
  47. + * &struct batadv_unicast packets are actually processed because they contain an
  48. + * inner ethernet header and are usually followed by actual network header. This
  49. + * allows the flow dissector to continue processing the packet.
  50. + *
  51. + * Return: FLOW_DISSECT_RET_PROTO_AGAIN when &struct batadv_unicast was found,
  52. + * FLOW_DISSECT_RET_OUT_GOOD when dissector should stop after encapsulation,
  53. + * otherwise FLOW_DISSECT_RET_OUT_BAD
  54. + */
  55. +static enum flow_dissect_ret
  56. +__skb_flow_dissect_batadv(const struct sk_buff *skb,
  57. + struct flow_dissector_key_control *key_control,
  58. + void *data, __be16 *p_proto, int *p_nhoff, int hlen,
  59. + unsigned int flags)
  60. +{
  61. + struct {
  62. + struct batadv_unicast_packet batadv_unicast;
  63. + struct ethhdr eth;
  64. + } *hdr, _hdr;
  65. +
  66. + hdr = __skb_header_pointer(skb, *p_nhoff, sizeof(_hdr), data, hlen,
  67. + &_hdr);
  68. + if (!hdr)
  69. + return FLOW_DISSECT_RET_OUT_BAD;
  70. +
  71. + if (hdr->batadv_unicast.version != BATADV_COMPAT_VERSION)
  72. + return FLOW_DISSECT_RET_OUT_BAD;
  73. +
  74. + if (hdr->batadv_unicast.packet_type != BATADV_UNICAST)
  75. + return FLOW_DISSECT_RET_OUT_BAD;
  76. +
  77. + *p_proto = hdr->eth.h_proto;
  78. + *p_nhoff += sizeof(*hdr);
  79. +
  80. + key_control->flags |= FLOW_DIS_ENCAPSULATION;
  81. + if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
  82. + return FLOW_DISSECT_RET_OUT_GOOD;
  83. +
  84. + return FLOW_DISSECT_RET_PROTO_AGAIN;
  85. +}
  86. +
  87. static void
  88. __skb_flow_dissect_tcp(const struct sk_buff *skb,
  89. struct flow_dissector *flow_dissector,
  90. @@ -722,6 +774,11 @@ proto_again:
  91. nhoff, hlen);
  92. break;
  93. + case htons(ETH_P_BATMAN):
  94. + fdret = __skb_flow_dissect_batadv(skb, key_control, data,
  95. + &proto, &nhoff, hlen, flags);
  96. + break;
  97. +
  98. default:
  99. fdret = FLOW_DISSECT_RET_OUT_BAD;
  100. break;