> -----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