732-08-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. From: Felix Fietkau <[email protected]>
  2. Date: Tue, 8 Nov 2022 15:03:15 +0100
  3. Subject: [PATCH] net: dsa: add support for DSA rx offloading via
  4. metadata dst
  5. If a metadata dst is present with the type METADATA_HW_PORT_MUX on a dsa cpu
  6. port netdev, assume that it carries the port number and that there is no DSA
  7. tag present in the skb data.
  8. Signed-off-by: Felix Fietkau <[email protected]>
  9. ---
  10. --- a/net/core/flow_dissector.c
  11. +++ b/net/core/flow_dissector.c
  12. @@ -941,11 +941,13 @@ bool __skb_flow_dissect(const struct net
  13. if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
  14. proto == htons(ETH_P_XDSA))) {
  15. const struct dsa_device_ops *ops;
  16. + struct metadata_dst *md_dst = skb_metadata_dst(skb);
  17. int offset = 0;
  18. ops = skb->dev->dsa_ptr->tag_ops;
  19. /* Only DSA header taggers break flow dissection */
  20. - if (ops->needed_headroom) {
  21. + if (ops->needed_headroom &&
  22. + (!md_dst || md_dst->type != METADATA_HW_PORT_MUX)) {
  23. if (ops->flow_dissect)
  24. ops->flow_dissect(skb, &proto, &offset);
  25. else
  26. --- a/net/dsa/dsa.c
  27. +++ b/net/dsa/dsa.c
  28. @@ -20,6 +20,7 @@
  29. #include <linux/phy_fixed.h>
  30. #include <linux/ptp_classify.h>
  31. #include <linux/etherdevice.h>
  32. +#include <net/dst_metadata.h>
  33. #include "dsa_priv.h"
  34. @@ -225,6 +226,7 @@ static bool dsa_skb_defer_rx_timestamp(s
  35. static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
  36. struct packet_type *pt, struct net_device *unused)
  37. {
  38. + struct metadata_dst *md_dst = skb_metadata_dst(skb);
  39. struct dsa_port *cpu_dp = dev->dsa_ptr;
  40. struct sk_buff *nskb = NULL;
  41. struct dsa_slave_priv *p;
  42. @@ -238,7 +240,21 @@ static int dsa_switch_rcv(struct sk_buff
  43. if (!skb)
  44. return 0;
  45. - nskb = cpu_dp->rcv(skb, dev);
  46. + if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) {
  47. + unsigned int port = md_dst->u.port_info.port_id;
  48. +
  49. + dsa_default_offload_fwd_mark(skb);
  50. + skb_dst_set(skb, NULL);
  51. + if (!skb_has_extensions(skb))
  52. + skb->slow_gro = 0;
  53. +
  54. + skb->dev = dsa_master_find_slave(dev, 0, port);
  55. + if (skb->dev)
  56. + nskb = skb;
  57. + } else {
  58. + nskb = cpu_dp->rcv(skb, dev);
  59. + }
  60. +
  61. if (!nskb) {
  62. kfree_skb(skb);
  63. return 0;