From: Andrew Rybchenko Date: Wed, 13 Oct 2021 17:34:45 +0000 (+0300) Subject: net/enic: support meta flow actions to overrule destinations X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=54bd4ebe8b059ce3d9128583e7b99bd0fd62fe29;p=dpdk.git net/enic: support meta flow actions to overrule destinations Add support for actions PORT_REPRESENTOR and REPRESENTED_PORT based on the existing support for action PORT_ID. Signed-off-by: Andrew Rybchenko Acked-by: Hyong Youb Kim --- diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini index a582616c07..ecff6c5f26 100644 --- a/doc/guides/nics/features/enic.ini +++ b/doc/guides/nics/features/enic.ini @@ -62,6 +62,8 @@ of_set_vlan_pcp = Y of_set_vlan_vid = Y passthru = Y port_id = Y +port_representor = Y +represented_port = Y queue = Y rss = Y vxlan_decap = Y 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; }