From: Alexander Kozyrev <akozyrev@nvidia.com>
To: dev@dpdk.org
Cc: rasland@nvidia.com, viacheslavo@nvidia.com, matan@nvidia.com,
orika@nvidia.com
Subject: [dpdk-dev] [PATCH] net/mlx5: example of modify field rte flow action
Date: Mon, 18 Jan 2021 06:08:34 +0000 [thread overview]
Message-ID: <20210118060834.32049-1-akozyrev@nvidia.com> (raw)
This patch is a draft for upcoming full-fledged support
for newly added modify_field RTE Flow action.
The example shows how to use the modify_field API to set
a source or destination MAC address with an immediate
value specified by a user:
flow create 0 ingress group 0 pattern eth / end
actions modify_field op set dst_type mac_dst
src_type value src_value 12345678 width 32 / rss /end
Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
---
drivers/net/mlx5/mlx5_flow.h | 4 +-
drivers/net/mlx5/mlx5_flow_dv.c | 120 ++++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index eb9f97a278..27862edcd1 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -218,6 +218,7 @@ enum mlx5_feature_name {
#define MLX5_FLOW_ACTION_SAMPLE (1ull << 36)
#define MLX5_FLOW_ACTION_TUNNEL_SET (1ull << 37)
#define MLX5_FLOW_ACTION_TUNNEL_MATCH (1ull << 38)
+#define MLX5_FLOW_ACTION_MODIFY_FIELD (1ull << 39)
#define MLX5_FLOW_FATE_ACTIONS \
(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
@@ -248,7 +249,8 @@ enum mlx5_feature_name {
MLX5_FLOW_ACTION_MARK_EXT | \
MLX5_FLOW_ACTION_SET_META | \
MLX5_FLOW_ACTION_SET_IPV4_DSCP | \
- MLX5_FLOW_ACTION_SET_IPV6_DSCP)
+ MLX5_FLOW_ACTION_SET_IPV6_DSCP | \
+ MLX5_FLOW_ACTION_MODIFY_FIELD)
#define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN | \
MLX5_FLOW_ACTION_OF_PUSH_VLAN)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 860ef9aa01..fc8e95132d 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1320,6 +1320,52 @@ flow_dv_convert_action_modify_ipv6_dscp
MLX5_MODIFICATION_TYPE_SET, error);
}
+/**
+ * Convert modify_field action to DV specification.
+ *
+ * @param[in,out] resource
+ * Pointer to the modify-header resource.
+ * @param[in] action
+ * Pointer to action specification.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_convert_action_modify_field
+ (struct mlx5_flow_dv_modify_hdr_resource *resource,
+ const struct rte_flow_action *action,
+ struct rte_flow_error *error)
+{
+ const struct rte_flow_action_modify_field *conf =
+ (const struct rte_flow_action_modify_field *)(action->conf);
+ struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_ETH };
+ struct rte_flow_item_eth eth;
+ struct rte_flow_item_eth eth_mask;
+
+ memset(ð, 0, sizeof(eth));
+ memset(ð_mask, 0, sizeof(eth_mask));
+ if (conf->dst.field == RTE_FLOW_FIELD_MAC_SRC) {
+ memcpy(ð.src.addr_bytes, &conf->src.value,
+ sizeof(eth.src.addr_bytes));
+ memcpy(ð_mask.src.addr_bytes,
+ &rte_flow_item_eth_mask.src.addr_bytes,
+ sizeof(eth_mask.src.addr_bytes));
+ } else {
+ memcpy(ð.dst.addr_bytes, &conf->src.value,
+ sizeof(eth.dst.addr_bytes));
+ memcpy(ð_mask.dst.addr_bytes,
+ &rte_flow_item_eth_mask.dst.addr_bytes,
+ sizeof(eth_mask.dst.addr_bytes));
+ }
+ item.spec = ð
+ item.mask = ð_mask;
+ return flow_dv_convert_modify_action(&item, modify_eth, NULL, resource,
+ MLX5_MODIFICATION_TYPE_SET, error);
+}
+
/**
* Validate MARK item.
*
@@ -3984,6 +4030,61 @@ flow_dv_validate_action_modify_ttl(const uint64_t action_flags,
return ret;
}
+/**
+ * Validate the generic modify field actions.
+ *
+ * @param[in] action_flags
+ * Holds the actions detected until now.
+ * @param[in] action
+ * Pointer to the modify action.
+ * @param[in] item_flags
+ * Holds the items detected.
+ * @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_action_modify_field(const uint64_t action_flags,
+ const struct rte_flow_action *action,
+ const uint64_t item_flags,
+ struct rte_flow_error *error)
+{
+ int ret = 0;
+ const struct rte_flow_action_modify_field *action_modify_field =
+ action->conf;
+
+ ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
+ if (!ret) {
+ if (!(item_flags & MLX5_FLOW_LAYER_L2))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "no L2 item in pattern");
+ if (action_modify_field->operation != RTE_FLOW_MODIFY_SET)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "add and sub opearation are"
+ " not supported");
+ if (action_modify_field->dst.field != RTE_FLOW_FIELD_MAC_DST &&
+ action_modify_field->dst.field != RTE_FLOW_FIELD_MAC_SRC)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "cannot modify requested"
+ " header field");
+ if (action_modify_field->src.field != RTE_FLOW_FIELD_VALUE)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "copy form another packet"
+ " field is not suported");
+ }
+ return ret;
+}
+
/**
* Validate jump action.
*
@@ -6120,6 +6221,19 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
action_flags |= MLX5_FLOW_ACTION_TUNNEL_SET;
break;
+ case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD:
+ ret = flow_dv_validate_action_modify_field(action_flags,
+ actions,
+ item_flags,
+ error);
+ if (ret < 0)
+ return ret;
+ /* Count all modify-header actions as one action. */
+ if (!(action_flags & MLX5_FLOW_ACTION_MODIFY_FIELD))
+ ++actions_n;
+ action_flags |= MLX5_FLOW_ACTION_MODIFY_FIELD;
+ rw_act_num += MLX5_ACT_NUM_MDF_MAC;
+ break;
default:
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION,
@@ -10404,6 +10518,12 @@ flow_dv_translate(struct rte_eth_dev *dev,
sample_act->action_flags |=
MLX5_FLOW_ACTION_ENCAP;
break;
+ case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD:
+ if (flow_dv_convert_action_modify_field
+ (mhdr_res, actions, error))
+ return -rte_errno;
+ action_flags |= MLX5_FLOW_ACTION_MODIFY_FIELD;
+ break;
case RTE_FLOW_ACTION_TYPE_END:
actions_end = true;
if (mhdr_res->actions_num) {
--
2.24.1
reply other threads:[~2021-01-18 6:08 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20210118060834.32049-1-akozyrev@nvidia.com \
--to=akozyrev@nvidia.com \
--cc=dev@dpdk.org \
--cc=matan@nvidia.com \
--cc=orika@nvidia.com \
--cc=rasland@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).