* [dpdk-dev] [PATCH 1/2] ethdev: add IPv4/IPv6 DSCP rewrite action
2020-01-02 6:04 [dpdk-dev] [PATCH 0/2] add IPv4/IPv6 DSCP rewrite action Suanming Mou
@ 2020-01-02 6:04 ` Suanming Mou
2020-01-02 6:04 ` [dpdk-dev] [PATCH 2/2] net/mlx5: " Suanming Mou
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 0/2] " Suanming Mou
2 siblings, 0 replies; 10+ messages in thread
From: Suanming Mou @ 2020-01-02 6:04 UTC (permalink / raw)
To: Adrien Mazarguil, Wenzhuo Lu, Jingjing Wu, Bernard Iremonger,
John McNamara, Marko Kovacevic, Thomas Monjalon, Ferruh Yigit,
Andrew Rybchenko
Cc: dev, orika
For some overlay network, such as VXLAN, the DSCP field in the new outer
IP header after VXLAN decapsulation may need to be updated accordingly.
This commit introduce the DSCP modify action for IPv4 and IPv6.
Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Ori Kam <orika@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 50 +++++++++++++++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 40 +++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 +++++
lib/librte_ethdev/rte_flow.c | 2 ++
lib/librte_ethdev/rte_flow.h | 31 ++++++++++++++++++
5 files changed, 131 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 99dade7..77a6141 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -326,6 +326,10 @@ enum index {
ACTION_SET_META,
ACTION_SET_META_DATA,
ACTION_SET_META_MASK,
+ ACTION_SET_IPV4_DSCP,
+ ACTION_SET_IPV4_DSCP_VALUE,
+ ACTION_SET_IPV6_DSCP,
+ ACTION_SET_IPV6_DSCP_VALUE,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1087,6 +1091,8 @@ struct parse_action_priv {
ACTION_RAW_DECAP,
ACTION_SET_TAG,
ACTION_SET_META,
+ ACTION_SET_IPV4_DSCP,
+ ACTION_SET_IPV6_DSCP,
ZERO,
};
@@ -1300,6 +1306,18 @@ struct parse_action_priv {
ZERO,
};
+static const enum index action_set_ipv4_dscp[] = {
+ ACTION_SET_IPV4_DSCP_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_dscp[] = {
+ ACTION_SET_IPV6_DSCP_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
static int parse_set_raw_encap_decap(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -3493,6 +3511,38 @@ static int comp_set_raw_index(struct context *, const struct token *,
(struct rte_flow_action_set_meta, mask)),
.call = parse_vc_conf,
},
+ [ACTION_SET_IPV4_DSCP] = {
+ .name = "set_ipv4_dscp",
+ .help = "set DSCP value",
+ .priv = PRIV_ACTION(SET_IPV4_DSCP,
+ sizeof(struct rte_flow_action_set_dscp)),
+ .next = NEXT(action_set_ipv4_dscp),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_DSCP_VALUE] = {
+ .name = "dscp_value",
+ .help = "new IPv4 DSCP value to set",
+ .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY
+ (struct rte_flow_action_set_dscp, dscp)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_DSCP] = {
+ .name = "set_ipv6_dscp",
+ .help = "set DSCP value",
+ .priv = PRIV_ACTION(SET_IPV6_DSCP,
+ sizeof(struct rte_flow_action_set_dscp)),
+ .next = NEXT(action_set_ipv6_dscp),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_DSCP_VALUE] = {
+ .name = "dscp_value",
+ .help = "new IPv6 DSCP value to set",
+ .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY
+ (struct rte_flow_action_set_dscp, dscp)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a254c81..2f21309 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2558,6 +2558,46 @@ the other path depending on HW capability.
| ``mask`` | bit-mask applies to "data" |
+----------+----------------------------+
+Action: ``SET_IPV4_DSCP``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set IPv4 DSCP.
+
+Modify DSCP in IPv4 header.
+
+It must be used with RTE_FLOW_ITEM_TYPE_IPV4 in pattern.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_dscp:
+
+.. table:: SET_IPV4_DSCP
+
+ +-----------+---------------------------------+
+ | Field | Value |
+ +===========+=================================+
+ | ``dscp`` | DSCP in low 6 bits, rest ignore |
+ +-----------+---------------------------------+
+
+Action: ``SET_IPV6_DSCP``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set IPv6 DSCP.
+
+Modify DSCP in IPv6 header.
+
+It must be used with RTE_FLOW_ITEM_TYPE_IPV6 in pattern.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_dscp:
+
+.. table:: SET_IPV6_DSCP
+
+ +-----------+---------------------------------+
+ | Field | Value |
+ +===========+=================================+
+ | ``dscp`` | DSCP in low 6 bits, rest ignore |
+ +-----------+---------------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 10aabf5..3baaacb 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4228,6 +4228,14 @@ This section lists supported actions and their attributes, if any.
- ``value {unsigned}``: Value to decrease TCP acknowledgment number by.
+- ``set_ipv4_dscp``: Set IPv4 DSCP value with specified value
+
+ - ``dscp_value {unsigned}``: The new DSCP value to be set
+
+- ``set_ipv6_dscp``: Set IPv6 DSCP value with specified value
+
+ - ``dscp_value {unsigned}``: The new DSCP value to be set
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 87a3e8c..b86aee3 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -168,6 +168,8 @@ struct rte_flow_desc_data {
MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
MK_FLOW_ACTION(SET_TAG, sizeof(struct rte_flow_action_set_tag)),
MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
+ MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
+ MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
};
int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index 452d359..76bf080 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -2004,6 +2004,26 @@ enum rte_flow_action_type {
* See struct rte_flow_action_set_meta.
*/
RTE_FLOW_ACTION_TYPE_SET_META,
+
+ /**
+ * Modify IPv4 DSCP in the outermost IP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV4,
+ * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_dscp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP,
+
+ /**
+ * Modify IPv6 DSCP in the outermost IP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV6,
+ * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_dscp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP,
};
/**
@@ -2530,6 +2550,17 @@ struct rte_flow_action_set_meta {
uint32_t mask;
};
+/**
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+ *
+ * Set the DSCP value for IPv4/IPv6 header.
+ * DSCP in low 6 bits, rest ignored.
+ */
+struct rte_flow_action_set_dscp {
+ uint8_t dscp;
+};
+
/* Mbuf dynamic field offset for metadata. */
extern int rte_flow_dynf_metadata_offs;
--
1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [dpdk-dev] [PATCH 2/2] net/mlx5: add IPv4/IPv6 DSCP rewrite action
2020-01-02 6:04 [dpdk-dev] [PATCH 0/2] add IPv4/IPv6 DSCP rewrite action Suanming Mou
2020-01-02 6:04 ` [dpdk-dev] [PATCH 1/2] ethdev: " Suanming Mou
@ 2020-01-02 6:04 ` Suanming Mou
2020-01-06 14:36 ` Matan Azrad
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 0/2] " Suanming Mou
2 siblings, 1 reply; 10+ messages in thread
From: Suanming Mou @ 2020-01-02 6:04 UTC (permalink / raw)
To: Matan Azrad, Shahaf Shuler, Viacheslav Ovsiienko
Cc: dev, orika, arybchenko, ferruh.yigit, thomas
This commit add the IPv4/IPv6 DSCP rewrite actions to the PMD code.
Supported actions:
RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
---
drivers/net/mlx5/mlx5_flow.h | 6 +-
drivers/net/mlx5/mlx5_flow_dv.c | 184 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 189 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 27d82ac..e42c98a 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -196,6 +196,8 @@ enum mlx5_feature_name {
#define MLX5_FLOW_ACTION_MARK_EXT (1ull << 33)
#define MLX5_FLOW_ACTION_SET_META (1ull << 34)
#define MLX5_FLOW_ACTION_METER (1ull << 35)
+#define MLX5_FLOW_ACTION_SET_IPV4_DSCP (1ull << 36)
+#define MLX5_FLOW_ACTION_SET_IPV6_DSCP (1ull << 37)
#define MLX5_FLOW_FATE_ACTIONS \
(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
@@ -232,7 +234,9 @@ enum mlx5_feature_name {
MLX5_FLOW_ACTION_OF_SET_VLAN_VID | \
MLX5_FLOW_ACTION_SET_TAG | \
MLX5_FLOW_ACTION_MARK_EXT | \
- MLX5_FLOW_ACTION_SET_META)
+ MLX5_FLOW_ACTION_SET_META | \
+ MLX5_FLOW_ACTION_SET_IPV4_DSCP | \
+ MLX5_FLOW_ACTION_SET_IPV6_DSCP)
#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 4c16281..15fe726 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -157,6 +157,7 @@ struct field_modify_info modify_vlan_out_first_vid[] = {
};
struct field_modify_info modify_ipv4[] = {
+ {1, 1, MLX5_MODI_OUT_IP_DSCP},
{1, 8, MLX5_MODI_OUT_IPV4_TTL},
{4, 12, MLX5_MODI_OUT_SIPV4},
{4, 16, MLX5_MODI_OUT_DIPV4},
@@ -164,6 +165,7 @@ struct field_modify_info modify_ipv4[] = {
};
struct field_modify_info modify_ipv6[] = {
+ {1, 0, MLX5_MODI_OUT_IP_DSCP},
{1, 7, MLX5_MODI_OUT_IPV6_HOPLIMIT},
{4, 8, MLX5_MODI_OUT_SIPV6_127_96},
{4, 12, MLX5_MODI_OUT_SIPV6_95_64},
@@ -1191,6 +1193,82 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Convert modify-header set IPv4 DSCP 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_ipv4_dscp
+ (struct mlx5_flow_dv_modify_hdr_resource *resource,
+ const struct rte_flow_action *action,
+ struct rte_flow_error *error)
+{
+ const struct rte_flow_action_set_dscp *conf =
+ (const struct rte_flow_action_set_dscp *)(action->conf);
+ struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV4 };
+ struct rte_flow_item_ipv4 ipv4;
+ struct rte_flow_item_ipv4 ipv4_mask;
+
+ memset(&ipv4, 0, sizeof(ipv4));
+ memset(&ipv4_mask, 0, sizeof(ipv4_mask));
+ ipv4.hdr.type_of_service = conf->dscp;
+ ipv4_mask.hdr.type_of_service = 0x3f;
+ item.spec = &ipv4;
+ item.mask = &ipv4_mask;
+ return flow_dv_convert_modify_action(&item, modify_ipv4, NULL, resource,
+ MLX5_MODIFICATION_TYPE_SET, error);
+}
+
+/**
+ * Convert modify-header set IPv6 DSCP 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_ipv6_dscp
+ (struct mlx5_flow_dv_modify_hdr_resource *resource,
+ const struct rte_flow_action *action,
+ struct rte_flow_error *error)
+{
+ const struct rte_flow_action_set_dscp *conf =
+ (const struct rte_flow_action_set_dscp *)(action->conf);
+ struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV6 };
+ struct rte_flow_item_ipv6 ipv6;
+ struct rte_flow_item_ipv6 ipv6_mask;
+
+ memset(&ipv6, 0, sizeof(ipv6));
+ memset(&ipv6_mask, 0, sizeof(ipv6_mask));
+ /*
+ * Even though the DSCP bits offset of IPv6 is not byte aligned,
+ * rdma-core only accept the DSCP bits byte aligned start from
+ * bit 0 to 5 as to be compatible with IPv4. No need to shift the
+ * bits in IPv6 case as rdma-core requires byte aligned value.
+ */
+ ipv6.hdr.vtc_flow = conf->dscp;
+ ipv6_mask.hdr.vtc_flow = 0x3f;
+ item.spec = &ipv6;
+ item.mask = &ipv6_mask;
+ return flow_dv_convert_modify_action(&item, modify_ipv6, NULL, resource,
+ MLX5_MODIFICATION_TYPE_SET, error);
+}
+
+/**
* Validate MARK item.
*
* @param[in] dev
@@ -3433,6 +3511,74 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Validate the modify-header IPv4 DSCP 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_ipv4_dscp(const uint64_t action_flags,
+ const struct rte_flow_action *action,
+ const uint64_t item_flags,
+ struct rte_flow_error *error)
+{
+ int ret = 0;
+
+ ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
+ if (!ret) {
+ if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV4))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "no ipv4 item in pattern");
+ }
+ return ret;
+}
+
+/**
+ * Validate the modify-header IPv6 DSCP 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_ipv6_dscp(const uint64_t action_flags,
+ const struct rte_flow_action *action,
+ const uint64_t item_flags,
+ struct rte_flow_error *error)
+{
+ int ret = 0;
+
+ ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
+ if (!ret) {
+ if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV6))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "no ipv6 item in pattern");
+ }
+ return ret;
+}
+
+/**
* Find existing modify-header resource or create and register a new one.
*
* @param dev[in, out]
@@ -4806,6 +4952,32 @@ struct field_modify_info modify_tcp[] = {
action_flags |= MLX5_FLOW_ACTION_METER;
++actions_n;
break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+ ret = flow_dv_validate_action_modify_ipv4_dscp
+ (action_flags,
+ actions,
+ item_flags,
+ error);
+ if (ret < 0)
+ return ret;
+ /* Count all modify-header actions as one action. */
+ if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
+ ++actions_n;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV4_DSCP;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+ ret = flow_dv_validate_action_modify_ipv6_dscp
+ (action_flags,
+ actions,
+ item_flags,
+ error);
+ if (ret < 0)
+ return ret;
+ /* Count all modify-header actions as one action. */
+ if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
+ ++actions_n;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV6_DSCP;
+ break;
default:
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION,
@@ -7101,6 +7273,18 @@ struct field_modify_info modify_tcp[] = {
flow->meter->mfts->meter_action;
action_flags |= MLX5_FLOW_ACTION_METER;
break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+ if (flow_dv_convert_action_modify_ipv4_dscp(&mhdr_res,
+ actions, error))
+ return -rte_errno;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV4_DSCP;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+ if (flow_dv_convert_action_modify_ipv6_dscp(&mhdr_res,
+ actions, error))
+ return -rte_errno;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV6_DSCP;
+ break;
case RTE_FLOW_ACTION_TYPE_END:
actions_end = true;
if (mhdr_res.actions_num) {
--
1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [dpdk-dev] [PATCH 2/2] net/mlx5: add IPv4/IPv6 DSCP rewrite action
2020-01-02 6:04 ` [dpdk-dev] [PATCH 2/2] net/mlx5: " Suanming Mou
@ 2020-01-06 14:36 ` Matan Azrad
2020-01-07 6:33 ` Suanming Mou
0 siblings, 1 reply; 10+ messages in thread
From: Matan Azrad @ 2020-01-06 14:36 UTC (permalink / raw)
To: Suanming Mou, Shahaf Shuler, Slava Ovsiienko
Cc: dev, Ori Kam, arybchenko, ferruh.yigit, Thomas Monjalon
Hi
From: Suanming Mou
> This commit add the IPv4/IPv6 DSCP rewrite actions to the PMD code.
>
> Supported actions:
> RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
> RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
>
> Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
> ---
> drivers/net/mlx5/mlx5_flow.h | 6 +-
> drivers/net/mlx5/mlx5_flow_dv.c | 184
> ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 189 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
> index 27d82ac..e42c98a 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -196,6 +196,8 @@ enum mlx5_feature_name { #define
> MLX5_FLOW_ACTION_MARK_EXT (1ull << 33) #define
> MLX5_FLOW_ACTION_SET_META (1ull << 34) #define
> MLX5_FLOW_ACTION_METER (1ull << 35)
> +#define MLX5_FLOW_ACTION_SET_IPV4_DSCP (1ull << 36) #define
> +MLX5_FLOW_ACTION_SET_IPV6_DSCP (1ull << 37)
>
> #define MLX5_FLOW_FATE_ACTIONS \
> (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
> @@ -232,7 +234,9 @@ enum mlx5_feature_name {
> MLX5_FLOW_ACTION_OF_SET_VLAN_VID
> | \
> MLX5_FLOW_ACTION_SET_TAG | \
> MLX5_FLOW_ACTION_MARK_EXT | \
> - MLX5_FLOW_ACTION_SET_META)
> + MLX5_FLOW_ACTION_SET_META | \
> + MLX5_FLOW_ACTION_SET_IPV4_DSCP | \
> + MLX5_FLOW_ACTION_SET_IPV6_DSCP)
I don't think DSCP set is a reg feature... please check...
> #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 4c16281..15fe726 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -157,6 +157,7 @@ struct field_modify_info modify_vlan_out_first_vid[]
> = { };
>
> struct field_modify_info modify_ipv4[] = {
> + {1, 1, MLX5_MODI_OUT_IP_DSCP},
> {1, 8, MLX5_MODI_OUT_IPV4_TTL},
> {4, 12, MLX5_MODI_OUT_SIPV4},
> {4, 16, MLX5_MODI_OUT_DIPV4},
> @@ -164,6 +165,7 @@ struct field_modify_info modify_ipv4[] = { };
>
> struct field_modify_info modify_ipv6[] = {
> + {1, 0, MLX5_MODI_OUT_IP_DSCP},
> {1, 7, MLX5_MODI_OUT_IPV6_HOPLIMIT},
> {4, 8, MLX5_MODI_OUT_SIPV6_127_96},
> {4, 12, MLX5_MODI_OUT_SIPV6_95_64},
> @@ -1191,6 +1193,82 @@ struct field_modify_info modify_tcp[] = { }
>
> /**
> + * Convert modify-header set IPv4 DSCP 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_ipv4_dscp
> + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_dscp *conf =
> + (const struct rte_flow_action_set_dscp *)(action->conf);
> + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV4 };
> + struct rte_flow_item_ipv4 ipv4;
> + struct rte_flow_item_ipv4 ipv4_mask;
> +
> + memset(&ipv4, 0, sizeof(ipv4));
> + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> + ipv4.hdr.type_of_service = conf->dscp;
> + ipv4_mask.hdr.type_of_service = 0x3f;
Please use RTE_IPV4_HDR_DSCP_MASK.
> + item.spec = &ipv4;
> + item.mask = &ipv4_mask;
> + return flow_dv_convert_modify_action(&item, modify_ipv4, NULL,
> resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> + * Convert modify-header set IPv6 DSCP 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_ipv6_dscp
> + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_dscp *conf =
> + (const struct rte_flow_action_set_dscp *)(action->conf);
> + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV6 };
> + struct rte_flow_item_ipv6 ipv6;
> + struct rte_flow_item_ipv6 ipv6_mask;
> +
> + memset(&ipv6, 0, sizeof(ipv6));
> + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> + /*
> + * Even though the DSCP bits offset of IPv6 is not byte aligned,
> + * rdma-core only accept the DSCP bits byte aligned start from
> + * bit 0 to 5 as to be compatible with IPv4. No need to shift the
> + * bits in IPv6 case as rdma-core requires byte aligned value.
> + */
> + ipv6.hdr.vtc_flow = conf->dscp;
> + ipv6_mask.hdr.vtc_flow = 0x3f;
Please use RTE_IPV6_HDR_DSCP_MASK.
> + item.spec = &ipv6;
> + item.mask = &ipv6_mask;
> + return flow_dv_convert_modify_action(&item, modify_ipv6, NULL,
> resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> * Validate MARK item.
> *
> * @param[in] dev
> @@ -3433,6 +3511,74 @@ struct field_modify_info modify_tcp[] = { }
>
> /**
> + * Validate the modify-header IPv4 DSCP 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_ipv4_dscp(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV4))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no ipv4 item in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> + * Validate the modify-header IPv6 DSCP 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_ipv6_dscp(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV6))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no ipv6 item in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> * Find existing modify-header resource or create and register a new one.
> *
> * @param dev[in, out]
> @@ -4806,6 +4952,32 @@ struct field_modify_info modify_tcp[] = {
> action_flags |= MLX5_FLOW_ACTION_METER;
> ++actions_n;
> break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
> + ret = flow_dv_validate_action_modify_ipv4_dscp
> + (action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV4_DSCP;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
> + ret = flow_dv_validate_action_modify_ipv6_dscp
> + (action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV6_DSCP;
> + break;
> default:
> return rte_flow_error_set(error, ENOTSUP,
>
> RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -7101,6 +7273,18 @@ struct field_modify_info modify_tcp[] = {
> flow->meter->mfts->meter_action;
> action_flags |= MLX5_FLOW_ACTION_METER;
> break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
> + if
> (flow_dv_convert_action_modify_ipv4_dscp(&mhdr_res,
> + actions, error))
> + return -rte_errno;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV4_DSCP;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
> + if
> (flow_dv_convert_action_modify_ipv6_dscp(&mhdr_res,
> + actions, error))
> + return -rte_errno;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV6_DSCP;
> + break;
> case RTE_FLOW_ACTION_TYPE_END:
> actions_end = true;
> if (mhdr_res.actions_num) {
> --
> 1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [dpdk-dev] [PATCH 2/2] net/mlx5: add IPv4/IPv6 DSCP rewrite action
2020-01-06 14:36 ` Matan Azrad
@ 2020-01-07 6:33 ` Suanming Mou
0 siblings, 0 replies; 10+ messages in thread
From: Suanming Mou @ 2020-01-07 6:33 UTC (permalink / raw)
To: Matan Azrad, Shahaf Shuler, Slava Ovsiienko
Cc: dev, Ori Kam, arybchenko, ferruh.yigit, Thomas Monjalon
Hi
> -----Original Message-----
> From: Matan Azrad <matan@mellanox.com>
> Sent: Monday, January 6, 2020 10:37 PM
> To: Suanming Mou <suanmingm@mellanox.com>; Shahaf Shuler
> <shahafs@mellanox.com>; Slava Ovsiienko <viacheslavo@mellanox.com>
> Cc: dev@dpdk.org; Ori Kam <orika@mellanox.com>;
> arybchenko@solarflare.com; ferruh.yigit@intel.com; Thomas Monjalon
> <thomas@monjalon.net>
> Subject: RE: [PATCH 2/2] net/mlx5: add IPv4/IPv6 DSCP rewrite action
>
> Hi
>
> From: Suanming Mou
> > This commit add the IPv4/IPv6 DSCP rewrite actions to the PMD code.
> >
> > Supported actions:
> > RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
> > RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
> >
> > Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
> > ---
> > drivers/net/mlx5/mlx5_flow.h | 6 +-
> > drivers/net/mlx5/mlx5_flow_dv.c | 184
> > ++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 189 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/mlx5/mlx5_flow.h
> > b/drivers/net/mlx5/mlx5_flow.h index 27d82ac..e42c98a 100644
> > --- a/drivers/net/mlx5/mlx5_flow.h
> > +++ b/drivers/net/mlx5/mlx5_flow.h
> > @@ -196,6 +196,8 @@ enum mlx5_feature_name { #define
> > MLX5_FLOW_ACTION_MARK_EXT (1ull << 33) #define
> > MLX5_FLOW_ACTION_SET_META (1ull << 34) #define
> MLX5_FLOW_ACTION_METER
> > (1ull << 35)
> > +#define MLX5_FLOW_ACTION_SET_IPV4_DSCP (1ull << 36) #define
> > +MLX5_FLOW_ACTION_SET_IPV6_DSCP (1ull << 37)
> >
> > #define MLX5_FLOW_FATE_ACTIONS \
> > (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \ @@ -
> 232,7 +234,9
> > @@ enum mlx5_feature_name {
> > MLX5_FLOW_ACTION_OF_SET_VLAN_VID
> > | \
> > MLX5_FLOW_ACTION_SET_TAG | \
> > MLX5_FLOW_ACTION_MARK_EXT | \
> > - MLX5_FLOW_ACTION_SET_META)
> > + MLX5_FLOW_ACTION_SET_META | \
> > + MLX5_FLOW_ACTION_SET_IPV4_DSCP | \
> > + MLX5_FLOW_ACTION_SET_IPV6_DSCP)
>
> I don't think DSCP set is a reg feature... please check...
It does not belong to the mlx5_feature_name, it belongs to the MLX5_FLOW_MODIFY_HDR_ACTIONS macro.
I don't know why git put the feature_name here. : (
>
> > #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 4c16281..15fe726 100644
> > --- a/drivers/net/mlx5/mlx5_flow_dv.c
> > +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> > @@ -157,6 +157,7 @@ struct field_modify_info
> > modify_vlan_out_first_vid[] = { };
> >
> > struct field_modify_info modify_ipv4[] = {
> > + {1, 1, MLX5_MODI_OUT_IP_DSCP},
> > {1, 8, MLX5_MODI_OUT_IPV4_TTL},
> > {4, 12, MLX5_MODI_OUT_SIPV4},
> > {4, 16, MLX5_MODI_OUT_DIPV4},
> > @@ -164,6 +165,7 @@ struct field_modify_info modify_ipv4[] = { };
> >
> > struct field_modify_info modify_ipv6[] = {
> > + {1, 0, MLX5_MODI_OUT_IP_DSCP},
> > {1, 7, MLX5_MODI_OUT_IPV6_HOPLIMIT},
> > {4, 8, MLX5_MODI_OUT_SIPV6_127_96},
> > {4, 12, MLX5_MODI_OUT_SIPV6_95_64},
> > @@ -1191,6 +1193,82 @@ struct field_modify_info modify_tcp[] = { }
> >
> > /**
> > + * Convert modify-header set IPv4 DSCP 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_ipv4_dscp
> > + (struct mlx5_flow_dv_modify_hdr_resource
> > *resource,
> > + const struct rte_flow_action *action,
> > + struct rte_flow_error *error)
> > +{
> > + const struct rte_flow_action_set_dscp *conf =
> > + (const struct rte_flow_action_set_dscp *)(action->conf);
> > + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV4 };
> > + struct rte_flow_item_ipv4 ipv4;
> > + struct rte_flow_item_ipv4 ipv4_mask;
> > +
> > + memset(&ipv4, 0, sizeof(ipv4));
> > + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> > + ipv4.hdr.type_of_service = conf->dscp;
> > + ipv4_mask.hdr.type_of_service = 0x3f;
>
> Please use RTE_IPV4_HDR_DSCP_MASK.
OK.
>
> > + item.spec = &ipv4;
> > + item.mask = &ipv4_mask;
> > + return flow_dv_convert_modify_action(&item, modify_ipv4, NULL,
> > resource,
> > + MLX5_MODIFICATION_TYPE_SET,
> > error); }
> > +
> > +/**
> > + * Convert modify-header set IPv6 DSCP 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_ipv6_dscp
> > + (struct mlx5_flow_dv_modify_hdr_resource
> > *resource,
> > + const struct rte_flow_action *action,
> > + struct rte_flow_error *error)
> > +{
> > + const struct rte_flow_action_set_dscp *conf =
> > + (const struct rte_flow_action_set_dscp *)(action->conf);
> > + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV6 };
> > + struct rte_flow_item_ipv6 ipv6;
> > + struct rte_flow_item_ipv6 ipv6_mask;
> > +
> > + memset(&ipv6, 0, sizeof(ipv6));
> > + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> > + /*
> > + * Even though the DSCP bits offset of IPv6 is not byte aligned,
> > + * rdma-core only accept the DSCP bits byte aligned start from
> > + * bit 0 to 5 as to be compatible with IPv4. No need to shift the
> > + * bits in IPv6 case as rdma-core requires byte aligned value.
> > + */
> > + ipv6.hdr.vtc_flow = conf->dscp;
> > + ipv6_mask.hdr.vtc_flow = 0x3f;
>
> Please use RTE_IPV6_HDR_DSCP_MASK.
OK.
>
> > + item.spec = &ipv6;
> > + item.mask = &ipv6_mask;
> > + return flow_dv_convert_modify_action(&item, modify_ipv6, NULL,
> > resource,
> > + MLX5_MODIFICATION_TYPE_SET,
> > error); }
> > +
> > +/**
> > * Validate MARK item.
> > *
> > * @param[in] dev
> > @@ -3433,6 +3511,74 @@ struct field_modify_info modify_tcp[] = { }
> >
> > /**
> > + * Validate the modify-header IPv4 DSCP 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_ipv4_dscp(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + const uint64_t item_flags,
> > + struct rte_flow_error *error)
> > +{
> > + int ret = 0;
> > +
> > + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> > error);
> > + if (!ret) {
> > + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV4))
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "no ipv4 item in pattern");
> > + }
> > + return ret;
> > +}
> > +
> > +/**
> > + * Validate the modify-header IPv6 DSCP 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_ipv6_dscp(const uint64_t action_flags,
> > + const struct rte_flow_action *action,
> > + const uint64_t item_flags,
> > + struct rte_flow_error *error)
> > +{
> > + int ret = 0;
> > +
> > + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> > error);
> > + if (!ret) {
> > + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV6))
> > + return rte_flow_error_set(error, EINVAL,
> > +
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > + NULL,
> > + "no ipv6 item in pattern");
> > + }
> > + return ret;
> > +}
> > +
> > +/**
> > * Find existing modify-header resource or create and register a new one.
> > *
> > * @param dev[in, out]
> > @@ -4806,6 +4952,32 @@ struct field_modify_info modify_tcp[] = {
> > action_flags |= MLX5_FLOW_ACTION_METER;
> > ++actions_n;
> > break;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
> > + ret = flow_dv_validate_action_modify_ipv4_dscp
> > + (action_flags,
> > + actions,
> > + item_flags,
> > + error);
> > + if (ret < 0)
> > + return ret;
> > + /* Count all modify-header actions as one action. */
> > + if (!(action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS))
> > + ++actions_n;
> > + action_flags |=
> > MLX5_FLOW_ACTION_SET_IPV4_DSCP;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
> > + ret = flow_dv_validate_action_modify_ipv6_dscp
> > + (action_flags,
> > + actions,
> > + item_flags,
> > + error);
> > + if (ret < 0)
> > + return ret;
> > + /* Count all modify-header actions as one action. */
> > + if (!(action_flags &
> > MLX5_FLOW_MODIFY_HDR_ACTIONS))
> > + ++actions_n;
> > + action_flags |=
> > MLX5_FLOW_ACTION_SET_IPV6_DSCP;
> > + break;
> > default:
> > return rte_flow_error_set(error, ENOTSUP,
> >
> > RTE_FLOW_ERROR_TYPE_ACTION,
> > @@ -7101,6 +7273,18 @@ struct field_modify_info modify_tcp[] = {
> > flow->meter->mfts->meter_action;
> > action_flags |= MLX5_FLOW_ACTION_METER;
> > break;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
> > + if
> > (flow_dv_convert_action_modify_ipv4_dscp(&mhdr_res,
> > + actions, error))
> > + return -rte_errno;
> > + action_flags |=
> > MLX5_FLOW_ACTION_SET_IPV4_DSCP;
> > + break;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
> > + if
> > (flow_dv_convert_action_modify_ipv6_dscp(&mhdr_res,
> > + actions, error))
> > + return -rte_errno;
> > + action_flags |=
> > MLX5_FLOW_ACTION_SET_IPV6_DSCP;
> > + break;
> > case RTE_FLOW_ACTION_TYPE_END:
> > actions_end = true;
> > if (mhdr_res.actions_num) {
> > --
> > 1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [dpdk-dev] [PATCH v2 0/2] add IPv4/IPv6 DSCP rewrite action
2020-01-02 6:04 [dpdk-dev] [PATCH 0/2] add IPv4/IPv6 DSCP rewrite action Suanming Mou
2020-01-02 6:04 ` [dpdk-dev] [PATCH 1/2] ethdev: " Suanming Mou
2020-01-02 6:04 ` [dpdk-dev] [PATCH 2/2] net/mlx5: " Suanming Mou
@ 2020-01-07 7:24 ` Suanming Mou
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 1/2] ethdev: " Suanming Mou
` (2 more replies)
2 siblings, 3 replies; 10+ messages in thread
From: Suanming Mou @ 2020-01-07 7:24 UTC (permalink / raw)
Cc: dev, rasland
For some overlay network, such as VXLAN, the DSCP field in the new outer
IP header after VXLAN decapsulation may need to be updated accordingly.
This patchset implements the DSCP rewrite action for IPv4 and IPv6 as RFC[1].
[1] https://inbox.dpdk.org/dev/1575955386-6672-1-git-send-email-suanmingm@mellanox.com/
---
v2: change the magic number 0x3f to RTE_IPV4/6_HDR_DSCP_MASK macro in PMD.
Suanming Mou (2):
ethdev: add IPv4/IPv6 DSCP rewrite action
net/mlx5: add IPv4/IPv6 DSCP rewrite action
app/test-pmd/cmdline_flow.c | 50 ++++++++
doc/guides/prog_guide/rte_flow.rst | 40 ++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 ++
drivers/net/mlx5/mlx5_flow.h | 6 +-
drivers/net/mlx5/mlx5_flow_dv.c | 184 ++++++++++++++++++++++++++++
lib/librte_ethdev/rte_flow.c | 2 +
lib/librte_ethdev/rte_flow.h | 31 +++++
7 files changed, 320 insertions(+), 1 deletion(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [dpdk-dev] [PATCH v2 1/2] ethdev: add IPv4/IPv6 DSCP rewrite action
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 0/2] " Suanming Mou
@ 2020-01-07 7:24 ` Suanming Mou
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: " Suanming Mou
2020-01-10 18:55 ` [dpdk-dev] [PATCH v2 0/2] " Ferruh Yigit
2 siblings, 0 replies; 10+ messages in thread
From: Suanming Mou @ 2020-01-07 7:24 UTC (permalink / raw)
To: Adrien Mazarguil, Wenzhuo Lu, Jingjing Wu, Bernard Iremonger,
John McNamara, Marko Kovacevic, Thomas Monjalon, Ferruh Yigit,
Andrew Rybchenko
Cc: dev, rasland
For some overlay network, such as VXLAN, the DSCP field in the new outer
IP header after VXLAN decapsulation may need to be updated accordingly.
This commit introduce the DSCP modify action for IPv4 and IPv6.
Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Ori Kam <orika@mellanox.com>
---
app/test-pmd/cmdline_flow.c | 50 +++++++++++++++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 40 +++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 +++++
lib/librte_ethdev/rte_flow.c | 2 ++
lib/librte_ethdev/rte_flow.h | 31 ++++++++++++++++++
5 files changed, 131 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 99dade7..77a6141 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -326,6 +326,10 @@ enum index {
ACTION_SET_META,
ACTION_SET_META_DATA,
ACTION_SET_META_MASK,
+ ACTION_SET_IPV4_DSCP,
+ ACTION_SET_IPV4_DSCP_VALUE,
+ ACTION_SET_IPV6_DSCP,
+ ACTION_SET_IPV6_DSCP_VALUE,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1087,6 +1091,8 @@ struct parse_action_priv {
ACTION_RAW_DECAP,
ACTION_SET_TAG,
ACTION_SET_META,
+ ACTION_SET_IPV4_DSCP,
+ ACTION_SET_IPV6_DSCP,
ZERO,
};
@@ -1300,6 +1306,18 @@ struct parse_action_priv {
ZERO,
};
+static const enum index action_set_ipv4_dscp[] = {
+ ACTION_SET_IPV4_DSCP_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_dscp[] = {
+ ACTION_SET_IPV6_DSCP_VALUE,
+ ACTION_NEXT,
+ ZERO,
+};
+
static int parse_set_raw_encap_decap(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -3493,6 +3511,38 @@ static int comp_set_raw_index(struct context *, const struct token *,
(struct rte_flow_action_set_meta, mask)),
.call = parse_vc_conf,
},
+ [ACTION_SET_IPV4_DSCP] = {
+ .name = "set_ipv4_dscp",
+ .help = "set DSCP value",
+ .priv = PRIV_ACTION(SET_IPV4_DSCP,
+ sizeof(struct rte_flow_action_set_dscp)),
+ .next = NEXT(action_set_ipv4_dscp),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_DSCP_VALUE] = {
+ .name = "dscp_value",
+ .help = "new IPv4 DSCP value to set",
+ .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY
+ (struct rte_flow_action_set_dscp, dscp)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_DSCP] = {
+ .name = "set_ipv6_dscp",
+ .help = "set DSCP value",
+ .priv = PRIV_ACTION(SET_IPV6_DSCP,
+ sizeof(struct rte_flow_action_set_dscp)),
+ .next = NEXT(action_set_ipv6_dscp),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_DSCP_VALUE] = {
+ .name = "dscp_value",
+ .help = "new IPv6 DSCP value to set",
+ .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY
+ (struct rte_flow_action_set_dscp, dscp)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index a254c81..2f21309 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2558,6 +2558,46 @@ the other path depending on HW capability.
| ``mask`` | bit-mask applies to "data" |
+----------+----------------------------+
+Action: ``SET_IPV4_DSCP``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set IPv4 DSCP.
+
+Modify DSCP in IPv4 header.
+
+It must be used with RTE_FLOW_ITEM_TYPE_IPV4 in pattern.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_dscp:
+
+.. table:: SET_IPV4_DSCP
+
+ +-----------+---------------------------------+
+ | Field | Value |
+ +===========+=================================+
+ | ``dscp`` | DSCP in low 6 bits, rest ignore |
+ +-----------+---------------------------------+
+
+Action: ``SET_IPV6_DSCP``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set IPv6 DSCP.
+
+Modify DSCP in IPv6 header.
+
+It must be used with RTE_FLOW_ITEM_TYPE_IPV6 in pattern.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_dscp:
+
+.. table:: SET_IPV6_DSCP
+
+ +-----------+---------------------------------+
+ | Field | Value |
+ +===========+=================================+
+ | ``dscp`` | DSCP in low 6 bits, rest ignore |
+ +-----------+---------------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 10aabf5..3baaacb 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -4228,6 +4228,14 @@ This section lists supported actions and their attributes, if any.
- ``value {unsigned}``: Value to decrease TCP acknowledgment number by.
+- ``set_ipv4_dscp``: Set IPv4 DSCP value with specified value
+
+ - ``dscp_value {unsigned}``: The new DSCP value to be set
+
+- ``set_ipv6_dscp``: Set IPv6 DSCP value with specified value
+
+ - ``dscp_value {unsigned}``: The new DSCP value to be set
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 87a3e8c..b86aee3 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -168,6 +168,8 @@ struct rte_flow_desc_data {
MK_FLOW_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)),
MK_FLOW_ACTION(SET_TAG, sizeof(struct rte_flow_action_set_tag)),
MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
+ MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
+ MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
};
int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index 58b5026..16d849e 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -2004,6 +2004,26 @@ enum rte_flow_action_type {
* See struct rte_flow_action_set_meta.
*/
RTE_FLOW_ACTION_TYPE_SET_META,
+
+ /**
+ * Modify IPv4 DSCP in the outermost IP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV4,
+ * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_dscp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP,
+
+ /**
+ * Modify IPv6 DSCP in the outermost IP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_IPV6,
+ * then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_dscp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP,
};
/**
@@ -2530,6 +2550,17 @@ struct rte_flow_action_set_meta {
uint32_t mask;
};
+/**
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+ *
+ * Set the DSCP value for IPv4/IPv6 header.
+ * DSCP in low 6 bits, rest ignored.
+ */
+struct rte_flow_action_set_dscp {
+ uint8_t dscp;
+};
+
/* Mbuf dynamic field offset for metadata. */
extern int rte_flow_dynf_metadata_offs;
--
1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [dpdk-dev] [PATCH v2 2/2] net/mlx5: add IPv4/IPv6 DSCP rewrite action
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 0/2] " Suanming Mou
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 1/2] ethdev: " Suanming Mou
@ 2020-01-07 7:24 ` Suanming Mou
2020-01-07 7:26 ` Matan Azrad
2020-01-10 18:55 ` [dpdk-dev] [PATCH v2 0/2] " Ferruh Yigit
2 siblings, 1 reply; 10+ messages in thread
From: Suanming Mou @ 2020-01-07 7:24 UTC (permalink / raw)
To: Matan Azrad, Shahaf Shuler, Viacheslav Ovsiienko; +Cc: dev, rasland
This commit add the IPv4/IPv6 DSCP rewrite actions to the PMD code.
Supported actions:
RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
---
drivers/net/mlx5/mlx5_flow.h | 6 +-
drivers/net/mlx5/mlx5_flow_dv.c | 184 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 189 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 27d82ac..e42c98a 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -196,6 +196,8 @@ enum mlx5_feature_name {
#define MLX5_FLOW_ACTION_MARK_EXT (1ull << 33)
#define MLX5_FLOW_ACTION_SET_META (1ull << 34)
#define MLX5_FLOW_ACTION_METER (1ull << 35)
+#define MLX5_FLOW_ACTION_SET_IPV4_DSCP (1ull << 36)
+#define MLX5_FLOW_ACTION_SET_IPV6_DSCP (1ull << 37)
#define MLX5_FLOW_FATE_ACTIONS \
(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
@@ -232,7 +234,9 @@ enum mlx5_feature_name {
MLX5_FLOW_ACTION_OF_SET_VLAN_VID | \
MLX5_FLOW_ACTION_SET_TAG | \
MLX5_FLOW_ACTION_MARK_EXT | \
- MLX5_FLOW_ACTION_SET_META)
+ MLX5_FLOW_ACTION_SET_META | \
+ MLX5_FLOW_ACTION_SET_IPV4_DSCP | \
+ MLX5_FLOW_ACTION_SET_IPV6_DSCP)
#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 4c16281..685fceb 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -157,6 +157,7 @@ struct field_modify_info modify_vlan_out_first_vid[] = {
};
struct field_modify_info modify_ipv4[] = {
+ {1, 1, MLX5_MODI_OUT_IP_DSCP},
{1, 8, MLX5_MODI_OUT_IPV4_TTL},
{4, 12, MLX5_MODI_OUT_SIPV4},
{4, 16, MLX5_MODI_OUT_DIPV4},
@@ -164,6 +165,7 @@ struct field_modify_info modify_ipv4[] = {
};
struct field_modify_info modify_ipv6[] = {
+ {1, 0, MLX5_MODI_OUT_IP_DSCP},
{1, 7, MLX5_MODI_OUT_IPV6_HOPLIMIT},
{4, 8, MLX5_MODI_OUT_SIPV6_127_96},
{4, 12, MLX5_MODI_OUT_SIPV6_95_64},
@@ -1191,6 +1193,82 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Convert modify-header set IPv4 DSCP 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_ipv4_dscp
+ (struct mlx5_flow_dv_modify_hdr_resource *resource,
+ const struct rte_flow_action *action,
+ struct rte_flow_error *error)
+{
+ const struct rte_flow_action_set_dscp *conf =
+ (const struct rte_flow_action_set_dscp *)(action->conf);
+ struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV4 };
+ struct rte_flow_item_ipv4 ipv4;
+ struct rte_flow_item_ipv4 ipv4_mask;
+
+ memset(&ipv4, 0, sizeof(ipv4));
+ memset(&ipv4_mask, 0, sizeof(ipv4_mask));
+ ipv4.hdr.type_of_service = conf->dscp;
+ ipv4_mask.hdr.type_of_service = RTE_IPV4_HDR_DSCP_MASK >> 2;
+ item.spec = &ipv4;
+ item.mask = &ipv4_mask;
+ return flow_dv_convert_modify_action(&item, modify_ipv4, NULL, resource,
+ MLX5_MODIFICATION_TYPE_SET, error);
+}
+
+/**
+ * Convert modify-header set IPv6 DSCP 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_ipv6_dscp
+ (struct mlx5_flow_dv_modify_hdr_resource *resource,
+ const struct rte_flow_action *action,
+ struct rte_flow_error *error)
+{
+ const struct rte_flow_action_set_dscp *conf =
+ (const struct rte_flow_action_set_dscp *)(action->conf);
+ struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV6 };
+ struct rte_flow_item_ipv6 ipv6;
+ struct rte_flow_item_ipv6 ipv6_mask;
+
+ memset(&ipv6, 0, sizeof(ipv6));
+ memset(&ipv6_mask, 0, sizeof(ipv6_mask));
+ /*
+ * Even though the DSCP bits offset of IPv6 is not byte aligned,
+ * rdma-core only accept the DSCP bits byte aligned start from
+ * bit 0 to 5 as to be compatible with IPv4. No need to shift the
+ * bits in IPv6 case as rdma-core requires byte aligned value.
+ */
+ ipv6.hdr.vtc_flow = conf->dscp;
+ ipv6_mask.hdr.vtc_flow = RTE_IPV6_HDR_DSCP_MASK >> 22;
+ item.spec = &ipv6;
+ item.mask = &ipv6_mask;
+ return flow_dv_convert_modify_action(&item, modify_ipv6, NULL, resource,
+ MLX5_MODIFICATION_TYPE_SET, error);
+}
+
+/**
* Validate MARK item.
*
* @param[in] dev
@@ -3433,6 +3511,74 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Validate the modify-header IPv4 DSCP 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_ipv4_dscp(const uint64_t action_flags,
+ const struct rte_flow_action *action,
+ const uint64_t item_flags,
+ struct rte_flow_error *error)
+{
+ int ret = 0;
+
+ ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
+ if (!ret) {
+ if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV4))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "no ipv4 item in pattern");
+ }
+ return ret;
+}
+
+/**
+ * Validate the modify-header IPv6 DSCP 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_ipv6_dscp(const uint64_t action_flags,
+ const struct rte_flow_action *action,
+ const uint64_t item_flags,
+ struct rte_flow_error *error)
+{
+ int ret = 0;
+
+ ret = flow_dv_validate_action_modify_hdr(action_flags, action, error);
+ if (!ret) {
+ if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV6))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL,
+ "no ipv6 item in pattern");
+ }
+ return ret;
+}
+
+/**
* Find existing modify-header resource or create and register a new one.
*
* @param dev[in, out]
@@ -4806,6 +4952,32 @@ struct field_modify_info modify_tcp[] = {
action_flags |= MLX5_FLOW_ACTION_METER;
++actions_n;
break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+ ret = flow_dv_validate_action_modify_ipv4_dscp
+ (action_flags,
+ actions,
+ item_flags,
+ error);
+ if (ret < 0)
+ return ret;
+ /* Count all modify-header actions as one action. */
+ if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
+ ++actions_n;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV4_DSCP;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+ ret = flow_dv_validate_action_modify_ipv6_dscp
+ (action_flags,
+ actions,
+ item_flags,
+ error);
+ if (ret < 0)
+ return ret;
+ /* Count all modify-header actions as one action. */
+ if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
+ ++actions_n;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV6_DSCP;
+ break;
default:
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION,
@@ -7101,6 +7273,18 @@ struct field_modify_info modify_tcp[] = {
flow->meter->mfts->meter_action;
action_flags |= MLX5_FLOW_ACTION_METER;
break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
+ if (flow_dv_convert_action_modify_ipv4_dscp(&mhdr_res,
+ actions, error))
+ return -rte_errno;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV4_DSCP;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
+ if (flow_dv_convert_action_modify_ipv6_dscp(&mhdr_res,
+ actions, error))
+ return -rte_errno;
+ action_flags |= MLX5_FLOW_ACTION_SET_IPV6_DSCP;
+ break;
case RTE_FLOW_ACTION_TYPE_END:
actions_end = true;
if (mhdr_res.actions_num) {
--
1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [dpdk-dev] [PATCH v2 2/2] net/mlx5: add IPv4/IPv6 DSCP rewrite action
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: " Suanming Mou
@ 2020-01-07 7:26 ` Matan Azrad
0 siblings, 0 replies; 10+ messages in thread
From: Matan Azrad @ 2020-01-07 7:26 UTC (permalink / raw)
To: Suanming Mou, Shahaf Shuler, Slava Ovsiienko; +Cc: dev, Raslan Darawsheh
From: Suanming Mou
> This commit add the IPv4/IPv6 DSCP rewrite actions to the PMD code.
>
> Supported actions:
> RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
> RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
>
> Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
Acked-by: Matan Azrad <matan@mellanox.com>
> ---
> drivers/net/mlx5/mlx5_flow.h | 6 +-
> drivers/net/mlx5/mlx5_flow_dv.c | 184
> ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 189 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
> index 27d82ac..e42c98a 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -196,6 +196,8 @@ enum mlx5_feature_name { #define
> MLX5_FLOW_ACTION_MARK_EXT (1ull << 33) #define
> MLX5_FLOW_ACTION_SET_META (1ull << 34) #define
> MLX5_FLOW_ACTION_METER (1ull << 35)
> +#define MLX5_FLOW_ACTION_SET_IPV4_DSCP (1ull << 36) #define
> +MLX5_FLOW_ACTION_SET_IPV6_DSCP (1ull << 37)
>
> #define MLX5_FLOW_FATE_ACTIONS \
> (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
> @@ -232,7 +234,9 @@ enum mlx5_feature_name {
> MLX5_FLOW_ACTION_OF_SET_VLAN_VID
> | \
> MLX5_FLOW_ACTION_SET_TAG | \
> MLX5_FLOW_ACTION_MARK_EXT | \
> - MLX5_FLOW_ACTION_SET_META)
> + MLX5_FLOW_ACTION_SET_META | \
> + MLX5_FLOW_ACTION_SET_IPV4_DSCP | \
> + MLX5_FLOW_ACTION_SET_IPV6_DSCP)
>
> #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 4c16281..685fceb 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -157,6 +157,7 @@ struct field_modify_info modify_vlan_out_first_vid[]
> = { };
>
> struct field_modify_info modify_ipv4[] = {
> + {1, 1, MLX5_MODI_OUT_IP_DSCP},
> {1, 8, MLX5_MODI_OUT_IPV4_TTL},
> {4, 12, MLX5_MODI_OUT_SIPV4},
> {4, 16, MLX5_MODI_OUT_DIPV4},
> @@ -164,6 +165,7 @@ struct field_modify_info modify_ipv4[] = { };
>
> struct field_modify_info modify_ipv6[] = {
> + {1, 0, MLX5_MODI_OUT_IP_DSCP},
> {1, 7, MLX5_MODI_OUT_IPV6_HOPLIMIT},
> {4, 8, MLX5_MODI_OUT_SIPV6_127_96},
> {4, 12, MLX5_MODI_OUT_SIPV6_95_64},
> @@ -1191,6 +1193,82 @@ struct field_modify_info modify_tcp[] = { }
>
> /**
> + * Convert modify-header set IPv4 DSCP 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_ipv4_dscp
> + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_dscp *conf =
> + (const struct rte_flow_action_set_dscp *)(action->conf);
> + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV4 };
> + struct rte_flow_item_ipv4 ipv4;
> + struct rte_flow_item_ipv4 ipv4_mask;
> +
> + memset(&ipv4, 0, sizeof(ipv4));
> + memset(&ipv4_mask, 0, sizeof(ipv4_mask));
> + ipv4.hdr.type_of_service = conf->dscp;
> + ipv4_mask.hdr.type_of_service = RTE_IPV4_HDR_DSCP_MASK >> 2;
> + item.spec = &ipv4;
> + item.mask = &ipv4_mask;
> + return flow_dv_convert_modify_action(&item, modify_ipv4, NULL,
> resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> + * Convert modify-header set IPv6 DSCP 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_ipv6_dscp
> + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct rte_flow_action_set_dscp *conf =
> + (const struct rte_flow_action_set_dscp *)(action->conf);
> + struct rte_flow_item item = { .type = RTE_FLOW_ITEM_TYPE_IPV6 };
> + struct rte_flow_item_ipv6 ipv6;
> + struct rte_flow_item_ipv6 ipv6_mask;
> +
> + memset(&ipv6, 0, sizeof(ipv6));
> + memset(&ipv6_mask, 0, sizeof(ipv6_mask));
> + /*
> + * Even though the DSCP bits offset of IPv6 is not byte aligned,
> + * rdma-core only accept the DSCP bits byte aligned start from
> + * bit 0 to 5 as to be compatible with IPv4. No need to shift the
> + * bits in IPv6 case as rdma-core requires byte aligned value.
> + */
> + ipv6.hdr.vtc_flow = conf->dscp;
> + ipv6_mask.hdr.vtc_flow = RTE_IPV6_HDR_DSCP_MASK >> 22;
> + item.spec = &ipv6;
> + item.mask = &ipv6_mask;
> + return flow_dv_convert_modify_action(&item, modify_ipv6, NULL,
> resource,
> + MLX5_MODIFICATION_TYPE_SET,
> error); }
> +
> +/**
> * Validate MARK item.
> *
> * @param[in] dev
> @@ -3433,6 +3511,74 @@ struct field_modify_info modify_tcp[] = { }
>
> /**
> + * Validate the modify-header IPv4 DSCP 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_ipv4_dscp(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV4))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no ipv4 item in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> + * Validate the modify-header IPv6 DSCP 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_ipv6_dscp(const uint64_t action_flags,
> + const struct rte_flow_action *action,
> + const uint64_t item_flags,
> + struct rte_flow_error *error)
> +{
> + int ret = 0;
> +
> + ret = flow_dv_validate_action_modify_hdr(action_flags, action,
> error);
> + if (!ret) {
> + if (!(item_flags & MLX5_FLOW_LAYER_L3_IPV6))
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ACTION,
> + NULL,
> + "no ipv6 item in pattern");
> + }
> + return ret;
> +}
> +
> +/**
> * Find existing modify-header resource or create and register a new one.
> *
> * @param dev[in, out]
> @@ -4806,6 +4952,32 @@ struct field_modify_info modify_tcp[] = {
> action_flags |= MLX5_FLOW_ACTION_METER;
> ++actions_n;
> break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
> + ret = flow_dv_validate_action_modify_ipv4_dscp
> + (action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV4_DSCP;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
> + ret = flow_dv_validate_action_modify_ipv6_dscp
> + (action_flags,
> + actions,
> + item_flags,
> + error);
> + if (ret < 0)
> + return ret;
> + /* Count all modify-header actions as one action. */
> + if (!(action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS))
> + ++actions_n;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV6_DSCP;
> + break;
> default:
> return rte_flow_error_set(error, ENOTSUP,
>
> RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -7101,6 +7273,18 @@ struct field_modify_info modify_tcp[] = {
> flow->meter->mfts->meter_action;
> action_flags |= MLX5_FLOW_ACTION_METER;
> break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP:
> + if
> (flow_dv_convert_action_modify_ipv4_dscp(&mhdr_res,
> + actions, error))
> + return -rte_errno;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV4_DSCP;
> + break;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP:
> + if
> (flow_dv_convert_action_modify_ipv6_dscp(&mhdr_res,
> + actions, error))
> + return -rte_errno;
> + action_flags |=
> MLX5_FLOW_ACTION_SET_IPV6_DSCP;
> + break;
> case RTE_FLOW_ACTION_TYPE_END:
> actions_end = true;
> if (mhdr_res.actions_num) {
> --
> 1.8.3.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [dpdk-dev] [PATCH v2 0/2] add IPv4/IPv6 DSCP rewrite action
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 0/2] " Suanming Mou
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 1/2] ethdev: " Suanming Mou
2020-01-07 7:24 ` [dpdk-dev] [PATCH v2 2/2] net/mlx5: " Suanming Mou
@ 2020-01-10 18:55 ` Ferruh Yigit
2 siblings, 0 replies; 10+ messages in thread
From: Ferruh Yigit @ 2020-01-10 18:55 UTC (permalink / raw)
To: Suanming Mou; +Cc: dev, rasland
On 1/7/2020 7:24 AM, Suanming Mou wrote:
> For some overlay network, such as VXLAN, the DSCP field in the new outer
> IP header after VXLAN decapsulation may need to be updated accordingly.
>
> This patchset implements the DSCP rewrite action for IPv4 and IPv6 as RFC[1].
>
> [1] https://inbox.dpdk.org/dev/1575955386-6672-1-git-send-email-suanmingm@mellanox.com/
>
> ---
> v2: change the magic number 0x3f to RTE_IPV4/6_HDR_DSCP_MASK macro in PMD.
>
> Suanming Mou (2):
> ethdev: add IPv4/IPv6 DSCP rewrite action
> net/mlx5: add IPv4/IPv6 DSCP rewrite action
Series applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread