> -----Original Message-----
> From: Ivan Malov <ivan.ma...@oktetlabs.ru>
> Sent: Sunday, October 10, 2021 11:39 PM
> To: dev@dpdk.org
> Cc: Thomas Monjalon <tho...@monjalon.net>; Ori Kam
> <or...@nvidia.com>; Andrew Rybchenko
> <andrew.rybche...@oktetlabs.ru>; John Daley (johndale)
> <johnd...@cisco.com>; Hyong Youb Kim (hyonkim) <hyon...@cisco.com>
> Subject: [PATCH v3 09/12] net/enic: support meta flow actions to overrule
> destinations
> 
> From: Andrew Rybchenko <andrew.rybche...@oktetlabs.ru>
> 
> Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT
> based on the existing support for action PORT_ID.
> 
> Signed-off-by: Andrew Rybchenko <andrew.rybche...@oktetlabs.ru>
> ---
>  drivers/net/enic/enic_fm_flow.c | 93 ++++++++++++++++++++++++++-----
> --
>  1 file changed, 75 insertions(+), 18 deletions(-)
> 

Looks good to me. Thanks a lot.

Acked-by: Hyong Youb Kim <hyon...@cisco.com>

-Hyong

> diff --git a/drivers/net/enic/enic_fm_flow.c
> b/drivers/net/enic/enic_fm_flow.c
> index cd364ee16b..4092ff1f61 100644
> --- a/drivers/net/enic/enic_fm_flow.c
> +++ b/drivers/net/enic/enic_fm_flow.c
> @@ -1242,6 +1242,35 @@ vf_egress_port_id_action(struct enic_flowman
> *fm,
>       return 0;
>  }
> 
> +static int
> +enic_fm_check_transfer_dst(struct enic *enic, uint16_t dst_port_id,
> +                        struct rte_eth_dev **dst_dev,
> +                        struct rte_flow_error *error)
> +{
> +     struct rte_eth_dev *dev;
> +
> +     ENICPMD_LOG(DEBUG, "port id %u", dst_port_id);
> +     if (!rte_eth_dev_is_valid_port(dst_port_id)) {
> +             return rte_flow_error_set(error, EINVAL,
> +                     RTE_FLOW_ERROR_TYPE_ACTION,
> +                     NULL, "invalid port_id");
> +     }
> +     dev = &rte_eth_devices[dst_port_id];
> +     if (!dev_is_enic(dev)) {
> +             return rte_flow_error_set(error, EINVAL,
> +                     RTE_FLOW_ERROR_TYPE_ACTION,
> +                     NULL, "port_id is not enic");
> +     }
> +     if (enic->switch_domain_id != pmd_priv(dev)->switch_domain_id) {
> +             return rte_flow_error_set(error, EINVAL,
> +                     RTE_FLOW_ERROR_TYPE_ACTION,
> +                     NULL, "destination and source ports are not in the
> same switch domain");
> +     }
> +
> +     *dst_dev = dev;
> +     return 0;
> +}
> +
>  /* Translate flow actions to flowman TCAM entry actions */
>  static int
>  enic_fm_copy_action(struct enic_flowman *fm,
> @@ -1446,24 +1475,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
>                               vnic_h = enic->fm_vnic_handle; /* This port
> */
>                               break;
>                       }
> -                     ENICPMD_LOG(DEBUG, "port id %u", port->id);
> -                     if (!rte_eth_dev_is_valid_port(port->id)) {
> -                             return rte_flow_error_set(error, EINVAL,
> -                                     RTE_FLOW_ERROR_TYPE_ACTION,
> -                                     NULL, "invalid port_id");
> -                     }
> -                     dev = &rte_eth_devices[port->id];
> -                     if (!dev_is_enic(dev)) {
> -                             return rte_flow_error_set(error, EINVAL,
> -                                     RTE_FLOW_ERROR_TYPE_ACTION,
> -                                     NULL, "port_id is not enic");
> -                     }
> -                     if (enic->switch_domain_id !=
> -                         pmd_priv(dev)->switch_domain_id) {
> -                             return rte_flow_error_set(error, EINVAL,
> -                                     RTE_FLOW_ERROR_TYPE_ACTION,
> -                                     NULL, "destination and source ports
> are not in the same switch domain");
> -                     }
> +                     ret = enic_fm_check_transfer_dst(enic, port->id,
> &dev,
> +                                                      error);
> +                     if (ret)
> +                             return ret;
>                       vnic_h = pmd_priv(dev)->fm_vnic_handle;
>                       overlap |= PORT_ID;
>                       /*
> @@ -1560,6 +1575,48 @@ enic_fm_copy_action(struct enic_flowman *fm,
>                       ovlan |= rte_be_to_cpu_16(vid->vlan_vid);
>                       break;
>               }
> +             case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: {
> +                     const struct rte_flow_action_ethdev *ethdev;
> +                     struct rte_eth_dev *dev;
> +
> +                     ethdev = actions->conf;
> +                     ret = enic_fm_check_transfer_dst(enic, ethdev-
> >port_id,
> +                                                      &dev, error);
> +                     if (ret)
> +                             return ret;
> +                     vnic_h = pmd_priv(dev)->fm_vnic_handle;
> +                     overlap |= PORT_ID;
> +                     /*
> +                      * Action PORT_REPRESENTOR implies ingress
> destination.
> +                      * Noting to do. We add an implicit stree at the
> +                      * end if needed.
> +                      */
> +                     ingress = 1;
> +                     break;
> +             }
> +             case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: {
> +                     const struct rte_flow_action_ethdev *ethdev;
> +                     struct rte_eth_dev *dev;
> +
> +                     if (overlap & PORT_ID) {
> +                             ENICPMD_LOG(DEBUG, "cannot have
> multiple egress PORT_ID actions");
> +                             goto unsupported;
> +                     }
> +                     ethdev = actions->conf;
> +                     ret = enic_fm_check_transfer_dst(enic, ethdev-
> >port_id,
> +                                                      &dev, error);
> +                     if (ret)
> +                             return ret;
> +                     vnic_h = pmd_priv(dev)->fm_vnic_handle;
> +                     overlap |= PORT_ID;
> +                     /* Action REPRESENTED_PORT: always egress
> destination */
> +                     ingress = 0;
> +                     ret = vf_egress_port_id_action(fm, dev, vnic_h,
> &fm_op,
> +                             error);
> +                     if (ret)
> +                             return ret;
> +                     break;
> +             }
>               default:
>                       goto unsupported;
>               }
> --
> 2.20.1

Reply via email to