* [dpdk-dev] [PATCH 1/3] ethdev: add flow api actions to modify IP addresses
2018-09-24 8:28 [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
@ 2018-09-24 8:28 ` Rahul Lakkireddy
2018-09-25 3:03 ` Xiaoyu Min
2018-09-24 8:28 ` [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
` (3 subsequent siblings)
4 siblings, 1 reply; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-09-24 8:28 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Add actions:
- SET_IPV4_SRC - set a new IPv4 source address.
- SET_IPV4_DST - set a new IPv4 destination address.
- SET_IPV6_SRC - set a new IPv6 source address.
- SET_IPV6_DST - set a new IPv6 destination address.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
Changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
action.
- Updated release notes.
app/test-pmd/cmdline_flow.c | 104 ++++++++++++++++++++
app/test-pmd/config.c | 8 ++
doc/guides/prog_guide/rte_flow.rst | 72 ++++++++++++++
doc/guides/rel_notes/release_18_11.rst | 6 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 18 ++++
lib/librte_ethdev/rte_flow.c | 8 ++
lib/librte_ethdev/rte_flow.h | 70 +++++++++++++
7 files changed, 286 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f9260600e..1432498a3 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -243,6 +243,14 @@ enum index {
ACTION_VXLAN_DECAP,
ACTION_NVGRE_ENCAP,
ACTION_NVGRE_DECAP,
+ ACTION_SET_IPV4_SRC,
+ ACTION_SET_IPV4_SRC_IPV4_SRC,
+ ACTION_SET_IPV4_DST,
+ ACTION_SET_IPV4_DST_IPV4_DST,
+ ACTION_SET_IPV6_SRC,
+ ACTION_SET_IPV6_SRC_IPV6_SRC,
+ ACTION_SET_IPV6_DST,
+ ACTION_SET_IPV6_DST_IPV6_DST,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -816,6 +824,10 @@ static const enum index next_action[] = {
ACTION_VXLAN_DECAP,
ACTION_NVGRE_ENCAP,
ACTION_NVGRE_DECAP,
+ ACTION_SET_IPV4_SRC,
+ ACTION_SET_IPV4_DST,
+ ACTION_SET_IPV6_SRC,
+ ACTION_SET_IPV6_DST,
ZERO,
};
@@ -918,6 +930,30 @@ static const enum index action_of_push_mpls[] = {
ZERO,
};
+static const enum index action_set_ipv4_src[] = {
+ ACTION_SET_IPV4_SRC_IPV4_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv4_dst[] = {
+ ACTION_SET_IPV4_DST_IPV4_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_src[] = {
+ ACTION_SET_IPV6_SRC_IPV6_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_dst[] = {
+ ACTION_SET_IPV6_DST_IPV6_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_jump[] = {
ACTION_JUMP_GROUP,
ACTION_NEXT,
@@ -2470,6 +2506,74 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_SET_IPV4_SRC] = {
+ .name = "set_ipv4_src",
+ .help = "Set a new IPv4 source address in the outermost"
+ " IPv4 header",
+ .priv = PRIV_ACTION(SET_IPV4_SRC,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ .next = NEXT(action_set_ipv4_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_SRC_IPV4_SRC] = {
+ .name = "ipv4_addr",
+ .help = "new IPv4 source address to set",
+ .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(IPV4_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv4, ipv4_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV4_DST] = {
+ .name = "set_ipv4_dst",
+ .help = "Set a new IPv4 destination address in the outermost"
+ " IPv4 header",
+ .priv = PRIV_ACTION(SET_IPV4_DST,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ .next = NEXT(action_set_ipv4_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_DST_IPV4_DST] = {
+ .name = "ipv4_addr",
+ .help = "new IPv4 destination address to set",
+ .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(IPV4_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv4, ipv4_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_SRC] = {
+ .name = "set_ipv6_src",
+ .help = "Set a new IPv6 source address in the outermost"
+ " IPv6 header",
+ .priv = PRIV_ACTION(SET_IPV6_SRC,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ .next = NEXT(action_set_ipv6_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_SRC_IPV6_SRC] = {
+ .name = "ipv6_addr",
+ .help = "new IPv6 source address to set",
+ .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(IPV6_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv6, ipv6_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_DST] = {
+ .name = "set_ipv6_dst",
+ .help = "Set a new IPv6 destination address in the outermost"
+ " IPv6 header",
+ .priv = PRIV_ACTION(SET_IPV6_DST,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ .next = NEXT(action_set_ipv6_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_DST_IPV6_DST] = {
+ .name = "ipv6_addr",
+ .help = "new IPv6 destination address to set",
+ .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(IPV6_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv6, ipv6_addr)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 794aa5268..14dbdf7a3 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1172,6 +1172,14 @@ static const struct {
sizeof(struct rte_flow_action_of_pop_mpls)),
MK_FLOW_ACTION(OF_PUSH_MPLS,
sizeof(struct rte_flow_action_of_push_mpls)),
+ MK_FLOW_ACTION(SET_IPV4_SRC,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV4_DST,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV6_SRC,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_IPV6_DST,
+ sizeof(struct rte_flow_action_set_ipv6)),
};
/** Compute storage space needed by action configuration and copy it. */
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index b305a72a5..b9bcaa3d1 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2076,6 +2076,78 @@ RTE_FLOW_ERROR_TYPE_ACTION error should be returned.
This action modifies the payload of matched flows.
+Action: ``SET_IPV4_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv4 source address in the outermost IPv4 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_src:
+
+.. table:: SET_IPV4_SRC
+
+ +-----------------------------------------+
+ | Field | Value |
+ +===============+=========================+
+ | ``ipv4_addr`` | new IPv4 source address |
+ +---------------+-------------------------+
+
+Action: ``SET_IPV4_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv4 destination address in the outermost IPv4 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_dst:
+
+.. table:: SET_IPV4_DST
+
+ +---------------+------------------------------+
+ | Field | Value |
+ +===============+==============================+
+ | ``ipv4_addr`` | new IPv4 destination address |
+ +---------------+------------------------------+
+
+Action: ``SET_IPV6_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv6 source address in the outermost IPv6 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_src:
+
+.. table:: SET_IPV6_SRC
+
+ +---------------+-------------------------+
+ | Field | Value |
+ +===============+=========================+
+ | ``ipv6_addr`` | new IPv6 source address |
+ +---------------+-------------------------+
+
+Action: ``SET_IPV6_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv6 destination address in the outermost IPv6 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_dst:
+
+.. table:: SET_IPV6_DST
+
+ +---------------+------------------------------+
+ | Field | Value |
+ +===============+==============================+
+ | ``ipv6_addr`` | new IPv6 destination address |
+ +---------------+------------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index f39cb15d2..782722318 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -87,6 +87,12 @@ New Features
the specified port. The port must be stopped before the command call in order
to reconfigure queues.
+* **Added new Flow API actions to rewrite fields in packet headers.**
+
+ Added new Flow API actions to:
+
+ * Modify source and destination IP addresses in the outermost IPv4/IPv6
+ headers.
API Changes
-----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 3a73000a6..97d91f066 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3704,6 +3704,24 @@ This section lists supported actions and their attributes, if any.
- ``nvgre_decap``: Performs a decapsulation action by stripping all headers of
the NVGRE tunnel network overlay from the matched flow.
+- ``set_ipv4_src``: Set a new IPv4 source address in the outermost IPv4 header.
+
+ - ``ipv4_addr``: New IPv4 source address.
+
+- ``set_ipv4_dst``: Set a new IPv4 destination address in the outermost IPv4
+ header.
+
+ - ``ipv4_addr``: New IPv4 destination address.
+
+- ``set_ipv6_src``: Set a new IPv6 source address in the outermost IPv6 header.
+
+ - ``ipv6_addr``: New IPv6 source address.
+
+- ``set_ipv6_dst``: Set a new IPv6 destination address in the outermost IPv6
+ header.
+
+ - ``ipv6_addr``: New IPv6 destination address.
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index cff4b5209..d4f1b9a05 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -109,6 +109,14 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
sizeof(struct rte_flow_action_of_pop_mpls)),
MK_FLOW_ACTION(OF_PUSH_MPLS,
sizeof(struct rte_flow_action_of_push_mpls)),
+ MK_FLOW_ACTION(SET_IPV4_SRC,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV4_DST,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV6_SRC,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_IPV6_DST,
+ sizeof(struct rte_flow_action_set_ipv6)),
};
static int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index f8ba71cdb..0fe91ae89 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -1505,6 +1505,46 @@ enum rte_flow_action_type {
* error.
*/
RTE_FLOW_ACTION_TYPE_NVGRE_DECAP,
+
+ /**
+ * Modify IPv4 source address in the outermost IPv4 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_ipv4.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC,
+
+ /**
+ * Modify IPv4 destination address in the outermost IPv4 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_ipv4.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_DST,
+
+ /**
+ * Modify IPv6 source address in the outermost IPv6 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_ipv6.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC,
+
+ /**
+ * Modify IPv6 destination address in the outermost IPv6 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_ipv6.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
};
/**
@@ -1868,6 +1908,36 @@ struct rte_flow_action_nvgre_encap {
struct rte_flow_item *definition;
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+ *
+ * Allows modification of IPv4 source (RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC)
+ * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV4_DST) in the
+ * specified outermost IPv4 header.
+ */
+struct rte_flow_action_set_ipv4 {
+ uint32_t ipv4_addr;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+ *
+ * Allows modification of IPv6 source (RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC)
+ * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV6_DST) in the
+ * specified outermost IPv6 header.
+ */
+struct rte_flow_action_set_ipv6 {
+ uint8_t ipv6_addr[16];
+};
+
/*
* Definition of a single action.
*
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH 1/3] ethdev: add flow api actions to modify IP addresses
2018-09-24 8:28 ` [dpdk-dev] [PATCH 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
@ 2018-09-25 3:03 ` Xiaoyu Min
0 siblings, 0 replies; 22+ messages in thread
From: Xiaoyu Min @ 2018-09-25 3:03 UTC (permalink / raw)
To: Rahul Lakkireddy; +Cc: dev, indranil, nirranjan
On 18-09-24 13:58:17, Rahul Lakkireddy wrote:
> Add actions:
> - SET_IPV4_SRC - set a new IPv4 source address.
> - SET_IPV4_DST - set a new IPv4 destination address.
> - SET_IPV6_SRC - set a new IPv6 source address.
> - SET_IPV6_DST - set a new IPv6 destination address.
>
> Original work by Shagun Agrawal
>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> ---
> Changes since RFC v2:
> - Updated comments, help messages, and doc to indicate that IP/TCP/UDP
> of the outermost headers are modified.
> - Updated comments and doc to indicate that a corresponding valid flow
> pattern item must be specified to offload corresponding header rewrite
> action.
> - Updated release notes.
>
> app/test-pmd/cmdline_flow.c | 104 ++++++++++++++++++++
> app/test-pmd/config.c | 8 ++
> doc/guides/prog_guide/rte_flow.rst | 72 ++++++++++++++
> doc/guides/rel_notes/release_18_11.rst | 6 ++
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 18 ++++
> lib/librte_ethdev/rte_flow.c | 8 ++
> lib/librte_ethdev/rte_flow.h | 70 +++++++++++++
> 7 files changed, 286 insertions(+)
>
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index f9260600e..1432498a3 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -243,6 +243,14 @@ enum index {
> ACTION_VXLAN_DECAP,
> ACTION_NVGRE_ENCAP,
> ACTION_NVGRE_DECAP,
> + ACTION_SET_IPV4_SRC,
> + ACTION_SET_IPV4_SRC_IPV4_SRC,
> + ACTION_SET_IPV4_DST,
> + ACTION_SET_IPV4_DST_IPV4_DST,
> + ACTION_SET_IPV6_SRC,
> + ACTION_SET_IPV6_SRC_IPV6_SRC,
> + ACTION_SET_IPV6_DST,
> + ACTION_SET_IPV6_DST_IPV6_DST,
> };
>
> /** Maximum size for pattern in struct rte_flow_item_raw. */
> @@ -816,6 +824,10 @@ static const enum index next_action[] = {
> ACTION_VXLAN_DECAP,
> ACTION_NVGRE_ENCAP,
> ACTION_NVGRE_DECAP,
> + ACTION_SET_IPV4_SRC,
> + ACTION_SET_IPV4_DST,
> + ACTION_SET_IPV6_SRC,
> + ACTION_SET_IPV6_DST,
> ZERO,
> };
>
> @@ -918,6 +930,30 @@ static const enum index action_of_push_mpls[] = {
> ZERO,
> };
>
> +static const enum index action_set_ipv4_src[] = {
> + ACTION_SET_IPV4_SRC_IPV4_SRC,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> +static const enum index action_set_ipv4_dst[] = {
> + ACTION_SET_IPV4_DST_IPV4_DST,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> +static const enum index action_set_ipv6_src[] = {
> + ACTION_SET_IPV6_SRC_IPV6_SRC,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> +static const enum index action_set_ipv6_dst[] = {
> + ACTION_SET_IPV6_DST_IPV6_DST,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> static const enum index action_jump[] = {
> ACTION_JUMP_GROUP,
> ACTION_NEXT,
> @@ -2470,6 +2506,74 @@ static const struct token token_list[] = {
> .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
> .call = parse_vc,
> },
> + [ACTION_SET_IPV4_SRC] = {
> + .name = "set_ipv4_src",
> + .help = "Set a new IPv4 source address in the outermost"
> + " IPv4 header",
> + .priv = PRIV_ACTION(SET_IPV4_SRC,
> + sizeof(struct rte_flow_action_set_ipv4)),
> + .next = NEXT(action_set_ipv4_src),
> + .call = parse_vc,
> + },
> + [ACTION_SET_IPV4_SRC_IPV4_SRC] = {
> + .name = "ipv4_addr",
> + .help = "new IPv4 source address to set",
> + .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(IPV4_ADDR)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_ipv4, ipv4_addr)),
> + .call = parse_vc_conf,
> + },
> + [ACTION_SET_IPV4_DST] = {
> + .name = "set_ipv4_dst",
> + .help = "Set a new IPv4 destination address in the outermost"
> + " IPv4 header",
> + .priv = PRIV_ACTION(SET_IPV4_DST,
> + sizeof(struct rte_flow_action_set_ipv4)),
> + .next = NEXT(action_set_ipv4_dst),
> + .call = parse_vc,
> + },
> + [ACTION_SET_IPV4_DST_IPV4_DST] = {
> + .name = "ipv4_addr",
> + .help = "new IPv4 destination address to set",
> + .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(IPV4_ADDR)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_ipv4, ipv4_addr)),
> + .call = parse_vc_conf,
> + },
> + [ACTION_SET_IPV6_SRC] = {
> + .name = "set_ipv6_src",
> + .help = "Set a new IPv6 source address in the outermost"
> + " IPv6 header",
> + .priv = PRIV_ACTION(SET_IPV6_SRC,
> + sizeof(struct rte_flow_action_set_ipv6)),
> + .next = NEXT(action_set_ipv6_src),
> + .call = parse_vc,
> + },
> + [ACTION_SET_IPV6_SRC_IPV6_SRC] = {
> + .name = "ipv6_addr",
> + .help = "new IPv6 source address to set",
> + .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(IPV6_ADDR)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_ipv6, ipv6_addr)),
> + .call = parse_vc_conf,
> + },
> + [ACTION_SET_IPV6_DST] = {
> + .name = "set_ipv6_dst",
> + .help = "Set a new IPv6 destination address in the outermost"
> + " IPv6 header",
> + .priv = PRIV_ACTION(SET_IPV6_DST,
> + sizeof(struct rte_flow_action_set_ipv6)),
> + .next = NEXT(action_set_ipv6_dst),
> + .call = parse_vc,
> + },
> + [ACTION_SET_IPV6_DST_IPV6_DST] = {
> + .name = "ipv6_addr",
> + .help = "new IPv6 destination address to set",
> + .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(IPV6_ADDR)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_ipv6, ipv6_addr)),
> + .call = parse_vc_conf,
> + },
> };
>
> /** Remove and return last entry from argument stack. */
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index 794aa5268..14dbdf7a3 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1172,6 +1172,14 @@ static const struct {
> sizeof(struct rte_flow_action_of_pop_mpls)),
> MK_FLOW_ACTION(OF_PUSH_MPLS,
> sizeof(struct rte_flow_action_of_push_mpls)),
> + MK_FLOW_ACTION(SET_IPV4_SRC,
> + sizeof(struct rte_flow_action_set_ipv4)),
> + MK_FLOW_ACTION(SET_IPV4_DST,
> + sizeof(struct rte_flow_action_set_ipv4)),
> + MK_FLOW_ACTION(SET_IPV6_SRC,
> + sizeof(struct rte_flow_action_set_ipv6)),
> + MK_FLOW_ACTION(SET_IPV6_DST,
> + sizeof(struct rte_flow_action_set_ipv6)),
> };
>
> /** Compute storage space needed by action configuration and copy it. */
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index b305a72a5..b9bcaa3d1 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -2076,6 +2076,78 @@ RTE_FLOW_ERROR_TYPE_ACTION error should be returned.
>
> This action modifies the payload of matched flows.
>
> +Action: ``SET_IPV4_SRC``
> +^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new IPv4 source address in the outermost IPv4 header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
> +Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
> +
> +.. _table_rte_flow_action_set_ipv4_src:
> +
> +.. table:: SET_IPV4_SRC
> +
> + +-----------------------------------------+
> + | Field | Value |
> + +===============+=========================+
> + | ``ipv4_addr`` | new IPv4 source address |
> + +---------------+-------------------------+
> +
> +Action: ``SET_IPV4_DST``
> +^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new IPv4 destination address in the outermost IPv4 header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
> +Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
> +
> +.. _table_rte_flow_action_set_ipv4_dst:
> +
> +.. table:: SET_IPV4_DST
> +
> + +---------------+------------------------------+
> + | Field | Value |
> + +===============+==============================+
> + | ``ipv4_addr`` | new IPv4 destination address |
> + +---------------+------------------------------+
> +
> +Action: ``SET_IPV6_SRC``
> +^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new IPv6 source address in the outermost IPv6 header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
> +Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
> +
> +.. _table_rte_flow_action_set_ipv6_src:
> +
> +.. table:: SET_IPV6_SRC
> +
> + +---------------+-------------------------+
> + | Field | Value |
> + +===============+=========================+
> + | ``ipv6_addr`` | new IPv6 source address |
> + +---------------+-------------------------+
> +
> +Action: ``SET_IPV6_DST``
> +^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new IPv6 destination address in the outermost IPv6 header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
> +Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
> +
> +.. _table_rte_flow_action_set_ipv6_dst:
> +
> +.. table:: SET_IPV6_DST
> +
> + +---------------+------------------------------+
> + | Field | Value |
> + +===============+==============================+
> + | ``ipv6_addr`` | new IPv6 destination address |
> + +---------------+------------------------------+
> +
> Negative types
> ~~~~~~~~~~~~~~
>
> diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
> index f39cb15d2..782722318 100644
> --- a/doc/guides/rel_notes/release_18_11.rst
> +++ b/doc/guides/rel_notes/release_18_11.rst
> @@ -87,6 +87,12 @@ New Features
> the specified port. The port must be stopped before the command call in order
> to reconfigure queues.
>
> +* **Added new Flow API actions to rewrite fields in packet headers.**
> +
> + Added new Flow API actions to:
> +
> + * Modify source and destination IP addresses in the outermost IPv4/IPv6
> + headers.
>
> API Changes
> -----------
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 3a73000a6..97d91f066 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3704,6 +3704,24 @@ This section lists supported actions and their attributes, if any.
> - ``nvgre_decap``: Performs a decapsulation action by stripping all headers of
> the NVGRE tunnel network overlay from the matched flow.
>
> +- ``set_ipv4_src``: Set a new IPv4 source address in the outermost IPv4 header.
> +
> + - ``ipv4_addr``: New IPv4 source address.
> +
> +- ``set_ipv4_dst``: Set a new IPv4 destination address in the outermost IPv4
> + header.
> +
> + - ``ipv4_addr``: New IPv4 destination address.
> +
> +- ``set_ipv6_src``: Set a new IPv6 source address in the outermost IPv6 header.
> +
> + - ``ipv6_addr``: New IPv6 source address.
> +
> +- ``set_ipv6_dst``: Set a new IPv6 destination address in the outermost IPv6
> + header.
> +
> + - ``ipv6_addr``: New IPv6 destination address.
> +
> Destroying flow rules
> ~~~~~~~~~~~~~~~~~~~~~
>
> diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
> index cff4b5209..d4f1b9a05 100644
> --- a/lib/librte_ethdev/rte_flow.c
> +++ b/lib/librte_ethdev/rte_flow.c
> @@ -109,6 +109,14 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
> sizeof(struct rte_flow_action_of_pop_mpls)),
> MK_FLOW_ACTION(OF_PUSH_MPLS,
> sizeof(struct rte_flow_action_of_push_mpls)),
> + MK_FLOW_ACTION(SET_IPV4_SRC,
> + sizeof(struct rte_flow_action_set_ipv4)),
> + MK_FLOW_ACTION(SET_IPV4_DST,
> + sizeof(struct rte_flow_action_set_ipv4)),
> + MK_FLOW_ACTION(SET_IPV6_SRC,
> + sizeof(struct rte_flow_action_set_ipv6)),
> + MK_FLOW_ACTION(SET_IPV6_DST,
> + sizeof(struct rte_flow_action_set_ipv6)),
> };
>
> static int
> diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
> index f8ba71cdb..0fe91ae89 100644
> --- a/lib/librte_ethdev/rte_flow.h
> +++ b/lib/librte_ethdev/rte_flow.h
> @@ -1505,6 +1505,46 @@ enum rte_flow_action_type {
> * error.
> */
> RTE_FLOW_ACTION_TYPE_NVGRE_DECAP,
> +
> + /**
> + * Modify IPv4 source address in the outermost IPv4 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_ipv4.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC,
> +
> + /**
> + * Modify IPv4 destination address in the outermost IPv4 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_ipv4.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_IPV4_DST,
> +
> + /**
> + * Modify IPv6 source address in the outermost IPv6 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_ipv6.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC,
> +
> + /**
> + * Modify IPv6 destination address in the outermost IPv6 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_ipv6.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
> };
>
> /**
> @@ -1868,6 +1908,36 @@ struct rte_flow_action_nvgre_encap {
> struct rte_flow_item *definition;
> };
>
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
> + * RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
> + *
> + * Allows modification of IPv4 source (RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC)
> + * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV4_DST) in the
> + * specified outermost IPv4 header.
> + */
> +struct rte_flow_action_set_ipv4 {
> + uint32_t ipv4_addr;
> +};
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
> + * RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
> + *
> + * Allows modification of IPv6 source (RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC)
> + * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV6_DST) in the
> + * specified outermost IPv6 header.
> + */
> +struct rte_flow_action_set_ipv6 {
> + uint8_t ipv6_addr[16];
> +};
> +
> /*
> * Definition of a single action.
> *
> --
> 2.18.0
>
Acked-by: Xiaoyu Min <jackmin@mellanox.com>
Thanks
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
2018-09-24 8:28 [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-09-24 8:28 ` [dpdk-dev] [PATCH 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
@ 2018-09-24 8:28 ` Rahul Lakkireddy
2018-09-25 3:06 ` Xiaoyu Min
2018-10-04 13:55 ` Ori Kam
2018-09-24 8:28 ` [dpdk-dev] [PATCH 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
` (2 subsequent siblings)
4 siblings, 2 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-09-24 8:28 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Add actions:
- SET_TP_SRC - set a new TCP/UDP source port number.
- SET_TP_DST - set a new TCP/UDP destination port number.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
Changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
action.
- Updated release notes.
app/test-pmd/cmdline_flow.c | 52 +++++++++++++++++++++
app/test-pmd/config.c | 4 ++
doc/guides/prog_guide/rte_flow.rst | 36 ++++++++++++++
doc/guides/rel_notes/release_18_11.rst | 2 +
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++++
lib/librte_ethdev/rte_flow.c | 4 ++
lib/librte_ethdev/rte_flow.h | 37 +++++++++++++++
7 files changed, 145 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 1432498a3..a9888cacf 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -251,6 +251,10 @@ enum index {
ACTION_SET_IPV6_SRC_IPV6_SRC,
ACTION_SET_IPV6_DST,
ACTION_SET_IPV6_DST_IPV6_DST,
+ ACTION_SET_TP_SRC,
+ ACTION_SET_TP_SRC_TP_SRC,
+ ACTION_SET_TP_DST,
+ ACTION_SET_TP_DST_TP_DST,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -828,6 +832,8 @@ static const enum index next_action[] = {
ACTION_SET_IPV4_DST,
ACTION_SET_IPV6_SRC,
ACTION_SET_IPV6_DST,
+ ACTION_SET_TP_SRC,
+ ACTION_SET_TP_DST,
ZERO,
};
@@ -954,6 +960,18 @@ static const enum index action_set_ipv6_dst[] = {
ZERO,
};
+static const enum index action_set_tp_src[] = {
+ ACTION_SET_TP_SRC_TP_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_tp_dst[] = {
+ ACTION_SET_TP_DST_TP_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_jump[] = {
ACTION_JUMP_GROUP,
ACTION_NEXT,
@@ -2574,6 +2592,40 @@ static const struct token token_list[] = {
(struct rte_flow_action_set_ipv6, ipv6_addr)),
.call = parse_vc_conf,
},
+ [ACTION_SET_TP_SRC] = {
+ .name = "set_tp_src",
+ .help = "set a new source port number in the outermost"
+ " TCP/UDP header",
+ .priv = PRIV_ACTION(SET_TP_SRC,
+ sizeof(struct rte_flow_action_set_tp)),
+ .next = NEXT(action_set_tp_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_TP_SRC_TP_SRC] = {
+ .name = "port",
+ .help = "new source port number to set",
+ .next = NEXT(action_set_tp_src, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_tp, port)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_TP_DST] = {
+ .name = "set_tp_dst",
+ .help = "set a new destination port number in the outermost"
+ " TCP/UDP header",
+ .priv = PRIV_ACTION(SET_TP_DST,
+ sizeof(struct rte_flow_action_set_tp)),
+ .next = NEXT(action_set_tp_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_TP_DST_TP_DST] = {
+ .name = "port",
+ .help = "new destination port number to set",
+ .next = NEXT(action_set_tp_dst, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_tp, port)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 14dbdf7a3..1629a6d7a 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1180,6 +1180,10 @@ static const struct {
sizeof(struct rte_flow_action_set_ipv6)),
MK_FLOW_ACTION(SET_IPV6_DST,
sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_TP_SRC,
+ sizeof(struct rte_flow_action_set_tp)),
+ MK_FLOW_ACTION(SET_TP_DST,
+ sizeof(struct rte_flow_action_set_tp)),
};
/** Compute storage space needed by action configuration and copy it. */
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index b9bcaa3d1..4be160209 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2148,6 +2148,42 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
| ``ipv6_addr`` | new IPv6 destination address |
+---------------+------------------------------+
+Action: ``SET_TP_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new source port number in the outermost TCP/UDP header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
+flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_tp_src:
+
+.. table:: SET_TP_SRC
+
+ +----------+-------------------------+
+ | Field | Value |
+ +==========+=========================+
+ | ``port`` | new TCP/UDP source port |
+ +---------------+--------------------+
+
+Action: ``SET_TP_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new destination port number in the outermost TCP/UDP header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
+flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_tp_dst:
+
+.. table:: SET_TP_DST
+
+ +----------+------------------------------+
+ | Field | Value |
+ +==========+==============================+
+ | ``port`` | new TCP/UDP destination port |
+ +---------------+-------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 782722318..84b0a6a4b 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -93,6 +93,8 @@ New Features
* Modify source and destination IP addresses in the outermost IPv4/IPv6
headers.
+ * Modify source and destination port numbers in the outermost TCP/UDP
+ headers.
API Changes
-----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 97d91f066..ffec7013b 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3722,6 +3722,16 @@ This section lists supported actions and their attributes, if any.
- ``ipv6_addr``: New IPv6 destination address.
+- ``of_set_tp_src``: Set a new source port number in the outermost TCP/UDP
+ header.
+
+ - ``port``: New TCP/UDP source port number.
+
+- ``of_set_tp_dst``: Set a new destination port number in the outermost TCP/UDP
+ header.
+
+ - ``port``: New TCP/UDP destination port number.
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index d4f1b9a05..409c79741 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -117,6 +117,10 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
sizeof(struct rte_flow_action_set_ipv6)),
MK_FLOW_ACTION(SET_IPV6_DST,
sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_TP_SRC,
+ sizeof(struct rte_flow_action_set_tp)),
+ MK_FLOW_ACTION(SET_TP_DST,
+ sizeof(struct rte_flow_action_set_tp)),
};
static int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index 0fe91ae89..cf5cecf42 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -1545,6 +1545,28 @@ enum rte_flow_action_type {
* See struct rte_flow_action_set_ipv6.
*/
RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
+
+ /**
+ * Modify source port number in the outermost TCP/UDP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
+ * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
+ * RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_tp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_TP_SRC,
+
+ /**
+ * Modify destination port number in the outermost TCP/UDP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
+ * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
+ * RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_tp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_TP_DST,
};
/**
@@ -1938,6 +1960,21 @@ struct rte_flow_action_set_ipv6 {
uint8_t ipv6_addr[16];
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_TP_DST
+ *
+ * Allows modification of source (RTE_FLOW_ACTION_TYPE_SET_TP_SRC)
+ * and destination (RTE_FLOW_ACTION_TYPE_SET_TP_DST) port numbers
+ * in the specified outermost TCP/UDP header.
+ */
+struct rte_flow_action_set_tp {
+ uint16_t port;
+};
+
/*
* Definition of a single action.
*
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
2018-09-24 8:28 ` [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
@ 2018-09-25 3:06 ` Xiaoyu Min
2018-10-04 13:55 ` Ori Kam
1 sibling, 0 replies; 22+ messages in thread
From: Xiaoyu Min @ 2018-09-25 3:06 UTC (permalink / raw)
To: Rahul Lakkireddy; +Cc: dev, indranil, nirranjan
On 18-09-24 13:58:18, Rahul Lakkireddy wrote:
> Add actions:
> - SET_TP_SRC - set a new TCP/UDP source port number.
> - SET_TP_DST - set a new TCP/UDP destination port number.
>
> Original work by Shagun Agrawal
>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> ---
> Changes since RFC v2:
> - Updated comments, help messages, and doc to indicate that IP/TCP/UDP
> of the outermost headers are modified.
> - Updated comments and doc to indicate that a corresponding valid flow
> pattern item must be specified to offload corresponding header rewrite
> action.
> - Updated release notes.
>
> app/test-pmd/cmdline_flow.c | 52 +++++++++++++++++++++
> app/test-pmd/config.c | 4 ++
> doc/guides/prog_guide/rte_flow.rst | 36 ++++++++++++++
> doc/guides/rel_notes/release_18_11.rst | 2 +
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++++
> lib/librte_ethdev/rte_flow.c | 4 ++
> lib/librte_ethdev/rte_flow.h | 37 +++++++++++++++
> 7 files changed, 145 insertions(+)
>
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 1432498a3..a9888cacf 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -251,6 +251,10 @@ enum index {
> ACTION_SET_IPV6_SRC_IPV6_SRC,
> ACTION_SET_IPV6_DST,
> ACTION_SET_IPV6_DST_IPV6_DST,
> + ACTION_SET_TP_SRC,
> + ACTION_SET_TP_SRC_TP_SRC,
> + ACTION_SET_TP_DST,
> + ACTION_SET_TP_DST_TP_DST,
> };
>
> /** Maximum size for pattern in struct rte_flow_item_raw. */
> @@ -828,6 +832,8 @@ static const enum index next_action[] = {
> ACTION_SET_IPV4_DST,
> ACTION_SET_IPV6_SRC,
> ACTION_SET_IPV6_DST,
> + ACTION_SET_TP_SRC,
> + ACTION_SET_TP_DST,
> ZERO,
> };
>
> @@ -954,6 +960,18 @@ static const enum index action_set_ipv6_dst[] = {
> ZERO,
> };
>
> +static const enum index action_set_tp_src[] = {
> + ACTION_SET_TP_SRC_TP_SRC,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> +static const enum index action_set_tp_dst[] = {
> + ACTION_SET_TP_DST_TP_DST,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> static const enum index action_jump[] = {
> ACTION_JUMP_GROUP,
> ACTION_NEXT,
> @@ -2574,6 +2592,40 @@ static const struct token token_list[] = {
> (struct rte_flow_action_set_ipv6, ipv6_addr)),
> .call = parse_vc_conf,
> },
> + [ACTION_SET_TP_SRC] = {
> + .name = "set_tp_src",
> + .help = "set a new source port number in the outermost"
> + " TCP/UDP header",
> + .priv = PRIV_ACTION(SET_TP_SRC,
> + sizeof(struct rte_flow_action_set_tp)),
> + .next = NEXT(action_set_tp_src),
> + .call = parse_vc,
> + },
> + [ACTION_SET_TP_SRC_TP_SRC] = {
> + .name = "port",
> + .help = "new source port number to set",
> + .next = NEXT(action_set_tp_src, NEXT_ENTRY(UNSIGNED)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_tp, port)),
> + .call = parse_vc_conf,
> + },
> + [ACTION_SET_TP_DST] = {
> + .name = "set_tp_dst",
> + .help = "set a new destination port number in the outermost"
> + " TCP/UDP header",
> + .priv = PRIV_ACTION(SET_TP_DST,
> + sizeof(struct rte_flow_action_set_tp)),
> + .next = NEXT(action_set_tp_dst),
> + .call = parse_vc,
> + },
> + [ACTION_SET_TP_DST_TP_DST] = {
> + .name = "port",
> + .help = "new destination port number to set",
> + .next = NEXT(action_set_tp_dst, NEXT_ENTRY(UNSIGNED)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_tp, port)),
> + .call = parse_vc_conf,
> + },
> };
>
> /** Remove and return last entry from argument stack. */
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index 14dbdf7a3..1629a6d7a 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1180,6 +1180,10 @@ static const struct {
> sizeof(struct rte_flow_action_set_ipv6)),
> MK_FLOW_ACTION(SET_IPV6_DST,
> sizeof(struct rte_flow_action_set_ipv6)),
> + MK_FLOW_ACTION(SET_TP_SRC,
> + sizeof(struct rte_flow_action_set_tp)),
> + MK_FLOW_ACTION(SET_TP_DST,
> + sizeof(struct rte_flow_action_set_tp)),
> };
>
> /** Compute storage space needed by action configuration and copy it. */
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index b9bcaa3d1..4be160209 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -2148,6 +2148,42 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
> | ``ipv6_addr`` | new IPv6 destination address |
> +---------------+------------------------------+
>
> +Action: ``SET_TP_SRC``
> +^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new source port number in the outermost TCP/UDP header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
> +flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
> +
> +.. _table_rte_flow_action_set_tp_src:
> +
> +.. table:: SET_TP_SRC
> +
> + +----------+-------------------------+
> + | Field | Value |
> + +==========+=========================+
> + | ``port`` | new TCP/UDP source port |
> + +---------------+--------------------+
> +
> +Action: ``SET_TP_DST``
> +^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new destination port number in the outermost TCP/UDP header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
> +flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
> +
> +.. _table_rte_flow_action_set_tp_dst:
> +
> +.. table:: SET_TP_DST
> +
> + +----------+------------------------------+
> + | Field | Value |
> + +==========+==============================+
> + | ``port`` | new TCP/UDP destination port |
> + +---------------+-------------------------+
> +
> Negative types
> ~~~~~~~~~~~~~~
>
> diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
> index 782722318..84b0a6a4b 100644
> --- a/doc/guides/rel_notes/release_18_11.rst
> +++ b/doc/guides/rel_notes/release_18_11.rst
> @@ -93,6 +93,8 @@ New Features
>
> * Modify source and destination IP addresses in the outermost IPv4/IPv6
> headers.
> + * Modify source and destination port numbers in the outermost TCP/UDP
> + headers.
>
> API Changes
> -----------
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 97d91f066..ffec7013b 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3722,6 +3722,16 @@ This section lists supported actions and their attributes, if any.
>
> - ``ipv6_addr``: New IPv6 destination address.
>
> +- ``of_set_tp_src``: Set a new source port number in the outermost TCP/UDP
> + header.
> +
> + - ``port``: New TCP/UDP source port number.
> +
> +- ``of_set_tp_dst``: Set a new destination port number in the outermost TCP/UDP
> + header.
> +
> + - ``port``: New TCP/UDP destination port number.
> +
> Destroying flow rules
> ~~~~~~~~~~~~~~~~~~~~~
>
> diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
> index d4f1b9a05..409c79741 100644
> --- a/lib/librte_ethdev/rte_flow.c
> +++ b/lib/librte_ethdev/rte_flow.c
> @@ -117,6 +117,10 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
> sizeof(struct rte_flow_action_set_ipv6)),
> MK_FLOW_ACTION(SET_IPV6_DST,
> sizeof(struct rte_flow_action_set_ipv6)),
> + MK_FLOW_ACTION(SET_TP_SRC,
> + sizeof(struct rte_flow_action_set_tp)),
> + MK_FLOW_ACTION(SET_TP_DST,
> + sizeof(struct rte_flow_action_set_tp)),
> };
>
> static int
> diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
> index 0fe91ae89..cf5cecf42 100644
> --- a/lib/librte_ethdev/rte_flow.h
> +++ b/lib/librte_ethdev/rte_flow.h
> @@ -1545,6 +1545,28 @@ enum rte_flow_action_type {
> * See struct rte_flow_action_set_ipv6.
> */
> RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
> +
> + /**
> + * Modify source port number in the outermost TCP/UDP header.
> + *
> + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
> + * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
> + * RTE_FLOW_ERROR_TYPE_ACTION error.
> + *
> + * See struct rte_flow_action_set_tp.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_TP_SRC,
> +
> + /**
> + * Modify destination port number in the outermost TCP/UDP header.
> + *
> + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
> + * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
> + * RTE_FLOW_ERROR_TYPE_ACTION error.
> + *
> + * See struct rte_flow_action_set_tp.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_TP_DST,
> };
>
> /**
> @@ -1938,6 +1960,21 @@ struct rte_flow_action_set_ipv6 {
> uint8_t ipv6_addr[16];
> };
>
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ACTION_TYPE_SET_TP_SRC
> + * RTE_FLOW_ACTION_TYPE_SET_TP_DST
> + *
> + * Allows modification of source (RTE_FLOW_ACTION_TYPE_SET_TP_SRC)
> + * and destination (RTE_FLOW_ACTION_TYPE_SET_TP_DST) port numbers
> + * in the specified outermost TCP/UDP header.
> + */
> +struct rte_flow_action_set_tp {
> + uint16_t port;
> +};
> +
> /*
> * Definition of a single action.
> *
> --
> 2.18.0
>
Acked-by: Xiaoyu Min <jackmin@mellanox.com>
Thanks
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
2018-09-24 8:28 ` [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
2018-09-25 3:06 ` Xiaoyu Min
@ 2018-10-04 13:55 ` Ori Kam
2018-10-04 15:35 ` Ferruh Yigit
1 sibling, 1 reply; 22+ messages in thread
From: Ori Kam @ 2018-10-04 13:55 UTC (permalink / raw)
To: Rahul Lakkireddy, dev; +Cc: indranil, nirranjan
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Rahul Lakkireddy
> Sent: Monday, September 24, 2018 11:28 AM
> To: dev@dpdk.org
> Cc: indranil@chelsio.com; nirranjan@chelsio.com
> Subject: [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify
> TCP/UDP port numbers
>
> Add actions:
> - SET_TP_SRC - set a new TCP/UDP source port number.
> - SET_TP_DST - set a new TCP/UDP destination port number.
>
> Original work by Shagun Agrawal
>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> ---
> Changes since RFC v2:
> - Updated comments, help messages, and doc to indicate that IP/TCP/UDP
> of the outermost headers are modified.
> - Updated comments and doc to indicate that a corresponding valid flow
> pattern item must be specified to offload corresponding header rewrite
> action.
> - Updated release notes.
>
> app/test-pmd/cmdline_flow.c | 52 +++++++++++++++++++++
> app/test-pmd/config.c | 4 ++
> doc/guides/prog_guide/rte_flow.rst | 36 ++++++++++++++
> doc/guides/rel_notes/release_18_11.rst | 2 +
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++++
> lib/librte_ethdev/rte_flow.c | 4 ++
> lib/librte_ethdev/rte_flow.h | 37 +++++++++++++++
> 7 files changed, 145 insertions(+)
>
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 1432498a3..a9888cacf 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -251,6 +251,10 @@ enum index {
> ACTION_SET_IPV6_SRC_IPV6_SRC,
> ACTION_SET_IPV6_DST,
> ACTION_SET_IPV6_DST_IPV6_DST,
> + ACTION_SET_TP_SRC,
> + ACTION_SET_TP_SRC_TP_SRC,
> + ACTION_SET_TP_DST,
> + ACTION_SET_TP_DST_TP_DST,
> };
>
> /** Maximum size for pattern in struct rte_flow_item_raw. */
> @@ -828,6 +832,8 @@ static const enum index next_action[] = {
> ACTION_SET_IPV4_DST,
> ACTION_SET_IPV6_SRC,
> ACTION_SET_IPV6_DST,
> + ACTION_SET_TP_SRC,
> + ACTION_SET_TP_DST,
> ZERO,
> };
>
> @@ -954,6 +960,18 @@ static const enum index action_set_ipv6_dst[] = {
> ZERO,
> };
>
> +static const enum index action_set_tp_src[] = {
> + ACTION_SET_TP_SRC_TP_SRC,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> +static const enum index action_set_tp_dst[] = {
> + ACTION_SET_TP_DST_TP_DST,
> + ACTION_NEXT,
> + ZERO,
> +};
> +
> static const enum index action_jump[] = {
> ACTION_JUMP_GROUP,
> ACTION_NEXT,
> @@ -2574,6 +2592,40 @@ static const struct token token_list[] = {
> (struct rte_flow_action_set_ipv6, ipv6_addr)),
> .call = parse_vc_conf,
> },
> + [ACTION_SET_TP_SRC] = {
> + .name = "set_tp_src",
> + .help = "set a new source port number in the outermost"
> + " TCP/UDP header",
> + .priv = PRIV_ACTION(SET_TP_SRC,
> + sizeof(struct rte_flow_action_set_tp)),
> + .next = NEXT(action_set_tp_src),
> + .call = parse_vc,
> + },
> + [ACTION_SET_TP_SRC_TP_SRC] = {
> + .name = "port",
> + .help = "new source port number to set",
> + .next = NEXT(action_set_tp_src, NEXT_ENTRY(UNSIGNED)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_tp, port)),
> + .call = parse_vc_conf,
> + },
> + [ACTION_SET_TP_DST] = {
> + .name = "set_tp_dst",
> + .help = "set a new destination port number in the outermost"
> + " TCP/UDP header",
> + .priv = PRIV_ACTION(SET_TP_DST,
> + sizeof(struct rte_flow_action_set_tp)),
> + .next = NEXT(action_set_tp_dst),
> + .call = parse_vc,
> + },
> + [ACTION_SET_TP_DST_TP_DST] = {
> + .name = "port",
> + .help = "new destination port number to set",
> + .next = NEXT(action_set_tp_dst, NEXT_ENTRY(UNSIGNED)),
> + .args = ARGS(ARGS_ENTRY_HTON
> + (struct rte_flow_action_set_tp, port)),
> + .call = parse_vc_conf,
> + },
> };
>
> /** Remove and return last entry from argument stack. */
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index 14dbdf7a3..1629a6d7a 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -1180,6 +1180,10 @@ static const struct {
> sizeof(struct rte_flow_action_set_ipv6)),
> MK_FLOW_ACTION(SET_IPV6_DST,
> sizeof(struct rte_flow_action_set_ipv6)),
> + MK_FLOW_ACTION(SET_TP_SRC,
> + sizeof(struct rte_flow_action_set_tp)),
> + MK_FLOW_ACTION(SET_TP_DST,
> + sizeof(struct rte_flow_action_set_tp)),
> };
>
> /** Compute storage space needed by action configuration and copy it. */
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index b9bcaa3d1..4be160209 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -2148,6 +2148,42 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error
> will be returned.
> | ``ipv6_addr`` | new IPv6 destination address |
> +---------------+------------------------------+
>
> +Action: ``SET_TP_SRC``
> +^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new source port number in the outermost TCP/UDP header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or
> RTE_FLOW_ITEM_TYPE_UDP
> +flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be
> returned.
> +
> +.. _table_rte_flow_action_set_tp_src:
> +
> +.. table:: SET_TP_SRC
> +
> + +----------+-------------------------+
> + | Field | Value |
> + +==========+=========================+
> + | ``port`` | new TCP/UDP source port |
> + +---------------+--------------------+
> +
> +Action: ``SET_TP_DST``
> +^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Set a new destination port number in the outermost TCP/UDP header.
> +
> +It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or
> RTE_FLOW_ITEM_TYPE_UDP
> +flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be
> returned.
> +
> +.. _table_rte_flow_action_set_tp_dst:
> +
> +.. table:: SET_TP_DST
> +
> + +----------+------------------------------+
> + | Field | Value |
> + +==========+==============================+
> + | ``port`` | new TCP/UDP destination port |
> + +---------------+-------------------------+
> +
> Negative types
> ~~~~~~~~~~~~~~
>
> diff --git a/doc/guides/rel_notes/release_18_11.rst
> b/doc/guides/rel_notes/release_18_11.rst
> index 782722318..84b0a6a4b 100644
> --- a/doc/guides/rel_notes/release_18_11.rst
> +++ b/doc/guides/rel_notes/release_18_11.rst
> @@ -93,6 +93,8 @@ New Features
>
> * Modify source and destination IP addresses in the outermost IPv4/IPv6
> headers.
> + * Modify source and destination port numbers in the outermost TCP/UDP
> + headers.
>
> API Changes
> -----------
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 97d91f066..ffec7013b 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3722,6 +3722,16 @@ This section lists supported actions and their
> attributes, if any.
>
> - ``ipv6_addr``: New IPv6 destination address.
>
> +- ``of_set_tp_src``: Set a new source port number in the outermost TCP/UDP
> + header.
> +
> + - ``port``: New TCP/UDP source port number.
> +
> +- ``of_set_tp_dst``: Set a new destination port number in the outermost
> TCP/UDP
> + header.
> +
> + - ``port``: New TCP/UDP destination port number.
> +
> Destroying flow rules
> ~~~~~~~~~~~~~~~~~~~~~
>
> diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
> index d4f1b9a05..409c79741 100644
> --- a/lib/librte_ethdev/rte_flow.c
> +++ b/lib/librte_ethdev/rte_flow.c
> @@ -117,6 +117,10 @@ static const struct rte_flow_desc_data
> rte_flow_desc_action[] = {
> sizeof(struct rte_flow_action_set_ipv6)),
> MK_FLOW_ACTION(SET_IPV6_DST,
> sizeof(struct rte_flow_action_set_ipv6)),
> + MK_FLOW_ACTION(SET_TP_SRC,
> + sizeof(struct rte_flow_action_set_tp)),
> + MK_FLOW_ACTION(SET_TP_DST,
> + sizeof(struct rte_flow_action_set_tp)),
> };
>
> static int
> diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
> index 0fe91ae89..cf5cecf42 100644
> --- a/lib/librte_ethdev/rte_flow.h
> +++ b/lib/librte_ethdev/rte_flow.h
> @@ -1545,6 +1545,28 @@ enum rte_flow_action_type {
> * See struct rte_flow_action_set_ipv6.
> */
> RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
> +
> + /**
> + * Modify source port number in the outermost TCP/UDP header.
> + *
> + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
> + * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
> + * RTE_FLOW_ERROR_TYPE_ACTION error.
> + *
> + * See struct rte_flow_action_set_tp.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_TP_SRC,
> +
> + /**
> + * Modify destination port number in the outermost TCP/UDP header.
> + *
> + * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
> + * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
> + * RTE_FLOW_ERROR_TYPE_ACTION error.
> + *
> + * See struct rte_flow_action_set_tp.
> + */
> + RTE_FLOW_ACTION_TYPE_SET_TP_DST,
> };
>
> /**
> @@ -1938,6 +1960,21 @@ struct rte_flow_action_set_ipv6 {
> uint8_t ipv6_addr[16];
> };
>
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ACTION_TYPE_SET_TP_SRC
> + * RTE_FLOW_ACTION_TYPE_SET_TP_DST
> + *
> + * Allows modification of source (RTE_FLOW_ACTION_TYPE_SET_TP_SRC)
> + * and destination (RTE_FLOW_ACTION_TYPE_SET_TP_DST) port numbers
> + * in the specified outermost TCP/UDP header.
> + */
> +struct rte_flow_action_set_tp {
> + uint16_t port;
> +};
> +
> /*
> * Definition of a single action.
> *
> --
> 2.18.0
Acked-by: Ori Kam <orika@mellanox.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
2018-10-04 13:55 ` Ori Kam
@ 2018-10-04 15:35 ` Ferruh Yigit
0 siblings, 0 replies; 22+ messages in thread
From: Ferruh Yigit @ 2018-10-04 15:35 UTC (permalink / raw)
To: Ori Kam, Rahul Lakkireddy, dev; +Cc: indranil, nirranjan
On 10/4/2018 2:55 PM, Ori Kam wrote:
>
>
>> -----Original Message-----
>> From: dev <dev-bounces@dpdk.org> On Behalf Of Rahul Lakkireddy
>> Sent: Monday, September 24, 2018 11:28 AM
>> To: dev@dpdk.org
>> Cc: indranil@chelsio.com; nirranjan@chelsio.com
>> Subject: [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify
>> TCP/UDP port numbers
>>
>> Add actions:
>> - SET_TP_SRC - set a new TCP/UDP source port number.
>> - SET_TP_DST - set a new TCP/UDP destination port number.
>>
>> Original work by Shagun Agrawal
>>
>> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
<...>
> Acked-by: Ori Kam <orika@mellanox.com>
Hi Rahul,
Can you please rebase the set on top of latest head? Please keep Acks in new
version of the set.
Thanks,
ferruh
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
2018-09-24 8:28 [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-09-24 8:28 ` [dpdk-dev] [PATCH 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-09-24 8:28 ` [dpdk-dev] [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
@ 2018-09-24 8:28 ` Rahul Lakkireddy
2018-10-03 20:33 ` [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Thomas Monjalon
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 " Rahul Lakkireddy
4 siblings, 0 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-09-24 8:28 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Query firmware for the new filter work request to offload flows with
actions to modify IP and TCP/UDP port addresses. When available,
translate IP and TCP/UDP port address modify actions to internal
hardware specification and offload the flow to hardware.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
Changes since RFC v2:
- Re-based to tip.
- Updated all instances of fw_filter_wr to new fw_filter2_wr and removed
fw_filter_wr.
- Ensure correct ULP type is set when offloading NAT actions.
- Returning appropriate RTE_FLOW_ERROR_TYPE_ACTION error if a corresponding
valid flow pattern item for the header rewrite action is not found.
- Updated release notes.
doc/guides/rel_notes/release_18_11.rst | 4 +-
drivers/net/cxgbe/base/common.h | 1 +
drivers/net/cxgbe/base/t4_msg.h | 1 +
drivers/net/cxgbe/base/t4fw_interface.h | 23 ++-
drivers/net/cxgbe/cxgbe_filter.c | 37 +++--
drivers/net/cxgbe/cxgbe_filter.h | 23 +++
drivers/net/cxgbe/cxgbe_flow.c | 178 +++++++++++++++++++++++-
drivers/net/cxgbe/cxgbe_main.c | 10 ++
8 files changed, 265 insertions(+), 12 deletions(-)
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 84b0a6a4b..04d5d26a4 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -59,7 +59,9 @@ New Features
Flow API support has been enhanced for CXGBE Poll Mode Driver to offload:
* Match items: destination MAC address.
- * Action items: push/pop/rewrite vlan header.
+ * Action items: push/pop/rewrite vlan header, rewrite IP addresses in
+ outermost IPv4/IPv6 header, rewrite port numbers in outermost TCP/UDP
+ header.
* **Added support for SR-IOV in netvsc PMD.**
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index d9f74d995..fd2006682 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -271,6 +271,7 @@ struct adapter_params {
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
u8 fw_caps_support; /* 32-bit Port Capabilities */
+ u8 filter2_wr_support; /* FW support for FILTER2_WR */
};
/* Firmware Port Capabilities types.
diff --git a/drivers/net/cxgbe/base/t4_msg.h b/drivers/net/cxgbe/base/t4_msg.h
index 2128da64f..6494f1827 100644
--- a/drivers/net/cxgbe/base/t4_msg.h
+++ b/drivers/net/cxgbe/base/t4_msg.h
@@ -32,6 +32,7 @@ enum CPL_error {
enum {
ULP_MODE_NONE = 0,
+ ULP_MODE_TCPDDP = 5,
};
enum {
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index e2d2ee897..b4c95c588 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -61,6 +61,7 @@ enum fw_wr_opcodes {
FW_ETH_TX_PKTS_WR = 0x09,
FW_ETH_TX_PKT_VM_WR = 0x11,
FW_ETH_TX_PKTS_VM_WR = 0x12,
+ FW_FILTER2_WR = 0x77,
FW_ETH_TX_PKTS2_WR = 0x78,
};
@@ -165,7 +166,7 @@ enum fw_filter_wr_cookie {
FW_FILTER_WR_EINVAL,
};
-struct fw_filter_wr {
+struct fw_filter2_wr {
__be32 op_pkd;
__be32 len16_pkd;
__be64 r3;
@@ -195,6 +196,19 @@ struct fw_filter_wr {
__be16 fpm;
__be16 r7;
__u8 sma[6];
+ __be16 r8;
+ __u8 filter_type_swapmac;
+ __u8 natmode_to_ulp_type;
+ __be16 newlport;
+ __be16 newfport;
+ __u8 newlip[16];
+ __u8 newfip[16];
+ __be32 natseqcheck;
+ __be32 r9;
+ __be64 r10;
+ __be64 r11;
+ __be64 r12;
+ __be64 r13;
};
#define S_FW_FILTER_WR_TID 12
@@ -300,6 +314,12 @@ struct fw_filter_wr {
#define S_FW_FILTER_WR_MATCHTYPEM 0
#define V_FW_FILTER_WR_MATCHTYPEM(x) ((x) << S_FW_FILTER_WR_MATCHTYPEM)
+#define S_FW_FILTER2_WR_NATMODE 5
+#define V_FW_FILTER2_WR_NATMODE(x) ((x) << S_FW_FILTER2_WR_NATMODE)
+
+#define S_FW_FILTER2_WR_ULP_TYPE 0
+#define V_FW_FILTER2_WR_ULP_TYPE(x) ((x) << S_FW_FILTER2_WR_ULP_TYPE)
+
/******************************************************************************
* C O M M A N D s
*********************/
@@ -655,6 +675,7 @@ enum fw_params_param_dev {
FW_PARAMS_PARAM_DEV_FWREV = 0x0B, /* fw version */
FW_PARAMS_PARAM_DEV_TPREV = 0x0C, /* tp version */
FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
+ FW_PARAMS_PARAM_DEV_FILTER2_WR = 0x1D,
};
/*
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index dcb1dd03e..b876abf43 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -89,6 +89,9 @@ int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
if (fs->val.iport >= adapter->params.nports)
return -ERANGE;
+ if (!fs->cap && fs->nat_mode && !adapter->params.filter2_wr_support)
+ return -EOPNOTSUPP;
+
return 0;
}
@@ -627,6 +630,7 @@ void clear_filter(struct filter_entry *f)
/**
* t4_mk_filtdelwr - create a delete filter WR
+ * @adap: adapter context
* @ftid: the filter ID
* @wr: the filter work request to populate
* @qid: ingress queue to receive the delete notification
@@ -634,10 +638,14 @@ void clear_filter(struct filter_entry *f)
* Creates a filter work request to delete the supplied filter. If @qid is
* negative the delete notification is suppressed.
*/
-static void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid)
+static void t4_mk_filtdelwr(struct adapter *adap, unsigned int ftid,
+ struct fw_filter2_wr *wr, int qid)
{
memset(wr, 0, sizeof(*wr));
- wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+ if (adap->params.filter2_wr_support)
+ wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+ else
+ wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
wr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*wr) / 16));
wr->tid_to_iq = cpu_to_be32(V_FW_FILTER_WR_TID(ftid) |
V_FW_FILTER_WR_NOREPLY(qid < 0));
@@ -655,7 +663,7 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
struct adapter *adapter = ethdev2adap(dev);
struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
struct rte_mbuf *mbuf;
- struct fw_filter_wr *fwr;
+ struct fw_filter2_wr *fwr;
struct sge_ctrl_txq *ctrlq;
unsigned int port_id = ethdev2pinfo(dev)->port_id;
@@ -667,8 +675,8 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
mbuf->data_len = sizeof(*fwr);
mbuf->pkt_len = mbuf->data_len;
- fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
- t4_mk_filtdelwr(f->tid, fwr, adapter->sge.fw_evtq.abs_id);
+ fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
+ t4_mk_filtdelwr(adapter, f->tid, fwr, adapter->sge.fw_evtq.abs_id);
/*
* Mark the filter as "pending" and ship off the Filter Work Request.
@@ -684,7 +692,7 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
struct adapter *adapter = ethdev2adap(dev);
struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
struct rte_mbuf *mbuf;
- struct fw_filter_wr *fwr;
+ struct fw_filter2_wr *fwr;
struct sge_ctrl_txq *ctrlq;
unsigned int port_id = ethdev2pinfo(dev)->port_id;
int ret;
@@ -712,13 +720,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
mbuf->data_len = sizeof(*fwr);
mbuf->pkt_len = mbuf->data_len;
- fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
+ fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
memset(fwr, 0, sizeof(*fwr));
/*
* Construct the work request to set the filter.
*/
- fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+ if (adapter->params.filter2_wr_support)
+ fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+ else
+ fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
fwr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*fwr) / 16));
fwr->tid_to_iq =
cpu_to_be32(V_FW_FILTER_WR_TID(f->tid) |
@@ -762,6 +773,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
fwr->fp = cpu_to_be16(f->fs.val.fport);
fwr->fpm = cpu_to_be16(f->fs.mask.fport);
+ if (adapter->params.filter2_wr_support && f->fs.nat_mode) {
+ fwr->natmode_to_ulp_type =
+ V_FW_FILTER2_WR_ULP_TYPE(ULP_MODE_TCPDDP) |
+ V_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);
+ memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
+ memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
+ fwr->newlport = cpu_to_be16(f->fs.nat_lport);
+ fwr->newfport = cpu_to_be16(f->fs.nat_fport);
+ }
+
/*
* Mark the filter as "pending" and ship off the Filter Work Request.
* When we get the Work Request Reply we'll clear the pending status.
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 83d647de6..950fa0bca 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -104,6 +104,18 @@ struct ch_filter_specification {
uint8_t dmac[ETHER_ADDR_LEN]; /* new destination MAC address */
uint16_t vlan; /* VLAN Tag to insert */
+ /*
+ * Switch proxy/rewrite fields. An ingress packet which matches a
+ * filter with "switch" set will be looped back out as an egress
+ * packet -- potentially with some header rewriting.
+ */
+ uint32_t nat_mode:3; /* specify NAT operation mode */
+
+ uint8_t nat_lip[16]; /* local IP to use after NAT'ing */
+ uint8_t nat_fip[16]; /* foreign IP to use after NAT'ing */
+ uint16_t nat_lport; /* local port number to use after NAT'ing */
+ uint16_t nat_fport; /* foreign port number to use after NAT'ing */
+
/* Filter rule value/mask pairs. */
struct ch_filter_tuple val;
struct ch_filter_tuple mask;
@@ -121,6 +133,17 @@ enum {
VLAN_REWRITE
};
+enum {
+ NAT_MODE_NONE = 0, /* No NAT performed */
+ NAT_MODE_DIP, /* NAT on Dst IP */
+ NAT_MODE_DIP_DP, /* NAT on Dst IP, Dst Port */
+ NAT_MODE_DIP_DP_SIP, /* NAT on Dst IP, Dst Port and Src IP */
+ NAT_MODE_DIP_DP_SP, /* NAT on Dst IP, Dst Port and Src Port */
+ NAT_MODE_SIP_SP, /* NAT on Src IP and Src Port */
+ NAT_MODE_DIP_SIP_SP, /* NAT on Dst IP, Src IP and Src Port */
+ NAT_MODE_ALL /* NAT on entire 4-tuple */
+};
+
enum filter_type {
FILTER_TYPE_IPV4 = 0,
FILTER_TYPE_IPV6,
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index bee3bd640..52cb3bdf4 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -368,14 +368,77 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)
return 0;
}
+static int
+cxgbe_get_flow_item_index(const struct rte_flow_item items[], u32 type)
+{
+ const struct rte_flow_item *i;
+ int j, index = -ENOENT;
+
+ for (i = items, j = 0; i->type != RTE_FLOW_ITEM_TYPE_END; i++, j++) {
+ if (i->type == type) {
+ index = j;
+ break;
+ }
+ }
+
+ return index;
+}
+
+static int
+ch_rte_parse_nat(uint8_t nmode, struct ch_filter_specification *fs)
+{
+ /* nmode:
+ * BIT_0 = [src_ip], BIT_1 = [dst_ip]
+ * BIT_2 = [src_port], BIT_3 = [dst_port]
+ *
+ * Only below cases are supported as per our spec.
+ */
+ switch (nmode) {
+ case 0: /* 0000b */
+ fs->nat_mode = NAT_MODE_NONE;
+ break;
+ case 2: /* 0010b */
+ fs->nat_mode = NAT_MODE_DIP;
+ break;
+ case 5: /* 0101b */
+ fs->nat_mode = NAT_MODE_SIP_SP;
+ break;
+ case 7: /* 0111b */
+ fs->nat_mode = NAT_MODE_DIP_SIP_SP;
+ break;
+ case 10: /* 1010b */
+ fs->nat_mode = NAT_MODE_DIP_DP;
+ break;
+ case 11: /* 1011b */
+ fs->nat_mode = NAT_MODE_DIP_DP_SIP;
+ break;
+ case 14: /* 1110b */
+ fs->nat_mode = NAT_MODE_DIP_DP_SP;
+ break;
+ case 15: /* 1111b */
+ fs->nat_mode = NAT_MODE_ALL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int
ch_rte_parse_atype_switch(const struct rte_flow_action *a,
+ const struct rte_flow_item items[],
+ uint8_t *nmode,
struct ch_filter_specification *fs,
struct rte_flow_error *e)
{
const struct rte_flow_action_of_set_vlan_vid *vlanid;
const struct rte_flow_action_of_push_vlan *pushvlan;
+ const struct rte_flow_action_set_ipv4 *ipv4;
+ const struct rte_flow_action_set_ipv6 *ipv6;
+ const struct rte_flow_action_set_tp *tp_port;
const struct rte_flow_action_phy_port *port;
+ int item_index;
switch (a->type) {
case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
@@ -401,6 +464,94 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
port = (const struct rte_flow_action_phy_port *)a->conf;
fs->eport = port->index;
break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV4);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV4 "
+ "found.");
+
+ ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+ memcpy(fs->nat_fip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+ *nmode |= 1 << 0;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV4);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV4 "
+ "found.");
+
+ ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+ memcpy(fs->nat_lip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+ *nmode |= 1 << 1;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV6);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV6 "
+ "found.");
+
+ ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+ memcpy(fs->nat_fip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+ *nmode |= 1 << 0;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV6);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV6 "
+ "found.");
+
+ ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+ memcpy(fs->nat_lip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+ *nmode |= 1 << 1;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_TCP);
+ if (item_index < 0) {
+ item_index =
+ cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_UDP);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_TCP or "
+ "RTE_FLOW_ITEM_TYPE_UDP found");
+ }
+
+ tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+ fs->nat_fport = be16_to_cpu(tp_port->port);
+ *nmode |= 1 << 2;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_TCP);
+ if (item_index < 0) {
+ item_index =
+ cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_UDP);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_TCP or "
+ "RTE_FLOW_ITEM_TYPE_UDP found");
+ }
+
+ tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+ fs->nat_lport = be16_to_cpu(tp_port->port);
+ *nmode |= 1 << 3;
+ break;
default:
/* We are not supposed to come here */
return rte_flow_error_set(e, EINVAL,
@@ -413,10 +564,12 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
static int
cxgbe_rtef_parse_actions(struct rte_flow *flow,
+ const struct rte_flow_item items[],
const struct rte_flow_action action[],
struct rte_flow_error *e)
{
struct ch_filter_specification *fs = &flow->fs;
+ uint8_t nmode = 0, nat_ipv4 = 0, nat_ipv6 = 0;
const struct rte_flow_action_queue *q;
const struct rte_flow_action *a;
char abit = 0;
@@ -458,6 +611,16 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
case RTE_FLOW_ACTION_TYPE_PHY_PORT:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+ nat_ipv4++;
+ goto action_switch;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+ nat_ipv6++;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+action_switch:
/* We allow multiple switch actions, but switch is
* not compatible with either queue or drop
*/
@@ -465,7 +628,14 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
return rte_flow_error_set(e, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, a,
"overlapping action specified");
- ret = ch_rte_parse_atype_switch(a, fs, e);
+ if (nat_ipv4 && nat_ipv6)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "Can't have one address ipv4 and the"
+ " other ipv6");
+
+ ret = ch_rte_parse_atype_switch(a, items, &nmode, fs,
+ e);
if (ret)
return ret;
fs->action = FILTER_SWITCH;
@@ -478,6 +648,10 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
}
}
+ if (ch_rte_parse_nat(nmode, fs))
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "invalid settings for swich action");
return 0;
}
@@ -586,7 +760,7 @@ cxgbe_flow_parse(struct rte_flow *flow,
ret = cxgbe_rtef_parse_items(flow, item, e);
if (ret)
return ret;
- return cxgbe_rtef_parse_actions(flow, action, e);
+ return cxgbe_rtef_parse_actions(flow, item, action, e);
}
static int __cxgbe_flow_create(struct rte_eth_dev *dev, struct rte_flow *flow)
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 9c40f51b2..a135df9c7 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -1180,6 +1180,16 @@ static int adap_init0(struct adapter *adap)
goto bye;
}
+ /* See if FW supports FW_FILTER2 work request */
+ if (is_t4(adap->params.chip)) {
+ adap->params.filter2_wr_support = 0;
+ } else {
+ params[0] = FW_PARAM_DEV(FILTER2_WR);
+ ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 1, params, val);
+ adap->params.filter2_wr_support = (ret == 0 && val[0] != 0);
+ }
+
/* query tid-related parameters */
params[0] = FW_PARAM_DEV(NTID);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
2018-09-24 8:28 [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
` (2 preceding siblings ...)
2018-09-24 8:28 ` [dpdk-dev] [PATCH 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
@ 2018-10-03 20:33 ` Thomas Monjalon
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 " Rahul Lakkireddy
4 siblings, 0 replies; 22+ messages in thread
From: Thomas Monjalon @ 2018-10-03 20:33 UTC (permalink / raw)
To: ferruh.yigit
Cc: dev, Rahul Lakkireddy, indranil, nirranjan, adrien.mazarguil, arybchenko
24/09/2018 10:28, Rahul Lakkireddy:
> Rahul Lakkireddy (3):
> ethdev: add flow api actions to modify IP addresses
> ethdev: add flow api actions to modify TCP/UDP port numbers
> net/cxgbe: add flow actions to modify IP and TCP/UDP port address
If no more comment, I think we should accept this series.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v2 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
2018-09-24 8:28 [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
` (3 preceding siblings ...)
2018-10-03 20:33 ` [dpdk-dev] [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Thomas Monjalon
@ 2018-10-06 15:41 ` Rahul Lakkireddy
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
` (3 more replies)
4 siblings, 4 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-06 15:41 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
This series of patches add support for actions:
- SET_IPV4_SRC - set a new IPv4 source address.
- SET_IPV4_DST - set a new IPv4 destination address.
- SET_IPV6_SRC - set a new IPv6 source address.
- SET_IPV6_DST - set a new IPv6 destination address.
- SET_TP_SRC - set a new TCP/UDP source port number.
- SET_TP_DST - set a new TCP/UDP destination port number.
These actions are useful in Network Address Translation use case
to edit IP address and TCP/UDP port numbers before switching
the packets out to the destination device port.
Patch 1 adds support for IP address rewrite to rte_flow and testpmd.
Patch 2 adds support for TCP/UDP port rewrite to rte_flow and testpmd.
Patch 3 shows CXGBE PMD example to offload these actions to hardware.
Feedback and suggestions will be much appreciated.
Thanks,
Rahul
RFC v1: http://mails.dpdk.org/archives/dev/2018-June/104913.html
RFC v2: http://mails.dpdk.org/archives/dev/2018-August/109672.html
---
v2:
- Rebased to tip.
- Removed adding actions to app/test-pmd/config.c, to sync with
rte_flow_conv() changes.
v1 changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
actions.
- Re-based CXGBE PMD changes in patch 3 to tip.
- Updated all instances of fw_filter_wr to new fw_filter2_wr and removed
fw_filter_wr.
- Ensure correct ULP type is set when offloading NAT actions.
- Returning appropriate RTE_FLOW_ERROR_TYPE_ACTION error if a corresponding
valid flow pattern item is not found.
- Updated release notes.
Rahul Lakkireddy (3):
ethdev: add flow api actions to modify IP addresses
ethdev: add flow api actions to modify TCP/UDP port numbers
net/cxgbe: add flow actions to modify IP and TCP/UDP port address
app/test-pmd/cmdline_flow.c | 156 +++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 108 ++++++++++++
doc/guides/rel_notes/release_18_11.rst | 13 +-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 28 +++
drivers/net/cxgbe/base/common.h | 1 +
drivers/net/cxgbe/base/t4_msg.h | 1 +
drivers/net/cxgbe/base/t4fw_interface.h | 23 ++-
drivers/net/cxgbe/cxgbe_filter.c | 37 +++-
drivers/net/cxgbe/cxgbe_filter.h | 23 +++
drivers/net/cxgbe/cxgbe_flow.c | 178 +++++++++++++++++++-
drivers/net/cxgbe/cxgbe_main.c | 10 ++
lib/librte_ethdev/rte_flow.c | 12 ++
lib/librte_ethdev/rte_flow.h | 107 ++++++++++++
13 files changed, 685 insertions(+), 12 deletions(-)
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 " Rahul Lakkireddy
@ 2018-10-06 15:41 ` Rahul Lakkireddy
2018-10-08 9:22 ` Andrew Rybchenko
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
` (2 subsequent siblings)
3 siblings, 1 reply; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-06 15:41 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Add actions:
- SET_IPV4_SRC - set a new IPv4 source address.
- SET_IPV4_DST - set a new IPv4 destination address.
- SET_IPV6_SRC - set a new IPv6 source address.
- SET_IPV6_DST - set a new IPv6 destination address.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Acked-by: Xiaoyu Min <jackmin@mellanox.com>
---
v2:
- Rebased to tip.
- Removed adding actions to app/test-pmd/config.c, to sync with
rte_flow_conv() changes.
v1 changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
action.
- Updated release notes.
app/test-pmd/cmdline_flow.c | 104 ++++++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 72 ++++++++++++++
doc/guides/rel_notes/release_18_11.rst | 7 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 18 ++++
lib/librte_ethdev/rte_flow.c | 8 ++
lib/librte_ethdev/rte_flow.h | 70 +++++++++++++
6 files changed, 279 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f9260600e..1432498a3 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -243,6 +243,14 @@ enum index {
ACTION_VXLAN_DECAP,
ACTION_NVGRE_ENCAP,
ACTION_NVGRE_DECAP,
+ ACTION_SET_IPV4_SRC,
+ ACTION_SET_IPV4_SRC_IPV4_SRC,
+ ACTION_SET_IPV4_DST,
+ ACTION_SET_IPV4_DST_IPV4_DST,
+ ACTION_SET_IPV6_SRC,
+ ACTION_SET_IPV6_SRC_IPV6_SRC,
+ ACTION_SET_IPV6_DST,
+ ACTION_SET_IPV6_DST_IPV6_DST,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -816,6 +824,10 @@ static const enum index next_action[] = {
ACTION_VXLAN_DECAP,
ACTION_NVGRE_ENCAP,
ACTION_NVGRE_DECAP,
+ ACTION_SET_IPV4_SRC,
+ ACTION_SET_IPV4_DST,
+ ACTION_SET_IPV6_SRC,
+ ACTION_SET_IPV6_DST,
ZERO,
};
@@ -918,6 +930,30 @@ static const enum index action_of_push_mpls[] = {
ZERO,
};
+static const enum index action_set_ipv4_src[] = {
+ ACTION_SET_IPV4_SRC_IPV4_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv4_dst[] = {
+ ACTION_SET_IPV4_DST_IPV4_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_src[] = {
+ ACTION_SET_IPV6_SRC_IPV6_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_dst[] = {
+ ACTION_SET_IPV6_DST_IPV6_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_jump[] = {
ACTION_JUMP_GROUP,
ACTION_NEXT,
@@ -2470,6 +2506,74 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_SET_IPV4_SRC] = {
+ .name = "set_ipv4_src",
+ .help = "Set a new IPv4 source address in the outermost"
+ " IPv4 header",
+ .priv = PRIV_ACTION(SET_IPV4_SRC,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ .next = NEXT(action_set_ipv4_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_SRC_IPV4_SRC] = {
+ .name = "ipv4_addr",
+ .help = "new IPv4 source address to set",
+ .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(IPV4_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv4, ipv4_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV4_DST] = {
+ .name = "set_ipv4_dst",
+ .help = "Set a new IPv4 destination address in the outermost"
+ " IPv4 header",
+ .priv = PRIV_ACTION(SET_IPV4_DST,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ .next = NEXT(action_set_ipv4_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_DST_IPV4_DST] = {
+ .name = "ipv4_addr",
+ .help = "new IPv4 destination address to set",
+ .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(IPV4_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv4, ipv4_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_SRC] = {
+ .name = "set_ipv6_src",
+ .help = "Set a new IPv6 source address in the outermost"
+ " IPv6 header",
+ .priv = PRIV_ACTION(SET_IPV6_SRC,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ .next = NEXT(action_set_ipv6_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_SRC_IPV6_SRC] = {
+ .name = "ipv6_addr",
+ .help = "new IPv6 source address to set",
+ .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(IPV6_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv6, ipv6_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_DST] = {
+ .name = "set_ipv6_dst",
+ .help = "Set a new IPv6 destination address in the outermost"
+ " IPv6 header",
+ .priv = PRIV_ACTION(SET_IPV6_DST,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ .next = NEXT(action_set_ipv6_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_DST_IPV6_DST] = {
+ .name = "ipv6_addr",
+ .help = "new IPv6 destination address to set",
+ .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(IPV6_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv6, ipv6_addr)),
+ .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 1b17f6e01..9272cd710 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2076,6 +2076,78 @@ RTE_FLOW_ERROR_TYPE_ACTION error should be returned.
This action modifies the payload of matched flows.
+Action: ``SET_IPV4_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv4 source address in the outermost IPv4 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_src:
+
+.. table:: SET_IPV4_SRC
+
+ +-----------------------------------------+
+ | Field | Value |
+ +===============+=========================+
+ | ``ipv4_addr`` | new IPv4 source address |
+ +---------------+-------------------------+
+
+Action: ``SET_IPV4_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv4 destination address in the outermost IPv4 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_dst:
+
+.. table:: SET_IPV4_DST
+
+ +---------------+------------------------------+
+ | Field | Value |
+ +===============+==============================+
+ | ``ipv4_addr`` | new IPv4 destination address |
+ +---------------+------------------------------+
+
+Action: ``SET_IPV6_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv6 source address in the outermost IPv6 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_src:
+
+.. table:: SET_IPV6_SRC
+
+ +---------------+-------------------------+
+ | Field | Value |
+ +===============+=========================+
+ | ``ipv6_addr`` | new IPv6 source address |
+ +---------------+-------------------------+
+
+Action: ``SET_IPV6_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv6 destination address in the outermost IPv6 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_dst:
+
+.. table:: SET_IPV6_DST
+
+ +---------------+------------------------------+
+ | Field | Value |
+ +===============+==============================+
+ | ``ipv6_addr`` | new IPv6 destination address |
+ +---------------+------------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 89ca3317f..12b99de37 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -130,6 +130,13 @@ New Features
this application doesn't need to launch dedicated worker threads for vhost
enqueue/dequeue operations.
+* **Added new Flow API actions to rewrite fields in packet headers.**
+
+ Added new Flow API actions to:
+
+ * Modify source and destination IP addresses in the outermost IPv4/IPv6
+ headers.
+
API Changes
-----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 3a73000a6..97d91f066 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3704,6 +3704,24 @@ This section lists supported actions and their attributes, if any.
- ``nvgre_decap``: Performs a decapsulation action by stripping all headers of
the NVGRE tunnel network overlay from the matched flow.
+- ``set_ipv4_src``: Set a new IPv4 source address in the outermost IPv4 header.
+
+ - ``ipv4_addr``: New IPv4 source address.
+
+- ``set_ipv4_dst``: Set a new IPv4 destination address in the outermost IPv4
+ header.
+
+ - ``ipv4_addr``: New IPv4 destination address.
+
+- ``set_ipv6_src``: Set a new IPv6 source address in the outermost IPv6 header.
+
+ - ``ipv6_addr``: New IPv6 source address.
+
+- ``set_ipv6_dst``: Set a new IPv6 destination address in the outermost IPv6
+ header.
+
+ - ``ipv6_addr``: New IPv6 destination address.
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 9c56a9734..9440b63a9 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -123,6 +123,14 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
MK_FLOW_ACTION(VXLAN_DECAP, 0),
MK_FLOW_ACTION(NVGRE_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
MK_FLOW_ACTION(NVGRE_DECAP, 0),
+ MK_FLOW_ACTION(SET_IPV4_SRC,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV4_DST,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV6_SRC,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_IPV6_DST,
+ sizeof(struct rte_flow_action_set_ipv6)),
};
static int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index f062ffead..81fa73442 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -1506,6 +1506,46 @@ enum rte_flow_action_type {
* error.
*/
RTE_FLOW_ACTION_TYPE_NVGRE_DECAP,
+
+ /**
+ * Modify IPv4 source address in the outermost IPv4 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_ipv4.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC,
+
+ /**
+ * Modify IPv4 destination address in the outermost IPv4 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_ipv4.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_DST,
+
+ /**
+ * Modify IPv6 source address in the outermost IPv6 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_ipv6.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC,
+
+ /**
+ * Modify IPv6 destination address in the outermost IPv6 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_ipv6.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
};
/**
@@ -1869,6 +1909,36 @@ struct rte_flow_action_nvgre_encap {
struct rte_flow_item *definition;
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+ *
+ * Allows modification of IPv4 source (RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC)
+ * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV4_DST) in the
+ * specified outermost IPv4 header.
+ */
+struct rte_flow_action_set_ipv4 {
+ uint32_t ipv4_addr;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+ *
+ * Allows modification of IPv6 source (RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC)
+ * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV6_DST) in the
+ * specified outermost IPv6 header.
+ */
+struct rte_flow_action_set_ipv6 {
+ uint8_t ipv6_addr[16];
+};
+
/*
* Definition of a single action.
*
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
@ 2018-10-08 9:22 ` Andrew Rybchenko
0 siblings, 0 replies; 22+ messages in thread
From: Andrew Rybchenko @ 2018-10-08 9:22 UTC (permalink / raw)
To: Rahul Lakkireddy, dev; +Cc: indranil, nirranjan
On 10/6/18 6:41 PM, Rahul Lakkireddy wrote:
> Add actions:
> - SET_IPV4_SRC - set a new IPv4 source address.
> - SET_IPV4_DST - set a new IPv4 destination address.
> - SET_IPV6_SRC - set a new IPv6 source address.
> - SET_IPV6_DST - set a new IPv6 destination address.
>
> Original work by Shagun Agrawal
>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> Acked-by: Xiaoyu Min <jackmin@mellanox.com>
One nit below, otherwise,
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
<...>
> @@ -1869,6 +1909,36 @@ struct rte_flow_action_nvgre_encap {
> struct rte_flow_item *definition;
> };
>
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
> + * RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
> + *
> + * Allows modification of IPv4 source (RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC)
> + * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV4_DST) in the
> + * specified outermost IPv4 header.
> + */
> +struct rte_flow_action_set_ipv4 {
> + uint32_t ipv4_addr;
I think rte_be32_t should be used. here to highlight byte order.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 " Rahul Lakkireddy
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
@ 2018-10-06 15:41 ` Rahul Lakkireddy
2018-10-08 9:24 ` Andrew Rybchenko
2018-10-06 15:42 ` [dpdk-dev] [PATCH v2 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
3 siblings, 1 reply; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-06 15:41 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Add actions:
- SET_TP_SRC - set a new TCP/UDP source port number.
- SET_TP_DST - set a new TCP/UDP destination port number.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Acked-by: Xiaoyu Min <jackmin@mellanox.com>
Acked-by: Ori Kam <orika@mellanox.com>
---
v2:
- Rebased to tip.
- Removed adding actions to app/test-pmd/config.c, to sync with
rte_flow_conv() changes.
v1 changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
action.
- Updated release notes.
app/test-pmd/cmdline_flow.c | 52 +++++++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 36 ++++++++++++++
doc/guides/rel_notes/release_18_11.rst | 2 +
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++++
lib/librte_ethdev/rte_flow.c | 4 ++
lib/librte_ethdev/rte_flow.h | 37 +++++++++++++++
6 files changed, 141 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 1432498a3..a9888cacf 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -251,6 +251,10 @@ enum index {
ACTION_SET_IPV6_SRC_IPV6_SRC,
ACTION_SET_IPV6_DST,
ACTION_SET_IPV6_DST_IPV6_DST,
+ ACTION_SET_TP_SRC,
+ ACTION_SET_TP_SRC_TP_SRC,
+ ACTION_SET_TP_DST,
+ ACTION_SET_TP_DST_TP_DST,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -828,6 +832,8 @@ static const enum index next_action[] = {
ACTION_SET_IPV4_DST,
ACTION_SET_IPV6_SRC,
ACTION_SET_IPV6_DST,
+ ACTION_SET_TP_SRC,
+ ACTION_SET_TP_DST,
ZERO,
};
@@ -954,6 +960,18 @@ static const enum index action_set_ipv6_dst[] = {
ZERO,
};
+static const enum index action_set_tp_src[] = {
+ ACTION_SET_TP_SRC_TP_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_tp_dst[] = {
+ ACTION_SET_TP_DST_TP_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_jump[] = {
ACTION_JUMP_GROUP,
ACTION_NEXT,
@@ -2574,6 +2592,40 @@ static const struct token token_list[] = {
(struct rte_flow_action_set_ipv6, ipv6_addr)),
.call = parse_vc_conf,
},
+ [ACTION_SET_TP_SRC] = {
+ .name = "set_tp_src",
+ .help = "set a new source port number in the outermost"
+ " TCP/UDP header",
+ .priv = PRIV_ACTION(SET_TP_SRC,
+ sizeof(struct rte_flow_action_set_tp)),
+ .next = NEXT(action_set_tp_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_TP_SRC_TP_SRC] = {
+ .name = "port",
+ .help = "new source port number to set",
+ .next = NEXT(action_set_tp_src, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_tp, port)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_TP_DST] = {
+ .name = "set_tp_dst",
+ .help = "set a new destination port number in the outermost"
+ " TCP/UDP header",
+ .priv = PRIV_ACTION(SET_TP_DST,
+ sizeof(struct rte_flow_action_set_tp)),
+ .next = NEXT(action_set_tp_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_TP_DST_TP_DST] = {
+ .name = "port",
+ .help = "new destination port number to set",
+ .next = NEXT(action_set_tp_dst, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_tp, port)),
+ .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 9272cd710..1c81a824d 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2148,6 +2148,42 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
| ``ipv6_addr`` | new IPv6 destination address |
+---------------+------------------------------+
+Action: ``SET_TP_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new source port number in the outermost TCP/UDP header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
+flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_tp_src:
+
+.. table:: SET_TP_SRC
+
+ +----------+-------------------------+
+ | Field | Value |
+ +==========+=========================+
+ | ``port`` | new TCP/UDP source port |
+ +---------------+--------------------+
+
+Action: ``SET_TP_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new destination port number in the outermost TCP/UDP header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
+flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_tp_dst:
+
+.. table:: SET_TP_DST
+
+ +----------+------------------------------+
+ | Field | Value |
+ +==========+==============================+
+ | ``port`` | new TCP/UDP destination port |
+ +---------------+-------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 12b99de37..2b4808226 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -136,6 +136,8 @@ New Features
* Modify source and destination IP addresses in the outermost IPv4/IPv6
headers.
+ * Modify source and destination port numbers in the outermost TCP/UDP
+ headers.
API Changes
-----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 97d91f066..ffec7013b 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3722,6 +3722,16 @@ This section lists supported actions and their attributes, if any.
- ``ipv6_addr``: New IPv6 destination address.
+- ``of_set_tp_src``: Set a new source port number in the outermost TCP/UDP
+ header.
+
+ - ``port``: New TCP/UDP source port number.
+
+- ``of_set_tp_dst``: Set a new destination port number in the outermost TCP/UDP
+ header.
+
+ - ``port``: New TCP/UDP destination port number.
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 9440b63a9..4eeb392b6 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -131,6 +131,10 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
sizeof(struct rte_flow_action_set_ipv6)),
MK_FLOW_ACTION(SET_IPV6_DST,
sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_TP_SRC,
+ sizeof(struct rte_flow_action_set_tp)),
+ MK_FLOW_ACTION(SET_TP_DST,
+ sizeof(struct rte_flow_action_set_tp)),
};
static int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index 81fa73442..ce2021641 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -1546,6 +1546,28 @@ enum rte_flow_action_type {
* See struct rte_flow_action_set_ipv6.
*/
RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
+
+ /**
+ * Modify source port number in the outermost TCP/UDP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
+ * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
+ * RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_tp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_TP_SRC,
+
+ /**
+ * Modify destination port number in the outermost TCP/UDP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
+ * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
+ * RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_tp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_TP_DST,
};
/**
@@ -1939,6 +1961,21 @@ struct rte_flow_action_set_ipv6 {
uint8_t ipv6_addr[16];
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_TP_DST
+ *
+ * Allows modification of source (RTE_FLOW_ACTION_TYPE_SET_TP_SRC)
+ * and destination (RTE_FLOW_ACTION_TYPE_SET_TP_DST) port numbers
+ * in the specified outermost TCP/UDP header.
+ */
+struct rte_flow_action_set_tp {
+ uint16_t port;
+};
+
/*
* Definition of a single action.
*
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
@ 2018-10-08 9:24 ` Andrew Rybchenko
0 siblings, 0 replies; 22+ messages in thread
From: Andrew Rybchenko @ 2018-10-08 9:24 UTC (permalink / raw)
To: Rahul Lakkireddy, dev; +Cc: indranil, nirranjan
On 10/6/18 6:41 PM, Rahul Lakkireddy wrote:
> Add actions:
> - SET_TP_SRC - set a new TCP/UDP source port number.
> - SET_TP_DST - set a new TCP/UDP destination port number.
>
> Original work by Shagun Agrawal
>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> Acked-by: Xiaoyu Min <jackmin@mellanox.com>
> Acked-by: Ori Kam <orika@mellanox.com>
One nit below, otherwise
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
<...>
> @@ -1939,6 +1961,21 @@ struct rte_flow_action_set_ipv6 {
> uint8_t ipv6_addr[16];
> };
>
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ACTION_TYPE_SET_TP_SRC
> + * RTE_FLOW_ACTION_TYPE_SET_TP_DST
> + *
> + * Allows modification of source (RTE_FLOW_ACTION_TYPE_SET_TP_SRC)
> + * and destination (RTE_FLOW_ACTION_TYPE_SET_TP_DST) port numbers
> + * in the specified outermost TCP/UDP header.
> + */
> +struct rte_flow_action_set_tp {
> + uint16_t port;
rte_be16_t?
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v2 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 " Rahul Lakkireddy
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
@ 2018-10-06 15:42 ` Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
3 siblings, 0 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-06 15:42 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Query firmware for the new filter work request to offload flows with
actions to modify IP and TCP/UDP port addresses. When available,
translate IP and TCP/UDP port address modify actions to internal
hardware specification and offload the flow to hardware.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.
v1 changes since RFC v2:
- Re-based to tip.
- Updated all instances of fw_filter_wr to new fw_filter2_wr and removed
fw_filter_wr.
- Ensure correct ULP type is set when offloading NAT actions.
- Returning appropriate RTE_FLOW_ERROR_TYPE_ACTION error if a corresponding
valid flow pattern item for the header rewrite action is not found.
- Updated release notes.
doc/guides/rel_notes/release_18_11.rst | 4 +-
drivers/net/cxgbe/base/common.h | 1 +
drivers/net/cxgbe/base/t4_msg.h | 1 +
drivers/net/cxgbe/base/t4fw_interface.h | 23 ++-
drivers/net/cxgbe/cxgbe_filter.c | 37 +++--
drivers/net/cxgbe/cxgbe_filter.h | 23 +++
drivers/net/cxgbe/cxgbe_flow.c | 178 +++++++++++++++++++++++-
drivers/net/cxgbe/cxgbe_main.c | 10 ++
8 files changed, 265 insertions(+), 12 deletions(-)
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 2b4808226..9a135c89c 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -59,7 +59,9 @@ New Features
Flow API support has been enhanced for CXGBE Poll Mode Driver to offload:
* Match items: destination MAC address.
- * Action items: push/pop/rewrite vlan header.
+ * Action items: push/pop/rewrite vlan header, rewrite IP addresses in
+ outermost IPv4/IPv6 header, rewrite port numbers in outermost TCP/UDP
+ header.
* **Added a devarg to use the latest supported vector path in i40e.**
A new devarg ``use-latest-supported-vec`` was introduced to allow users to
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index d9f74d995..fd2006682 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -271,6 +271,7 @@ struct adapter_params {
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
u8 fw_caps_support; /* 32-bit Port Capabilities */
+ u8 filter2_wr_support; /* FW support for FILTER2_WR */
};
/* Firmware Port Capabilities types.
diff --git a/drivers/net/cxgbe/base/t4_msg.h b/drivers/net/cxgbe/base/t4_msg.h
index 2128da64f..6494f1827 100644
--- a/drivers/net/cxgbe/base/t4_msg.h
+++ b/drivers/net/cxgbe/base/t4_msg.h
@@ -32,6 +32,7 @@ enum CPL_error {
enum {
ULP_MODE_NONE = 0,
+ ULP_MODE_TCPDDP = 5,
};
enum {
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index e2d2ee897..b4c95c588 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -61,6 +61,7 @@ enum fw_wr_opcodes {
FW_ETH_TX_PKTS_WR = 0x09,
FW_ETH_TX_PKT_VM_WR = 0x11,
FW_ETH_TX_PKTS_VM_WR = 0x12,
+ FW_FILTER2_WR = 0x77,
FW_ETH_TX_PKTS2_WR = 0x78,
};
@@ -165,7 +166,7 @@ enum fw_filter_wr_cookie {
FW_FILTER_WR_EINVAL,
};
-struct fw_filter_wr {
+struct fw_filter2_wr {
__be32 op_pkd;
__be32 len16_pkd;
__be64 r3;
@@ -195,6 +196,19 @@ struct fw_filter_wr {
__be16 fpm;
__be16 r7;
__u8 sma[6];
+ __be16 r8;
+ __u8 filter_type_swapmac;
+ __u8 natmode_to_ulp_type;
+ __be16 newlport;
+ __be16 newfport;
+ __u8 newlip[16];
+ __u8 newfip[16];
+ __be32 natseqcheck;
+ __be32 r9;
+ __be64 r10;
+ __be64 r11;
+ __be64 r12;
+ __be64 r13;
};
#define S_FW_FILTER_WR_TID 12
@@ -300,6 +314,12 @@ struct fw_filter_wr {
#define S_FW_FILTER_WR_MATCHTYPEM 0
#define V_FW_FILTER_WR_MATCHTYPEM(x) ((x) << S_FW_FILTER_WR_MATCHTYPEM)
+#define S_FW_FILTER2_WR_NATMODE 5
+#define V_FW_FILTER2_WR_NATMODE(x) ((x) << S_FW_FILTER2_WR_NATMODE)
+
+#define S_FW_FILTER2_WR_ULP_TYPE 0
+#define V_FW_FILTER2_WR_ULP_TYPE(x) ((x) << S_FW_FILTER2_WR_ULP_TYPE)
+
/******************************************************************************
* C O M M A N D s
*********************/
@@ -655,6 +675,7 @@ enum fw_params_param_dev {
FW_PARAMS_PARAM_DEV_FWREV = 0x0B, /* fw version */
FW_PARAMS_PARAM_DEV_TPREV = 0x0C, /* tp version */
FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
+ FW_PARAMS_PARAM_DEV_FILTER2_WR = 0x1D,
};
/*
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index dcb1dd03e..b876abf43 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -89,6 +89,9 @@ int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
if (fs->val.iport >= adapter->params.nports)
return -ERANGE;
+ if (!fs->cap && fs->nat_mode && !adapter->params.filter2_wr_support)
+ return -EOPNOTSUPP;
+
return 0;
}
@@ -627,6 +630,7 @@ void clear_filter(struct filter_entry *f)
/**
* t4_mk_filtdelwr - create a delete filter WR
+ * @adap: adapter context
* @ftid: the filter ID
* @wr: the filter work request to populate
* @qid: ingress queue to receive the delete notification
@@ -634,10 +638,14 @@ void clear_filter(struct filter_entry *f)
* Creates a filter work request to delete the supplied filter. If @qid is
* negative the delete notification is suppressed.
*/
-static void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid)
+static void t4_mk_filtdelwr(struct adapter *adap, unsigned int ftid,
+ struct fw_filter2_wr *wr, int qid)
{
memset(wr, 0, sizeof(*wr));
- wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+ if (adap->params.filter2_wr_support)
+ wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+ else
+ wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
wr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*wr) / 16));
wr->tid_to_iq = cpu_to_be32(V_FW_FILTER_WR_TID(ftid) |
V_FW_FILTER_WR_NOREPLY(qid < 0));
@@ -655,7 +663,7 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
struct adapter *adapter = ethdev2adap(dev);
struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
struct rte_mbuf *mbuf;
- struct fw_filter_wr *fwr;
+ struct fw_filter2_wr *fwr;
struct sge_ctrl_txq *ctrlq;
unsigned int port_id = ethdev2pinfo(dev)->port_id;
@@ -667,8 +675,8 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
mbuf->data_len = sizeof(*fwr);
mbuf->pkt_len = mbuf->data_len;
- fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
- t4_mk_filtdelwr(f->tid, fwr, adapter->sge.fw_evtq.abs_id);
+ fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
+ t4_mk_filtdelwr(adapter, f->tid, fwr, adapter->sge.fw_evtq.abs_id);
/*
* Mark the filter as "pending" and ship off the Filter Work Request.
@@ -684,7 +692,7 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
struct adapter *adapter = ethdev2adap(dev);
struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
struct rte_mbuf *mbuf;
- struct fw_filter_wr *fwr;
+ struct fw_filter2_wr *fwr;
struct sge_ctrl_txq *ctrlq;
unsigned int port_id = ethdev2pinfo(dev)->port_id;
int ret;
@@ -712,13 +720,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
mbuf->data_len = sizeof(*fwr);
mbuf->pkt_len = mbuf->data_len;
- fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
+ fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
memset(fwr, 0, sizeof(*fwr));
/*
* Construct the work request to set the filter.
*/
- fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+ if (adapter->params.filter2_wr_support)
+ fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+ else
+ fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
fwr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*fwr) / 16));
fwr->tid_to_iq =
cpu_to_be32(V_FW_FILTER_WR_TID(f->tid) |
@@ -762,6 +773,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
fwr->fp = cpu_to_be16(f->fs.val.fport);
fwr->fpm = cpu_to_be16(f->fs.mask.fport);
+ if (adapter->params.filter2_wr_support && f->fs.nat_mode) {
+ fwr->natmode_to_ulp_type =
+ V_FW_FILTER2_WR_ULP_TYPE(ULP_MODE_TCPDDP) |
+ V_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);
+ memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
+ memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
+ fwr->newlport = cpu_to_be16(f->fs.nat_lport);
+ fwr->newfport = cpu_to_be16(f->fs.nat_fport);
+ }
+
/*
* Mark the filter as "pending" and ship off the Filter Work Request.
* When we get the Work Request Reply we'll clear the pending status.
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 83d647de6..950fa0bca 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -104,6 +104,18 @@ struct ch_filter_specification {
uint8_t dmac[ETHER_ADDR_LEN]; /* new destination MAC address */
uint16_t vlan; /* VLAN Tag to insert */
+ /*
+ * Switch proxy/rewrite fields. An ingress packet which matches a
+ * filter with "switch" set will be looped back out as an egress
+ * packet -- potentially with some header rewriting.
+ */
+ uint32_t nat_mode:3; /* specify NAT operation mode */
+
+ uint8_t nat_lip[16]; /* local IP to use after NAT'ing */
+ uint8_t nat_fip[16]; /* foreign IP to use after NAT'ing */
+ uint16_t nat_lport; /* local port number to use after NAT'ing */
+ uint16_t nat_fport; /* foreign port number to use after NAT'ing */
+
/* Filter rule value/mask pairs. */
struct ch_filter_tuple val;
struct ch_filter_tuple mask;
@@ -121,6 +133,17 @@ enum {
VLAN_REWRITE
};
+enum {
+ NAT_MODE_NONE = 0, /* No NAT performed */
+ NAT_MODE_DIP, /* NAT on Dst IP */
+ NAT_MODE_DIP_DP, /* NAT on Dst IP, Dst Port */
+ NAT_MODE_DIP_DP_SIP, /* NAT on Dst IP, Dst Port and Src IP */
+ NAT_MODE_DIP_DP_SP, /* NAT on Dst IP, Dst Port and Src Port */
+ NAT_MODE_SIP_SP, /* NAT on Src IP and Src Port */
+ NAT_MODE_DIP_SIP_SP, /* NAT on Dst IP, Src IP and Src Port */
+ NAT_MODE_ALL /* NAT on entire 4-tuple */
+};
+
enum filter_type {
FILTER_TYPE_IPV4 = 0,
FILTER_TYPE_IPV6,
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index bee3bd640..52cb3bdf4 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -368,14 +368,77 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)
return 0;
}
+static int
+cxgbe_get_flow_item_index(const struct rte_flow_item items[], u32 type)
+{
+ const struct rte_flow_item *i;
+ int j, index = -ENOENT;
+
+ for (i = items, j = 0; i->type != RTE_FLOW_ITEM_TYPE_END; i++, j++) {
+ if (i->type == type) {
+ index = j;
+ break;
+ }
+ }
+
+ return index;
+}
+
+static int
+ch_rte_parse_nat(uint8_t nmode, struct ch_filter_specification *fs)
+{
+ /* nmode:
+ * BIT_0 = [src_ip], BIT_1 = [dst_ip]
+ * BIT_2 = [src_port], BIT_3 = [dst_port]
+ *
+ * Only below cases are supported as per our spec.
+ */
+ switch (nmode) {
+ case 0: /* 0000b */
+ fs->nat_mode = NAT_MODE_NONE;
+ break;
+ case 2: /* 0010b */
+ fs->nat_mode = NAT_MODE_DIP;
+ break;
+ case 5: /* 0101b */
+ fs->nat_mode = NAT_MODE_SIP_SP;
+ break;
+ case 7: /* 0111b */
+ fs->nat_mode = NAT_MODE_DIP_SIP_SP;
+ break;
+ case 10: /* 1010b */
+ fs->nat_mode = NAT_MODE_DIP_DP;
+ break;
+ case 11: /* 1011b */
+ fs->nat_mode = NAT_MODE_DIP_DP_SIP;
+ break;
+ case 14: /* 1110b */
+ fs->nat_mode = NAT_MODE_DIP_DP_SP;
+ break;
+ case 15: /* 1111b */
+ fs->nat_mode = NAT_MODE_ALL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int
ch_rte_parse_atype_switch(const struct rte_flow_action *a,
+ const struct rte_flow_item items[],
+ uint8_t *nmode,
struct ch_filter_specification *fs,
struct rte_flow_error *e)
{
const struct rte_flow_action_of_set_vlan_vid *vlanid;
const struct rte_flow_action_of_push_vlan *pushvlan;
+ const struct rte_flow_action_set_ipv4 *ipv4;
+ const struct rte_flow_action_set_ipv6 *ipv6;
+ const struct rte_flow_action_set_tp *tp_port;
const struct rte_flow_action_phy_port *port;
+ int item_index;
switch (a->type) {
case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
@@ -401,6 +464,94 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
port = (const struct rte_flow_action_phy_port *)a->conf;
fs->eport = port->index;
break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV4);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV4 "
+ "found.");
+
+ ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+ memcpy(fs->nat_fip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+ *nmode |= 1 << 0;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV4);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV4 "
+ "found.");
+
+ ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+ memcpy(fs->nat_lip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+ *nmode |= 1 << 1;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV6);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV6 "
+ "found.");
+
+ ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+ memcpy(fs->nat_fip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+ *nmode |= 1 << 0;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV6);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV6 "
+ "found.");
+
+ ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+ memcpy(fs->nat_lip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+ *nmode |= 1 << 1;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_TCP);
+ if (item_index < 0) {
+ item_index =
+ cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_UDP);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_TCP or "
+ "RTE_FLOW_ITEM_TYPE_UDP found");
+ }
+
+ tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+ fs->nat_fport = be16_to_cpu(tp_port->port);
+ *nmode |= 1 << 2;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_TCP);
+ if (item_index < 0) {
+ item_index =
+ cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_UDP);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_TCP or "
+ "RTE_FLOW_ITEM_TYPE_UDP found");
+ }
+
+ tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+ fs->nat_lport = be16_to_cpu(tp_port->port);
+ *nmode |= 1 << 3;
+ break;
default:
/* We are not supposed to come here */
return rte_flow_error_set(e, EINVAL,
@@ -413,10 +564,12 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
static int
cxgbe_rtef_parse_actions(struct rte_flow *flow,
+ const struct rte_flow_item items[],
const struct rte_flow_action action[],
struct rte_flow_error *e)
{
struct ch_filter_specification *fs = &flow->fs;
+ uint8_t nmode = 0, nat_ipv4 = 0, nat_ipv6 = 0;
const struct rte_flow_action_queue *q;
const struct rte_flow_action *a;
char abit = 0;
@@ -458,6 +611,16 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
case RTE_FLOW_ACTION_TYPE_PHY_PORT:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+ nat_ipv4++;
+ goto action_switch;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+ nat_ipv6++;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+action_switch:
/* We allow multiple switch actions, but switch is
* not compatible with either queue or drop
*/
@@ -465,7 +628,14 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
return rte_flow_error_set(e, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, a,
"overlapping action specified");
- ret = ch_rte_parse_atype_switch(a, fs, e);
+ if (nat_ipv4 && nat_ipv6)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "Can't have one address ipv4 and the"
+ " other ipv6");
+
+ ret = ch_rte_parse_atype_switch(a, items, &nmode, fs,
+ e);
if (ret)
return ret;
fs->action = FILTER_SWITCH;
@@ -478,6 +648,10 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
}
}
+ if (ch_rte_parse_nat(nmode, fs))
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "invalid settings for swich action");
return 0;
}
@@ -586,7 +760,7 @@ cxgbe_flow_parse(struct rte_flow *flow,
ret = cxgbe_rtef_parse_items(flow, item, e);
if (ret)
return ret;
- return cxgbe_rtef_parse_actions(flow, action, e);
+ return cxgbe_rtef_parse_actions(flow, item, action, e);
}
static int __cxgbe_flow_create(struct rte_eth_dev *dev, struct rte_flow *flow)
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 9c40f51b2..a135df9c7 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -1180,6 +1180,16 @@ static int adap_init0(struct adapter *adap)
goto bye;
}
+ /* See if FW supports FW_FILTER2 work request */
+ if (is_t4(adap->params.chip)) {
+ adap->params.filter2_wr_support = 0;
+ } else {
+ params[0] = FW_PARAM_DEV(FILTER2_WR);
+ ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 1, params, val);
+ adap->params.filter2_wr_support = (ret == 0 && val[0] != 0);
+ }
+
/* query tid-related parameters */
params[0] = FW_PARAM_DEV(NTID);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
2018-10-06 15:41 ` [dpdk-dev] [PATCH v2 " Rahul Lakkireddy
` (2 preceding siblings ...)
2018-10-06 15:42 ` [dpdk-dev] [PATCH v2 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
@ 2018-10-09 8:44 ` Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
` (3 more replies)
3 siblings, 4 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-09 8:44 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
This series of patches add support for actions:
- SET_IPV4_SRC - set a new IPv4 source address.
- SET_IPV4_DST - set a new IPv4 destination address.
- SET_IPV6_SRC - set a new IPv6 source address.
- SET_IPV6_DST - set a new IPv6 destination address.
- SET_TP_SRC - set a new TCP/UDP source port number.
- SET_TP_DST - set a new TCP/UDP destination port number.
These actions are useful in Network Address Translation use case
to edit IP address and TCP/UDP port numbers before switching
the packets out to the destination device port.
Patch 1 adds support for IP address rewrite to rte_flow and testpmd.
Patch 2 adds support for TCP/UDP port rewrite to rte_flow and testpmd.
Patch 3 shows CXGBE PMD example to offload these actions to hardware.
Feedback and suggestions will be much appreciated.
Thanks,
Rahul
RFC v1: http://mails.dpdk.org/archives/dev/2018-June/104913.html
RFC v2: http://mails.dpdk.org/archives/dev/2018-August/109672.html
---
v3:
- Replaced uint32_t with rte_be32_t to reflect the byte order of
the new IPv4 addresses to rewrite.
- Replaced uint16_t with rte_be16_t to reflect the byte order of
the new TCP/UDP port addresses to rewrite.
v2:
- Rebased to tip.
- Removed adding actions to app/test-pmd/config.c, to sync with
rte_flow_conv() changes.
v1 changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
actions.
- Re-based CXGBE PMD changes in patch 3 to tip.
- Updated all instances of fw_filter_wr to new fw_filter2_wr and removed
fw_filter_wr.
- Ensure correct ULP type is set when offloading NAT actions.
- Returning appropriate RTE_FLOW_ERROR_TYPE_ACTION error if a corresponding
valid flow pattern item is not found.
- Updated release notes.
Rahul Lakkireddy (3):
ethdev: add flow api actions to modify IP addresses
ethdev: add flow api actions to modify TCP/UDP port numbers
net/cxgbe: add flow actions to modify IP and TCP/UDP port address
app/test-pmd/cmdline_flow.c | 156 +++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 108 ++++++++++++
doc/guides/rel_notes/release_18_11.rst | 13 +-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 28 +++
drivers/net/cxgbe/base/common.h | 1 +
drivers/net/cxgbe/base/t4_msg.h | 1 +
drivers/net/cxgbe/base/t4fw_interface.h | 23 ++-
drivers/net/cxgbe/cxgbe_filter.c | 37 +++-
drivers/net/cxgbe/cxgbe_filter.h | 23 +++
drivers/net/cxgbe/cxgbe_flow.c | 178 +++++++++++++++++++-
drivers/net/cxgbe/cxgbe_main.c | 10 ++
lib/librte_ethdev/rte_flow.c | 12 ++
lib/librte_ethdev/rte_flow.h | 107 ++++++++++++
13 files changed, 685 insertions(+), 12 deletions(-)
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
@ 2018-10-09 8:44 ` Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
` (2 subsequent siblings)
3 siblings, 0 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-09 8:44 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Add actions:
- SET_IPV4_SRC - set a new IPv4 source address.
- SET_IPV4_DST - set a new IPv4 destination address.
- SET_IPV6_SRC - set a new IPv6 source address.
- SET_IPV6_DST - set a new IPv6 destination address.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Acked-by: Xiaoyu Min <jackmin@mellanox.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
v3:
- Replaced uint32_t with rte_be32_t to reflect the byte order of
the new IPv4 addresses to rewrite.
v2:
- Rebased to tip.
- Removed adding actions to app/test-pmd/config.c, to sync with
rte_flow_conv() changes.
v1 changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
action.
- Updated release notes.
app/test-pmd/cmdline_flow.c | 104 ++++++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 72 ++++++++++++++
doc/guides/rel_notes/release_18_11.rst | 7 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 18 ++++
lib/librte_ethdev/rte_flow.c | 8 ++
lib/librte_ethdev/rte_flow.h | 70 +++++++++++++
6 files changed, 279 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f9260600e..1432498a3 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -243,6 +243,14 @@ enum index {
ACTION_VXLAN_DECAP,
ACTION_NVGRE_ENCAP,
ACTION_NVGRE_DECAP,
+ ACTION_SET_IPV4_SRC,
+ ACTION_SET_IPV4_SRC_IPV4_SRC,
+ ACTION_SET_IPV4_DST,
+ ACTION_SET_IPV4_DST_IPV4_DST,
+ ACTION_SET_IPV6_SRC,
+ ACTION_SET_IPV6_SRC_IPV6_SRC,
+ ACTION_SET_IPV6_DST,
+ ACTION_SET_IPV6_DST_IPV6_DST,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -816,6 +824,10 @@ static const enum index next_action[] = {
ACTION_VXLAN_DECAP,
ACTION_NVGRE_ENCAP,
ACTION_NVGRE_DECAP,
+ ACTION_SET_IPV4_SRC,
+ ACTION_SET_IPV4_DST,
+ ACTION_SET_IPV6_SRC,
+ ACTION_SET_IPV6_DST,
ZERO,
};
@@ -918,6 +930,30 @@ static const enum index action_of_push_mpls[] = {
ZERO,
};
+static const enum index action_set_ipv4_src[] = {
+ ACTION_SET_IPV4_SRC_IPV4_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv4_dst[] = {
+ ACTION_SET_IPV4_DST_IPV4_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_src[] = {
+ ACTION_SET_IPV6_SRC_IPV6_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_ipv6_dst[] = {
+ ACTION_SET_IPV6_DST_IPV6_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_jump[] = {
ACTION_JUMP_GROUP,
ACTION_NEXT,
@@ -2470,6 +2506,74 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+ [ACTION_SET_IPV4_SRC] = {
+ .name = "set_ipv4_src",
+ .help = "Set a new IPv4 source address in the outermost"
+ " IPv4 header",
+ .priv = PRIV_ACTION(SET_IPV4_SRC,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ .next = NEXT(action_set_ipv4_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_SRC_IPV4_SRC] = {
+ .name = "ipv4_addr",
+ .help = "new IPv4 source address to set",
+ .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(IPV4_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv4, ipv4_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV4_DST] = {
+ .name = "set_ipv4_dst",
+ .help = "Set a new IPv4 destination address in the outermost"
+ " IPv4 header",
+ .priv = PRIV_ACTION(SET_IPV4_DST,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ .next = NEXT(action_set_ipv4_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV4_DST_IPV4_DST] = {
+ .name = "ipv4_addr",
+ .help = "new IPv4 destination address to set",
+ .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(IPV4_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv4, ipv4_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_SRC] = {
+ .name = "set_ipv6_src",
+ .help = "Set a new IPv6 source address in the outermost"
+ " IPv6 header",
+ .priv = PRIV_ACTION(SET_IPV6_SRC,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ .next = NEXT(action_set_ipv6_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_SRC_IPV6_SRC] = {
+ .name = "ipv6_addr",
+ .help = "new IPv6 source address to set",
+ .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(IPV6_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv6, ipv6_addr)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_IPV6_DST] = {
+ .name = "set_ipv6_dst",
+ .help = "Set a new IPv6 destination address in the outermost"
+ " IPv6 header",
+ .priv = PRIV_ACTION(SET_IPV6_DST,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ .next = NEXT(action_set_ipv6_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_IPV6_DST_IPV6_DST] = {
+ .name = "ipv6_addr",
+ .help = "new IPv6 destination address to set",
+ .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(IPV6_ADDR)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_ipv6, ipv6_addr)),
+ .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 1b17f6e01..9272cd710 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2076,6 +2076,78 @@ RTE_FLOW_ERROR_TYPE_ACTION error should be returned.
This action modifies the payload of matched flows.
+Action: ``SET_IPV4_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv4 source address in the outermost IPv4 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_src:
+
+.. table:: SET_IPV4_SRC
+
+ +-----------------------------------------+
+ | Field | Value |
+ +===============+=========================+
+ | ``ipv4_addr`` | new IPv4 source address |
+ +---------------+-------------------------+
+
+Action: ``SET_IPV4_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv4 destination address in the outermost IPv4 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV4 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv4_dst:
+
+.. table:: SET_IPV4_DST
+
+ +---------------+------------------------------+
+ | Field | Value |
+ +===============+==============================+
+ | ``ipv4_addr`` | new IPv4 destination address |
+ +---------------+------------------------------+
+
+Action: ``SET_IPV6_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv6 source address in the outermost IPv6 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_src:
+
+.. table:: SET_IPV6_SRC
+
+ +---------------+-------------------------+
+ | Field | Value |
+ +===============+=========================+
+ | ``ipv6_addr`` | new IPv6 source address |
+ +---------------+-------------------------+
+
+Action: ``SET_IPV6_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new IPv6 destination address in the outermost IPv6 header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_IPV6 flow pattern item.
+Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_ipv6_dst:
+
+.. table:: SET_IPV6_DST
+
+ +---------------+------------------------------+
+ | Field | Value |
+ +===============+==============================+
+ | ``ipv6_addr`` | new IPv6 destination address |
+ +---------------+------------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 89ca3317f..12b99de37 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -130,6 +130,13 @@ New Features
this application doesn't need to launch dedicated worker threads for vhost
enqueue/dequeue operations.
+* **Added new Flow API actions to rewrite fields in packet headers.**
+
+ Added new Flow API actions to:
+
+ * Modify source and destination IP addresses in the outermost IPv4/IPv6
+ headers.
+
API Changes
-----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 3a73000a6..97d91f066 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3704,6 +3704,24 @@ This section lists supported actions and their attributes, if any.
- ``nvgre_decap``: Performs a decapsulation action by stripping all headers of
the NVGRE tunnel network overlay from the matched flow.
+- ``set_ipv4_src``: Set a new IPv4 source address in the outermost IPv4 header.
+
+ - ``ipv4_addr``: New IPv4 source address.
+
+- ``set_ipv4_dst``: Set a new IPv4 destination address in the outermost IPv4
+ header.
+
+ - ``ipv4_addr``: New IPv4 destination address.
+
+- ``set_ipv6_src``: Set a new IPv6 source address in the outermost IPv6 header.
+
+ - ``ipv6_addr``: New IPv6 source address.
+
+- ``set_ipv6_dst``: Set a new IPv6 destination address in the outermost IPv6
+ header.
+
+ - ``ipv6_addr``: New IPv6 destination address.
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 9c56a9734..9440b63a9 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -123,6 +123,14 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
MK_FLOW_ACTION(VXLAN_DECAP, 0),
MK_FLOW_ACTION(NVGRE_ENCAP, sizeof(struct rte_flow_action_vxlan_encap)),
MK_FLOW_ACTION(NVGRE_DECAP, 0),
+ MK_FLOW_ACTION(SET_IPV4_SRC,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV4_DST,
+ sizeof(struct rte_flow_action_set_ipv4)),
+ MK_FLOW_ACTION(SET_IPV6_SRC,
+ sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_IPV6_DST,
+ sizeof(struct rte_flow_action_set_ipv6)),
};
static int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index f062ffead..942165f63 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -1506,6 +1506,46 @@ enum rte_flow_action_type {
* error.
*/
RTE_FLOW_ACTION_TYPE_NVGRE_DECAP,
+
+ /**
+ * Modify IPv4 source address in the outermost IPv4 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_ipv4.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC,
+
+ /**
+ * Modify IPv4 destination address in the outermost IPv4 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_ipv4.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV4_DST,
+
+ /**
+ * Modify IPv6 source address in the outermost IPv6 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_ipv6.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC,
+
+ /**
+ * Modify IPv6 destination address in the outermost IPv6 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_ipv6.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
};
/**
@@ -1869,6 +1909,36 @@ struct rte_flow_action_nvgre_encap {
struct rte_flow_item *definition;
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+ *
+ * Allows modification of IPv4 source (RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC)
+ * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV4_DST) in the
+ * specified outermost IPv4 header.
+ */
+struct rte_flow_action_set_ipv4 {
+ rte_be32_t ipv4_addr;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+ *
+ * Allows modification of IPv6 source (RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC)
+ * and destination address (RTE_FLOW_ACTION_TYPE_SET_IPV6_DST) in the
+ * specified outermost IPv6 header.
+ */
+struct rte_flow_action_set_ipv6 {
+ uint8_t ipv6_addr[16];
+};
+
/*
* Definition of a single action.
*
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v3 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
@ 2018-10-09 8:44 ` Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
2018-10-09 13:04 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Ferruh Yigit
3 siblings, 0 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-09 8:44 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Add actions:
- SET_TP_SRC - set a new TCP/UDP source port number.
- SET_TP_DST - set a new TCP/UDP destination port number.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Acked-by: Xiaoyu Min <jackmin@mellanox.com>
Acked-by: Ori Kam <orika@mellanox.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
v3:
- Replaced uint16_t with rte_be16_t to reflect the byte order of
the new TCP/UDP port addresses to rewrite.
v2:
- Rebased to tip.
- Removed adding actions to app/test-pmd/config.c, to sync with
rte_flow_conv() changes.
v1 changes since RFC v2:
- Updated comments, help messages, and doc to indicate that IP/TCP/UDP
of the outermost headers are modified.
- Updated comments and doc to indicate that a corresponding valid flow
pattern item must be specified to offload corresponding header rewrite
action.
- Updated release notes.
app/test-pmd/cmdline_flow.c | 52 +++++++++++++++++++++
doc/guides/prog_guide/rte_flow.rst | 36 ++++++++++++++
doc/guides/rel_notes/release_18_11.rst | 2 +
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++++
lib/librte_ethdev/rte_flow.c | 4 ++
lib/librte_ethdev/rte_flow.h | 37 +++++++++++++++
6 files changed, 141 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 1432498a3..a9888cacf 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -251,6 +251,10 @@ enum index {
ACTION_SET_IPV6_SRC_IPV6_SRC,
ACTION_SET_IPV6_DST,
ACTION_SET_IPV6_DST_IPV6_DST,
+ ACTION_SET_TP_SRC,
+ ACTION_SET_TP_SRC_TP_SRC,
+ ACTION_SET_TP_DST,
+ ACTION_SET_TP_DST_TP_DST,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -828,6 +832,8 @@ static const enum index next_action[] = {
ACTION_SET_IPV4_DST,
ACTION_SET_IPV6_SRC,
ACTION_SET_IPV6_DST,
+ ACTION_SET_TP_SRC,
+ ACTION_SET_TP_DST,
ZERO,
};
@@ -954,6 +960,18 @@ static const enum index action_set_ipv6_dst[] = {
ZERO,
};
+static const enum index action_set_tp_src[] = {
+ ACTION_SET_TP_SRC_TP_SRC,
+ ACTION_NEXT,
+ ZERO,
+};
+
+static const enum index action_set_tp_dst[] = {
+ ACTION_SET_TP_DST_TP_DST,
+ ACTION_NEXT,
+ ZERO,
+};
+
static const enum index action_jump[] = {
ACTION_JUMP_GROUP,
ACTION_NEXT,
@@ -2574,6 +2592,40 @@ static const struct token token_list[] = {
(struct rte_flow_action_set_ipv6, ipv6_addr)),
.call = parse_vc_conf,
},
+ [ACTION_SET_TP_SRC] = {
+ .name = "set_tp_src",
+ .help = "set a new source port number in the outermost"
+ " TCP/UDP header",
+ .priv = PRIV_ACTION(SET_TP_SRC,
+ sizeof(struct rte_flow_action_set_tp)),
+ .next = NEXT(action_set_tp_src),
+ .call = parse_vc,
+ },
+ [ACTION_SET_TP_SRC_TP_SRC] = {
+ .name = "port",
+ .help = "new source port number to set",
+ .next = NEXT(action_set_tp_src, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_tp, port)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_SET_TP_DST] = {
+ .name = "set_tp_dst",
+ .help = "set a new destination port number in the outermost"
+ " TCP/UDP header",
+ .priv = PRIV_ACTION(SET_TP_DST,
+ sizeof(struct rte_flow_action_set_tp)),
+ .next = NEXT(action_set_tp_dst),
+ .call = parse_vc,
+ },
+ [ACTION_SET_TP_DST_TP_DST] = {
+ .name = "port",
+ .help = "new destination port number to set",
+ .next = NEXT(action_set_tp_dst, NEXT_ENTRY(UNSIGNED)),
+ .args = ARGS(ARGS_ENTRY_HTON
+ (struct rte_flow_action_set_tp, port)),
+ .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 9272cd710..1c81a824d 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2148,6 +2148,42 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
| ``ipv6_addr`` | new IPv6 destination address |
+---------------+------------------------------+
+Action: ``SET_TP_SRC``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new source port number in the outermost TCP/UDP header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
+flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_tp_src:
+
+.. table:: SET_TP_SRC
+
+ +----------+-------------------------+
+ | Field | Value |
+ +==========+=========================+
+ | ``port`` | new TCP/UDP source port |
+ +---------------+--------------------+
+
+Action: ``SET_TP_DST``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set a new destination port number in the outermost TCP/UDP header.
+
+It must be used with a valid RTE_FLOW_ITEM_TYPE_TCP or RTE_FLOW_ITEM_TYPE_UDP
+flow pattern item. Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
+
+.. _table_rte_flow_action_set_tp_dst:
+
+.. table:: SET_TP_DST
+
+ +----------+------------------------------+
+ | Field | Value |
+ +==========+==============================+
+ | ``port`` | new TCP/UDP destination port |
+ +---------------+-------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 12b99de37..2b4808226 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -136,6 +136,8 @@ New Features
* Modify source and destination IP addresses in the outermost IPv4/IPv6
headers.
+ * Modify source and destination port numbers in the outermost TCP/UDP
+ headers.
API Changes
-----------
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 97d91f066..ffec7013b 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3722,6 +3722,16 @@ This section lists supported actions and their attributes, if any.
- ``ipv6_addr``: New IPv6 destination address.
+- ``of_set_tp_src``: Set a new source port number in the outermost TCP/UDP
+ header.
+
+ - ``port``: New TCP/UDP source port number.
+
+- ``of_set_tp_dst``: Set a new destination port number in the outermost TCP/UDP
+ header.
+
+ - ``port``: New TCP/UDP destination port number.
+
Destroying flow rules
~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 9440b63a9..4eeb392b6 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -131,6 +131,10 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
sizeof(struct rte_flow_action_set_ipv6)),
MK_FLOW_ACTION(SET_IPV6_DST,
sizeof(struct rte_flow_action_set_ipv6)),
+ MK_FLOW_ACTION(SET_TP_SRC,
+ sizeof(struct rte_flow_action_set_tp)),
+ MK_FLOW_ACTION(SET_TP_DST,
+ sizeof(struct rte_flow_action_set_tp)),
};
static int
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index 942165f63..0805906ae 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -1546,6 +1546,28 @@ enum rte_flow_action_type {
* See struct rte_flow_action_set_ipv6.
*/
RTE_FLOW_ACTION_TYPE_SET_IPV6_DST,
+
+ /**
+ * Modify source port number in the outermost TCP/UDP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
+ * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
+ * RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_tp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_TP_SRC,
+
+ /**
+ * Modify destination port number in the outermost TCP/UDP header.
+ *
+ * If flow pattern does not define a valid RTE_FLOW_ITEM_TYPE_TCP
+ * or RTE_FLOW_ITEM_TYPE_UDP, then the PMD should return a
+ * RTE_FLOW_ERROR_TYPE_ACTION error.
+ *
+ * See struct rte_flow_action_set_tp.
+ */
+ RTE_FLOW_ACTION_TYPE_SET_TP_DST,
};
/**
@@ -1939,6 +1961,21 @@ struct rte_flow_action_set_ipv6 {
uint8_t ipv6_addr[16];
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+ * RTE_FLOW_ACTION_TYPE_SET_TP_DST
+ *
+ * Allows modification of source (RTE_FLOW_ACTION_TYPE_SET_TP_SRC)
+ * and destination (RTE_FLOW_ACTION_TYPE_SET_TP_DST) port numbers
+ * in the specified outermost TCP/UDP header.
+ */
+struct rte_flow_action_set_tp {
+ rte_be16_t port;
+};
+
/*
* Definition of a single action.
*
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [dpdk-dev] [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
@ 2018-10-09 8:44 ` Rahul Lakkireddy
2018-10-09 12:25 ` Ferruh Yigit
2018-10-09 13:04 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Ferruh Yigit
3 siblings, 1 reply; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-09 8:44 UTC (permalink / raw)
To: dev; +Cc: indranil, nirranjan
Query firmware for the new filter work request to offload flows with
actions to modify IP and TCP/UDP port addresses. When available,
translate IP and TCP/UDP port address modify actions to internal
hardware specification and offload the flow to hardware.
Original work by Shagun Agrawal
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v3:
- No changes.
v2:
- No changes.
v1 changes since RFC v2:
- Re-based to tip.
- Updated all instances of fw_filter_wr to new fw_filter2_wr and removed
fw_filter_wr.
- Ensure correct ULP type is set when offloading NAT actions.
- Returning appropriate RTE_FLOW_ERROR_TYPE_ACTION error if a corresponding
valid flow pattern item for the header rewrite action is not found.
- Updated release notes.
doc/guides/rel_notes/release_18_11.rst | 4 +-
drivers/net/cxgbe/base/common.h | 1 +
drivers/net/cxgbe/base/t4_msg.h | 1 +
drivers/net/cxgbe/base/t4fw_interface.h | 23 ++-
drivers/net/cxgbe/cxgbe_filter.c | 37 +++--
drivers/net/cxgbe/cxgbe_filter.h | 23 +++
drivers/net/cxgbe/cxgbe_flow.c | 178 +++++++++++++++++++++++-
drivers/net/cxgbe/cxgbe_main.c | 10 ++
8 files changed, 265 insertions(+), 12 deletions(-)
diff --git a/doc/guides/rel_notes/release_18_11.rst b/doc/guides/rel_notes/release_18_11.rst
index 2b4808226..9a135c89c 100644
--- a/doc/guides/rel_notes/release_18_11.rst
+++ b/doc/guides/rel_notes/release_18_11.rst
@@ -59,7 +59,9 @@ New Features
Flow API support has been enhanced for CXGBE Poll Mode Driver to offload:
* Match items: destination MAC address.
- * Action items: push/pop/rewrite vlan header.
+ * Action items: push/pop/rewrite vlan header, rewrite IP addresses in
+ outermost IPv4/IPv6 header, rewrite port numbers in outermost TCP/UDP
+ header.
* **Added a devarg to use the latest supported vector path in i40e.**
A new devarg ``use-latest-supported-vec`` was introduced to allow users to
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index d9f74d995..fd2006682 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -271,6 +271,7 @@ struct adapter_params {
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
u8 fw_caps_support; /* 32-bit Port Capabilities */
+ u8 filter2_wr_support; /* FW support for FILTER2_WR */
};
/* Firmware Port Capabilities types.
diff --git a/drivers/net/cxgbe/base/t4_msg.h b/drivers/net/cxgbe/base/t4_msg.h
index 2128da64f..6494f1827 100644
--- a/drivers/net/cxgbe/base/t4_msg.h
+++ b/drivers/net/cxgbe/base/t4_msg.h
@@ -32,6 +32,7 @@ enum CPL_error {
enum {
ULP_MODE_NONE = 0,
+ ULP_MODE_TCPDDP = 5,
};
enum {
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index e2d2ee897..b4c95c588 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -61,6 +61,7 @@ enum fw_wr_opcodes {
FW_ETH_TX_PKTS_WR = 0x09,
FW_ETH_TX_PKT_VM_WR = 0x11,
FW_ETH_TX_PKTS_VM_WR = 0x12,
+ FW_FILTER2_WR = 0x77,
FW_ETH_TX_PKTS2_WR = 0x78,
};
@@ -165,7 +166,7 @@ enum fw_filter_wr_cookie {
FW_FILTER_WR_EINVAL,
};
-struct fw_filter_wr {
+struct fw_filter2_wr {
__be32 op_pkd;
__be32 len16_pkd;
__be64 r3;
@@ -195,6 +196,19 @@ struct fw_filter_wr {
__be16 fpm;
__be16 r7;
__u8 sma[6];
+ __be16 r8;
+ __u8 filter_type_swapmac;
+ __u8 natmode_to_ulp_type;
+ __be16 newlport;
+ __be16 newfport;
+ __u8 newlip[16];
+ __u8 newfip[16];
+ __be32 natseqcheck;
+ __be32 r9;
+ __be64 r10;
+ __be64 r11;
+ __be64 r12;
+ __be64 r13;
};
#define S_FW_FILTER_WR_TID 12
@@ -300,6 +314,12 @@ struct fw_filter_wr {
#define S_FW_FILTER_WR_MATCHTYPEM 0
#define V_FW_FILTER_WR_MATCHTYPEM(x) ((x) << S_FW_FILTER_WR_MATCHTYPEM)
+#define S_FW_FILTER2_WR_NATMODE 5
+#define V_FW_FILTER2_WR_NATMODE(x) ((x) << S_FW_FILTER2_WR_NATMODE)
+
+#define S_FW_FILTER2_WR_ULP_TYPE 0
+#define V_FW_FILTER2_WR_ULP_TYPE(x) ((x) << S_FW_FILTER2_WR_ULP_TYPE)
+
/******************************************************************************
* C O M M A N D s
*********************/
@@ -655,6 +675,7 @@ enum fw_params_param_dev {
FW_PARAMS_PARAM_DEV_FWREV = 0x0B, /* fw version */
FW_PARAMS_PARAM_DEV_TPREV = 0x0C, /* tp version */
FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
+ FW_PARAMS_PARAM_DEV_FILTER2_WR = 0x1D,
};
/*
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index dcb1dd03e..b876abf43 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -89,6 +89,9 @@ int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
if (fs->val.iport >= adapter->params.nports)
return -ERANGE;
+ if (!fs->cap && fs->nat_mode && !adapter->params.filter2_wr_support)
+ return -EOPNOTSUPP;
+
return 0;
}
@@ -627,6 +630,7 @@ void clear_filter(struct filter_entry *f)
/**
* t4_mk_filtdelwr - create a delete filter WR
+ * @adap: adapter context
* @ftid: the filter ID
* @wr: the filter work request to populate
* @qid: ingress queue to receive the delete notification
@@ -634,10 +638,14 @@ void clear_filter(struct filter_entry *f)
* Creates a filter work request to delete the supplied filter. If @qid is
* negative the delete notification is suppressed.
*/
-static void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid)
+static void t4_mk_filtdelwr(struct adapter *adap, unsigned int ftid,
+ struct fw_filter2_wr *wr, int qid)
{
memset(wr, 0, sizeof(*wr));
- wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+ if (adap->params.filter2_wr_support)
+ wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+ else
+ wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
wr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*wr) / 16));
wr->tid_to_iq = cpu_to_be32(V_FW_FILTER_WR_TID(ftid) |
V_FW_FILTER_WR_NOREPLY(qid < 0));
@@ -655,7 +663,7 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
struct adapter *adapter = ethdev2adap(dev);
struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
struct rte_mbuf *mbuf;
- struct fw_filter_wr *fwr;
+ struct fw_filter2_wr *fwr;
struct sge_ctrl_txq *ctrlq;
unsigned int port_id = ethdev2pinfo(dev)->port_id;
@@ -667,8 +675,8 @@ static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
mbuf->data_len = sizeof(*fwr);
mbuf->pkt_len = mbuf->data_len;
- fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
- t4_mk_filtdelwr(f->tid, fwr, adapter->sge.fw_evtq.abs_id);
+ fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
+ t4_mk_filtdelwr(adapter, f->tid, fwr, adapter->sge.fw_evtq.abs_id);
/*
* Mark the filter as "pending" and ship off the Filter Work Request.
@@ -684,7 +692,7 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
struct adapter *adapter = ethdev2adap(dev);
struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
struct rte_mbuf *mbuf;
- struct fw_filter_wr *fwr;
+ struct fw_filter2_wr *fwr;
struct sge_ctrl_txq *ctrlq;
unsigned int port_id = ethdev2pinfo(dev)->port_id;
int ret;
@@ -712,13 +720,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
mbuf->data_len = sizeof(*fwr);
mbuf->pkt_len = mbuf->data_len;
- fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter_wr *);
+ fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
memset(fwr, 0, sizeof(*fwr));
/*
* Construct the work request to set the filter.
*/
- fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
+ if (adapter->params.filter2_wr_support)
+ fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
+ else
+ fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
fwr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*fwr) / 16));
fwr->tid_to_iq =
cpu_to_be32(V_FW_FILTER_WR_TID(f->tid) |
@@ -762,6 +773,16 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
fwr->fp = cpu_to_be16(f->fs.val.fport);
fwr->fpm = cpu_to_be16(f->fs.mask.fport);
+ if (adapter->params.filter2_wr_support && f->fs.nat_mode) {
+ fwr->natmode_to_ulp_type =
+ V_FW_FILTER2_WR_ULP_TYPE(ULP_MODE_TCPDDP) |
+ V_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);
+ memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
+ memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
+ fwr->newlport = cpu_to_be16(f->fs.nat_lport);
+ fwr->newfport = cpu_to_be16(f->fs.nat_fport);
+ }
+
/*
* Mark the filter as "pending" and ship off the Filter Work Request.
* When we get the Work Request Reply we'll clear the pending status.
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 83d647de6..950fa0bca 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -104,6 +104,18 @@ struct ch_filter_specification {
uint8_t dmac[ETHER_ADDR_LEN]; /* new destination MAC address */
uint16_t vlan; /* VLAN Tag to insert */
+ /*
+ * Switch proxy/rewrite fields. An ingress packet which matches a
+ * filter with "switch" set will be looped back out as an egress
+ * packet -- potentially with some header rewriting.
+ */
+ uint32_t nat_mode:3; /* specify NAT operation mode */
+
+ uint8_t nat_lip[16]; /* local IP to use after NAT'ing */
+ uint8_t nat_fip[16]; /* foreign IP to use after NAT'ing */
+ uint16_t nat_lport; /* local port number to use after NAT'ing */
+ uint16_t nat_fport; /* foreign port number to use after NAT'ing */
+
/* Filter rule value/mask pairs. */
struct ch_filter_tuple val;
struct ch_filter_tuple mask;
@@ -121,6 +133,17 @@ enum {
VLAN_REWRITE
};
+enum {
+ NAT_MODE_NONE = 0, /* No NAT performed */
+ NAT_MODE_DIP, /* NAT on Dst IP */
+ NAT_MODE_DIP_DP, /* NAT on Dst IP, Dst Port */
+ NAT_MODE_DIP_DP_SIP, /* NAT on Dst IP, Dst Port and Src IP */
+ NAT_MODE_DIP_DP_SP, /* NAT on Dst IP, Dst Port and Src Port */
+ NAT_MODE_SIP_SP, /* NAT on Src IP and Src Port */
+ NAT_MODE_DIP_SIP_SP, /* NAT on Dst IP, Src IP and Src Port */
+ NAT_MODE_ALL /* NAT on entire 4-tuple */
+};
+
enum filter_type {
FILTER_TYPE_IPV4 = 0,
FILTER_TYPE_IPV6,
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index bee3bd640..52cb3bdf4 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -368,14 +368,77 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)
return 0;
}
+static int
+cxgbe_get_flow_item_index(const struct rte_flow_item items[], u32 type)
+{
+ const struct rte_flow_item *i;
+ int j, index = -ENOENT;
+
+ for (i = items, j = 0; i->type != RTE_FLOW_ITEM_TYPE_END; i++, j++) {
+ if (i->type == type) {
+ index = j;
+ break;
+ }
+ }
+
+ return index;
+}
+
+static int
+ch_rte_parse_nat(uint8_t nmode, struct ch_filter_specification *fs)
+{
+ /* nmode:
+ * BIT_0 = [src_ip], BIT_1 = [dst_ip]
+ * BIT_2 = [src_port], BIT_3 = [dst_port]
+ *
+ * Only below cases are supported as per our spec.
+ */
+ switch (nmode) {
+ case 0: /* 0000b */
+ fs->nat_mode = NAT_MODE_NONE;
+ break;
+ case 2: /* 0010b */
+ fs->nat_mode = NAT_MODE_DIP;
+ break;
+ case 5: /* 0101b */
+ fs->nat_mode = NAT_MODE_SIP_SP;
+ break;
+ case 7: /* 0111b */
+ fs->nat_mode = NAT_MODE_DIP_SIP_SP;
+ break;
+ case 10: /* 1010b */
+ fs->nat_mode = NAT_MODE_DIP_DP;
+ break;
+ case 11: /* 1011b */
+ fs->nat_mode = NAT_MODE_DIP_DP_SIP;
+ break;
+ case 14: /* 1110b */
+ fs->nat_mode = NAT_MODE_DIP_DP_SP;
+ break;
+ case 15: /* 1111b */
+ fs->nat_mode = NAT_MODE_ALL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int
ch_rte_parse_atype_switch(const struct rte_flow_action *a,
+ const struct rte_flow_item items[],
+ uint8_t *nmode,
struct ch_filter_specification *fs,
struct rte_flow_error *e)
{
const struct rte_flow_action_of_set_vlan_vid *vlanid;
const struct rte_flow_action_of_push_vlan *pushvlan;
+ const struct rte_flow_action_set_ipv4 *ipv4;
+ const struct rte_flow_action_set_ipv6 *ipv6;
+ const struct rte_flow_action_set_tp *tp_port;
const struct rte_flow_action_phy_port *port;
+ int item_index;
switch (a->type) {
case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
@@ -401,6 +464,94 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
port = (const struct rte_flow_action_phy_port *)a->conf;
fs->eport = port->index;
break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV4);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV4 "
+ "found.");
+
+ ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+ memcpy(fs->nat_fip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+ *nmode |= 1 << 0;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV4);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV4 "
+ "found.");
+
+ ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf;
+ memcpy(fs->nat_lip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr));
+ *nmode |= 1 << 1;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV6);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV6 "
+ "found.");
+
+ ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+ memcpy(fs->nat_fip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+ *nmode |= 1 << 0;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_IPV6);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_IPV6 "
+ "found.");
+
+ ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf;
+ memcpy(fs->nat_lip, ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr));
+ *nmode |= 1 << 1;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_TCP);
+ if (item_index < 0) {
+ item_index =
+ cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_UDP);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_TCP or "
+ "RTE_FLOW_ITEM_TYPE_UDP found");
+ }
+
+ tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+ fs->nat_fport = be16_to_cpu(tp_port->port);
+ *nmode |= 1 << 2;
+ break;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+ item_index = cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_TCP);
+ if (item_index < 0) {
+ item_index =
+ cxgbe_get_flow_item_index(items,
+ RTE_FLOW_ITEM_TYPE_UDP);
+ if (item_index < 0)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "No RTE_FLOW_ITEM_TYPE_TCP or "
+ "RTE_FLOW_ITEM_TYPE_UDP found");
+ }
+
+ tp_port = (const struct rte_flow_action_set_tp *)a->conf;
+ fs->nat_lport = be16_to_cpu(tp_port->port);
+ *nmode |= 1 << 3;
+ break;
default:
/* We are not supposed to come here */
return rte_flow_error_set(e, EINVAL,
@@ -413,10 +564,12 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a,
static int
cxgbe_rtef_parse_actions(struct rte_flow *flow,
+ const struct rte_flow_item items[],
const struct rte_flow_action action[],
struct rte_flow_error *e)
{
struct ch_filter_specification *fs = &flow->fs;
+ uint8_t nmode = 0, nat_ipv4 = 0, nat_ipv6 = 0;
const struct rte_flow_action_queue *q;
const struct rte_flow_action *a;
char abit = 0;
@@ -458,6 +611,16 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
case RTE_FLOW_ACTION_TYPE_PHY_PORT:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
+ nat_ipv4++;
+ goto action_switch;
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
+ nat_ipv6++;
+ case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
+ case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
+action_switch:
/* We allow multiple switch actions, but switch is
* not compatible with either queue or drop
*/
@@ -465,7 +628,14 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
return rte_flow_error_set(e, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, a,
"overlapping action specified");
- ret = ch_rte_parse_atype_switch(a, fs, e);
+ if (nat_ipv4 && nat_ipv6)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "Can't have one address ipv4 and the"
+ " other ipv6");
+
+ ret = ch_rte_parse_atype_switch(a, items, &nmode, fs,
+ e);
if (ret)
return ret;
fs->action = FILTER_SWITCH;
@@ -478,6 +648,10 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
}
}
+ if (ch_rte_parse_nat(nmode, fs))
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, a,
+ "invalid settings for swich action");
return 0;
}
@@ -586,7 +760,7 @@ cxgbe_flow_parse(struct rte_flow *flow,
ret = cxgbe_rtef_parse_items(flow, item, e);
if (ret)
return ret;
- return cxgbe_rtef_parse_actions(flow, action, e);
+ return cxgbe_rtef_parse_actions(flow, item, action, e);
}
static int __cxgbe_flow_create(struct rte_eth_dev *dev, struct rte_flow *flow)
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 9c40f51b2..a135df9c7 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -1180,6 +1180,16 @@ static int adap_init0(struct adapter *adap)
goto bye;
}
+ /* See if FW supports FW_FILTER2 work request */
+ if (is_t4(adap->params.chip)) {
+ adap->params.filter2_wr_support = 0;
+ } else {
+ params[0] = FW_PARAM_DEV(FILTER2_WR);
+ ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 1, params, val);
+ adap->params.filter2_wr_support = (ret == 0 && val[0] != 0);
+ }
+
/* query tid-related parameters */
params[0] = FW_PARAM_DEV(NTID);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
--
2.18.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
@ 2018-10-09 12:25 ` Ferruh Yigit
2018-10-09 12:39 ` Rahul Lakkireddy
0 siblings, 1 reply; 22+ messages in thread
From: Ferruh Yigit @ 2018-10-09 12:25 UTC (permalink / raw)
To: Rahul Lakkireddy, dev; +Cc: indranil, nirranjan
On 10/9/2018 9:44 AM, Rahul Lakkireddy wrote:
> Query firmware for the new filter work request to offload flows with
> actions to modify IP and TCP/UDP port addresses. When available,
> translate IP and TCP/UDP port address modify actions to internal
> hardware specification and offload the flow to hardware.
>
> Original work by Shagun Agrawal
>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
<...>
> @@ -458,6 +611,16 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
> case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
> case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
> case RTE_FLOW_ACTION_TYPE_PHY_PORT:
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
> + nat_ipv4++;
> + goto action_switch;
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
> + nat_ipv6++;
> + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> + case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
This is causing build error [1], fall through seems OK/intended, I will add [2]
while merging to clarify it. Please shout if you prefer another fix.
[1]
.../drivers/net/cxgbe/cxgbe_flow.c: In function ‘cxgbe_rtef_parse_actions’:
.../drivers/net/cxgbe/cxgbe_flow.c:620:12: error: this statement may fall
through [-Werror=implicit-fallthrough=]
nat_ipv6++;
~~~~~~~~^~
.../drivers/net/cxgbe/cxgbe_flow.c:621:3: note: here
case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
^~~~
[2]
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index 52cb3bdf4..3e4acf333 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -618,6 +618,7 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
nat_ipv6++;
+ goto action_switch;
case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
action_switch:
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
2018-10-09 12:25 ` Ferruh Yigit
@ 2018-10-09 12:39 ` Rahul Lakkireddy
0 siblings, 0 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-10-09 12:39 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, Indranil Choudhury, Nirranjan Kirubaharan
On Tuesday, October 10/09/18, 2018 at 17:55:09 +0530, Ferruh Yigit wrote:
> On 10/9/2018 9:44 AM, Rahul Lakkireddy wrote:
> > Query firmware for the new filter work request to offload flows with
> > actions to modify IP and TCP/UDP port addresses. When available,
> > translate IP and TCP/UDP port address modify actions to internal
> > hardware specification and offload the flow to hardware.
> >
> > Original work by Shagun Agrawal
> >
> > Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
>
> <...>
>
> > @@ -458,6 +611,16 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
> > case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
> > case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
> > case RTE_FLOW_ACTION_TYPE_PHY_PORT:
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
> > + nat_ipv4++;
> > + goto action_switch;
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
> > + nat_ipv6++;
> > + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> > + case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
>
> This is causing build error [1], fall through seems OK/intended, I will add [2]
> while merging to clarify it. Please shout if you prefer another fix.
>
Yes, fall through is intended here. I'm fine with [2]. Thanks for fixing
it.
> [1]
> .../drivers/net/cxgbe/cxgbe_flow.c: In function ‘cxgbe_rtef_parse_actions’:
> .../drivers/net/cxgbe/cxgbe_flow.c:620:12: error: this statement may fall
> through [-Werror=implicit-fallthrough=]
> nat_ipv6++;
> ~~~~~~~~^~
> .../drivers/net/cxgbe/cxgbe_flow.c:621:3: note: here
> case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> ^~~~
>
>
> [2]
> diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
> index 52cb3bdf4..3e4acf333 100644
> --- a/drivers/net/cxgbe/cxgbe_flow.c
> +++ b/drivers/net/cxgbe/cxgbe_flow.c
> @@ -618,6 +618,7 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
> case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC:
> case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST:
> nat_ipv6++;
> + goto action_switch;
> case RTE_FLOW_ACTION_TYPE_SET_TP_SRC:
> case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
> action_switch:
Thanks,
Rahul
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
` (2 preceding siblings ...)
2018-10-09 8:44 ` [dpdk-dev] [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
@ 2018-10-09 13:04 ` Ferruh Yigit
3 siblings, 0 replies; 22+ messages in thread
From: Ferruh Yigit @ 2018-10-09 13:04 UTC (permalink / raw)
To: Rahul Lakkireddy, dev; +Cc: indranil, nirranjan
On 10/9/2018 9:44 AM, Rahul Lakkireddy wrote:
> This series of patches add support for actions:
> - SET_IPV4_SRC - set a new IPv4 source address.
> - SET_IPV4_DST - set a new IPv4 destination address.
> - SET_IPV6_SRC - set a new IPv6 source address.
> - SET_IPV6_DST - set a new IPv6 destination address.
> - SET_TP_SRC - set a new TCP/UDP source port number.
> - SET_TP_DST - set a new TCP/UDP destination port number.
>
> These actions are useful in Network Address Translation use case
> to edit IP address and TCP/UDP port numbers before switching
> the packets out to the destination device port.
>
> Patch 1 adds support for IP address rewrite to rte_flow and testpmd.
>
> Patch 2 adds support for TCP/UDP port rewrite to rte_flow and testpmd.
>
> Patch 3 shows CXGBE PMD example to offload these actions to hardware.
>
> Feedback and suggestions will be much appreciated.
>
> Thanks,
> Rahul
>
> RFC v1: http://mails.dpdk.org/archives/dev/2018-June/104913.html
> RFC v2: http://mails.dpdk.org/archives/dev/2018-August/109672.html
>
> ---
> v3:
> - Replaced uint32_t with rte_be32_t to reflect the byte order of
> the new IPv4 addresses to rewrite.
> - Replaced uint16_t with rte_be16_t to reflect the byte order of
> the new TCP/UDP port addresses to rewrite.
>
> v2:
> - Rebased to tip.
> - Removed adding actions to app/test-pmd/config.c, to sync with
> rte_flow_conv() changes.
>
> v1 changes since RFC v2:
> - Updated comments, help messages, and doc to indicate that IP/TCP/UDP
> of the outermost headers are modified.
> - Updated comments and doc to indicate that a corresponding valid flow
> pattern item must be specified to offload corresponding header rewrite
> actions.
> - Re-based CXGBE PMD changes in patch 3 to tip.
> - Updated all instances of fw_filter_wr to new fw_filter2_wr and removed
> fw_filter_wr.
> - Ensure correct ULP type is set when offloading NAT actions.
> - Returning appropriate RTE_FLOW_ERROR_TYPE_ACTION error if a corresponding
> valid flow pattern item is not found.
> - Updated release notes.
>
>
> Rahul Lakkireddy (3):
> ethdev: add flow api actions to modify IP addresses
> ethdev: add flow api actions to modify TCP/UDP port numbers
> net/cxgbe: add flow actions to modify IP and TCP/UDP port address
Series applied to dpdk-next-net/master, thanks.
(modification mentioned on v3 3/3 has been applied while merging)
^ permalink raw reply [flat|nested] 22+ messages in thread