Re: [PATCH net-next v3 1/4] net: dsa: add support for DSA rx offloading via metadata dst

Vladimir Oltean
2022-11-14T12:15:14Z

On Thu, Nov 10, 2022 at 10:22:08PM +0100, Felix Fietkau wrote:
> If a metadata dst is present with the type METADATA_HW_PORT_MUX on a dsa cpu
> port netdev, assume that it carries the port number and that there is no DSA
> tag present in the skb data.
>
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
> ---
> net/core/flow_dissector.c | 4 +++-
> net/dsa/dsa.c | 19 ++++++++++++++++++-
> 2 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> index 25cd35f5922e..1f476abc25e1 100644
> --- a/net/core/flow_dissector.c
> +++ b/net/core/flow_dissector.c
> @@ -972,11 +972,13 @@ bool __skb_flow_dissect(const struct net *net,
> if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
> proto == htons(ETH_P_XDSA))) {
> const struct dsa_device_ops *ops;
> + struct metadata_dst *md_dst = skb_metadata_dst(skb);

Since you're resending, could you please preserve reverse Christmas tree
variable ordering here?

> int offset = 0;
>
> ops = skb->dev->dsa_ptr->tag_ops;
> /* Only DSA header taggers break flow dissection */
> - if (ops->needed_headroom) {
> + if (ops->needed_headroom &&
> + (!md_dst || md_dst->type != METADATA_HW_PORT_MUX)) {
> if (ops->flow_dissect)
> ops->flow_dissect(skb, &proto, &offset);
> else
> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> index 64b14f655b23..0b67622cf905 100644
> --- a/net/dsa/dsa.c
> +++ b/net/dsa/dsa.c
> @@ -11,6 +11,7 @@
> #include <linux/netdevice.h>
> #include <linux/sysfs.h>
> #include <linux/ptp_classify.h>
> +#include <net/dst_metadata.h>
>
> #include "dsa_priv.h"
>
> @@ -216,6 +217,7 @@ static bool dsa_skb_defer_rx_timestamp(struct dsa_slave_priv *p,
> static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
> struct packet_type *pt, struct net_device *unused)
> {
> + struct metadata_dst *md_dst = skb_metadata_dst(skb);
> struct dsa_port *cpu_dp = dev->dsa_ptr;
> struct sk_buff *nskb = NULL;
> struct dsa_slave_priv *p;
> @@ -229,7 +231,22 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
> if (!skb)
> return 0;
>
> - nskb = cpu_dp->rcv(skb, dev);
> + if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) {
> + unsigned int port = md_dst->u.port_info.port_id;
> +
> + skb_dst_set(skb, NULL);
> + if (!skb_has_extensions(skb))
> + skb->slow_gro = 0;
> +
> + skb->dev = dsa_master_find_slave(dev, 0, port);
> + if (likely(skb->dev)) {
> + dsa_default_offload_fwd_mark(skb);
> + nskb = skb;
> + }
> + } else {
> + nskb = cpu_dp->rcv(skb, dev);
> + }
> +
> if (!nskb) {
> kfree_skb(skb);
> return 0;
> --
> 2.38.1
>