From: Sean Zhang <xiazhang@nvidia.com>
To: Matan Azrad <matan@nvidia.com>,
Viacheslav Ovsiienko <viacheslavo@nvidia.com>
Cc: <dev@dpdk.org>
Subject: [v1] net/mlx5: support represented port item
Date: Sat, 2 Apr 2022 09:40:00 +0300 [thread overview]
Message-ID: <20220402064000.8772-1-xiazhang@nvidia.com> (raw)
Add support for represented_port item in pattern. And if the spec and mask
both are NULL, translate function will not add source vport to matcher.
For example, testpmd starts with PF, VF-rep0 and VF-rep1, below command
will redirect packets from VF0 and VF1 to wire:
testpmd> flow create 0 ingress transfer group 0 pattern eth /
represented_port / end actions represented_port ethdev_id is 0 / end
Signed-off-by: Sean Zhang <xiazhang@nvidia.com>
---
drivers/net/mlx5/mlx5_flow.h | 4 +
drivers/net/mlx5/mlx5_flow_dv.c | 160 +++++++++++++++++++++++++++++++-
2 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index f56115dd11..0740b01de5 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -186,6 +186,10 @@ enum mlx5_feature_name {
#define MLX5_FLOW_ITEM_INNER_FLEX (UINT64_C(1) << 38)
#define MLX5_FLOW_ITEM_FLEX_TUNNEL (UINT64_C(1) << 39)
+/* Port Representor/Represented Port item */
+#define MLX5_FLOW_ITEM_PORT_REPRESENTOR (UINT64_C(1) << 40)
+#define MLX5_FLOW_ITEM_REPRESENTED_PORT (UINT64_C(1) << 41)
+
/* Outer Masks. */
#define MLX5_FLOW_LAYER_OUTER_L3 \
(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 1e9bd63635..f20a64e8e4 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2209,6 +2209,80 @@ flow_dv_validate_item_port_id(struct rte_eth_dev *dev,
return 0;
}
+/**
+ * Validate represented port item.
+ *
+ * @param[in] dev
+ * Pointer to the rte_eth_dev structure.
+ * @param[in] item
+ * Item specification.
+ * @param[in] attr
+ * Attributes of flow that includes this item.
+ * @param[in] item_flags
+ * Bit-fields that holds the items detected until now.
+ * @param[out] error
+ * Pointer to error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_validate_item_represented_port(struct rte_eth_dev *dev,
+ const struct rte_flow_item *item,
+ const struct rte_flow_attr *attr,
+ uint64_t item_flags,
+ struct rte_flow_error *error)
+{
+ const struct rte_flow_item_ethdev *spec = item->spec;
+ const struct rte_flow_item_ethdev *mask = item->mask;
+ const struct rte_flow_item_ethdev switch_mask = {
+ .port_id = UINT16_MAX,
+ };
+ struct mlx5_priv *esw_priv;
+ struct mlx5_priv *dev_priv;
+ int ret;
+
+ if (!attr->transfer)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+ "match on port id is valid only when transfer flag is enabled");
+ if (item_flags & MLX5_FLOW_ITEM_REPRESENTED_PORT)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ITEM, item,
+ "multiple source ports are not supported");
+ if (!mask)
+ mask = &switch_mask;
+ if (mask->port_id != UINT16_MAX)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,
+ "no support for partial mask on \"id\" field");
+ ret = mlx5_flow_item_acceptable
+ (item, (const uint8_t *)mask,
+ (const uint8_t *)&rte_flow_item_ethdev_mask,
+ sizeof(struct rte_flow_item_ethdev),
+ MLX5_ITEM_RANGE_NOT_ACCEPTED, error);
+ if (ret)
+ return ret;
+ if (!spec || spec->port_id == UINT16_MAX)
+ return 0;
+ esw_priv = mlx5_port_to_eswitch_info(spec->port_id, false);
+ if (!esw_priv)
+ return rte_flow_error_set(error, rte_errno,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC, spec,
+ "failed to obtain E-Switch info for port");
+ dev_priv = mlx5_dev_to_eswitch_info(dev);
+ if (!dev_priv)
+ return rte_flow_error_set(error, rte_errno,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL,
+ "failed to obtain E-Switch info");
+ if (esw_priv->domain_id != dev_priv->domain_id)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC, spec,
+ "cannot match on a port from a different E-Switch");
+ return 0;
+}
+
/**
* Validate VLAN item.
*
@@ -6963,6 +7037,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
last_item = MLX5_FLOW_ITEM_PORT_ID;
port_id_item = items;
break;
+ case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
+ ret = flow_dv_validate_item_represented_port
+ (dev, items, attr, item_flags, error);
+ if (ret < 0)
+ return ret;
+ last_item = MLX5_FLOW_ITEM_REPRESENTED_PORT;
+ break;
case RTE_FLOW_ITEM_TYPE_ETH:
ret = mlx5_flow_validate_item_eth(items, item_flags,
true, error);
@@ -9918,6 +9999,77 @@ flow_dv_translate_item_port_id(struct rte_eth_dev *dev, void *matcher,
return 0;
}
+/**
+ * Translate represented port item to eswitch match on port id.
+ *
+ * @param[in] dev
+ * The devich to configure through.
+ * @param[in, out] matcher
+ * Flow matcher.
+ * @param[in, out] key
+ * Flow matcher value.
+ * @param[in] item
+ * Flow pattern to translate.
+ * @param[in]
+ * Flow attributes.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise.
+ */
+static int
+flow_dv_translate_item_represented_port(struct rte_eth_dev *dev, void *matcher,
+ void *key,
+ const struct rte_flow_item *item,
+ const struct rte_flow_attr *attr)
+{
+ const struct rte_flow_item_ethdev *pid_m = item ? item->mask : NULL;
+ const struct rte_flow_item_ethdev *pid_v = item ? item->spec : NULL;
+ struct mlx5_priv *priv;
+ uint16_t mask, id;
+
+ if (!pid_m && !pid_v)
+ return 0;
+ if (pid_v && pid_v->port_id == UINT16_MAX) {
+ flow_dv_translate_item_source_vport(matcher, key,
+ flow_dv_get_esw_manager_vport_id(dev), UINT16_MAX);
+ return 0;
+ }
+ mask = pid_m ? pid_m->port_id : UINT16_MAX;
+ id = pid_v ? pid_v->port_id : dev->data->port_id;
+ priv = mlx5_port_to_eswitch_info(id, item == NULL);
+ if (!priv)
+ return -rte_errno;
+ /*
+ * Translate to vport field or to metadata, depending on mode.
+ * Kernel can use either misc.source_port or half of C0 metadata
+ * register.
+ */
+ if (priv->vport_meta_mask) {
+ /*
+ * Provide the hint for SW steering library
+ * to insert the flow into ingress domain and
+ * save the extra vport match.
+ */
+ if (mask == UINT16_MAX && priv->vport_id == UINT16_MAX &&
+ priv->pf_bond < 0 && attr->transfer)
+ flow_dv_translate_item_source_vport
+ (matcher, key, priv->vport_id, mask);
+ /*
+ * We should always set the vport metadata register,
+ * otherwise the SW steering library can drop
+ * the rule if wire vport metadata value is not zero,
+ * it depends on kernel configuration.
+ */
+ flow_dv_translate_item_meta_vport(matcher, key,
+ priv->vport_meta_tag,
+ priv->vport_meta_mask);
+ } else {
+ flow_dv_translate_item_source_vport(matcher, key,
+ priv->vport_id, mask);
+ }
+ return 0;
+}
+
/**
* Add ICMP6 item to matcher and to the value.
*
@@ -13543,6 +13695,11 @@ flow_dv_translate(struct rte_eth_dev *dev,
(dev, match_mask, match_value, items, attr);
last_item = MLX5_FLOW_ITEM_PORT_ID;
break;
+ case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
+ flow_dv_translate_item_represented_port
+ (dev, match_mask, match_value, items, attr);
+ last_item = MLX5_FLOW_ITEM_REPRESENTED_PORT;
+ break;
case RTE_FLOW_ITEM_TYPE_ETH:
flow_dv_translate_item_eth(match_mask, match_value,
items, tunnel,
@@ -13801,7 +13958,8 @@ flow_dv_translate(struct rte_eth_dev *dev,
* In both cases the source port is set according the current port
* in use.
*/
- if (!(item_flags & MLX5_FLOW_ITEM_PORT_ID) && priv->sh->esw_mode &&
+ if (!(item_flags & MLX5_FLOW_ITEM_PORT_ID) &&
+ !(item_flags & MLX5_FLOW_ITEM_REPRESENTED_PORT) && priv->sh->esw_mode &&
!(attr->egress && !attr->transfer)) {
if (flow_dv_translate_item_port_id(dev, match_mask,
match_value, NULL, attr))
--
2.21.0
next reply other threads:[~2022-04-02 6:40 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-02 6:40 Sean Zhang [this message]
2022-06-06 7:21 ` Slava Ovsiienko
2022-06-07 11:17 ` [v2] " Sean Zhang
2022-06-14 7:44 ` Raslan Darawsheh
2022-06-07 11:18 ` [v2 0/3] Add support for modifying ECN in IPv4/IPv6 header Sean Zhang
2022-06-07 11:18 ` [v2 1/3] common/mlx5: add modify ECN capability check Sean Zhang
2022-06-07 11:18 ` [v2 2/3] net/mlx5: add support to modify ECN field Sean Zhang
2022-06-07 11:19 ` [v2 3/3] net/mlx5: add modify field support in meter Sean Zhang
2022-06-14 7:45 ` [v2 0/3] Add support for modifying ECN in IPv4/IPv6 header Raslan Darawsheh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220402064000.8772-1-xiazhang@nvidia.com \
--to=xiazhang@nvidia.com \
--cc=dev@dpdk.org \
--cc=matan@nvidia.com \
--cc=viacheslavo@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).