All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
@ 2018-09-24  8:28 Rahul Lakkireddy
  2018-09-24  8:28 ` [PATCH 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
                   ` (4 more replies)
  0 siblings, 5 replies; 22+ messages in thread
From: Rahul Lakkireddy @ 2018-09-24  8:28 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

---
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 +++++++++++++++++
 app/test-pmd/config.c                       |  12 ++
 doc/guides/prog_guide/rte_flow.rst          | 108 ++++++++++++
 doc/guides/rel_notes/release_18_11.rst      |  12 +-
 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 ++++++++++++
 14 files changed, 696 insertions(+), 12 deletions(-)

-- 
2.18.0

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/3] ethdev: add flow api actions to modify IP addresses
  2018-09-24  8:28 [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 ` [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 related	[flat|nested] 22+ messages in thread

* [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
  2018-09-24  8:28 [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
  2018-09-24  8:28 ` [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 ` [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 related	[flat|nested] 22+ messages in thread

* [PATCH 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
  2018-09-24  8:28 [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
  2018-09-24  8:28 ` [PATCH 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
  2018-09-24  8:28 ` [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 ` [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Thomas Monjalon
  2018-10-06 15:41 ` [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 related	[flat|nested] 22+ messages in thread

* Re: [PATCH 1/3] ethdev: add flow api actions to modify IP addresses
  2018-09-24  8:28 ` [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

* Re: [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
  2018-09-24  8:28 ` [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: [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
  2018-09-24  8:28 [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 ` [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 ` [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

* Re: [PATCH 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
  2018-09-24  8:28 ` [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: [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

* [PATCH v2 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
  2018-09-24  8:28 [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 ` [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   ` [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

* [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses
  2018-10-06 15:41 ` [PATCH v2 " Rahul Lakkireddy
@ 2018-10-06 15:41   ` Rahul Lakkireddy
  2018-10-08  9:22     ` Andrew Rybchenko
  2018-10-06 15:41   ` [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 related	[flat|nested] 22+ messages in thread

* [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
  2018-10-06 15:41 ` [PATCH v2 " Rahul Lakkireddy
  2018-10-06 15:41   ` [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   ` [PATCH v2 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
  2018-10-09  8:44   ` [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 related	[flat|nested] 22+ messages in thread

* [PATCH v2 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
  2018-10-06 15:41 ` [PATCH v2 " Rahul Lakkireddy
  2018-10-06 15:41   ` [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
  2018-10-06 15:41   ` [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   ` [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 related	[flat|nested] 22+ messages in thread

* Re: [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses
  2018-10-06 15:41   ` [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

* Re: [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
  2018-10-06 15:41   ` [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

* [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
  2018-10-06 15:41 ` [PATCH v2 " Rahul Lakkireddy
                     ` (2 preceding siblings ...)
  2018-10-06 15:42   ` [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     ` [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

* [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses
  2018-10-09  8:44   ` [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     ` [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 related	[flat|nested] 22+ messages in thread

* [PATCH v3 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers
  2018-10-09  8:44   ` [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
  2018-10-09  8:44     ` [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     ` [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
  2018-10-09 13:04     ` [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 related	[flat|nested] 22+ messages in thread

* [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
  2018-10-09  8:44   ` [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
  2018-10-09  8:44     ` [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
  2018-10-09  8:44     ` [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     ` [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 related	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address
  2018-10-09  8:44     ` [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: [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: [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API
  2018-10-09  8:44   ` [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     ` [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

end of thread, other threads:[~2018-10-09 13:04 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-24  8:28 [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-09-24  8:28 ` [PATCH 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-09-25  3:03   ` Xiaoyu Min
2018-09-24  8:28 ` [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
2018-09-24  8:28 ` [PATCH 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
2018-10-03 20:33 ` [PATCH 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Thomas Monjalon
2018-10-06 15:41 ` [PATCH v2 " Rahul Lakkireddy
2018-10-06 15:41   ` [PATCH v2 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-10-08  9:22     ` Andrew Rybchenko
2018-10-06 15:41   ` [PATCH v2 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
2018-10-08  9:24     ` Andrew Rybchenko
2018-10-06 15:42   ` [PATCH v2 3/3] net/cxgbe: add flow actions to modify IP and TCP/UDP port address Rahul Lakkireddy
2018-10-09  8:44   ` [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Rahul Lakkireddy
2018-10-09  8:44     ` [PATCH v3 1/3] ethdev: add flow api actions to modify IP addresses Rahul Lakkireddy
2018-10-09  8:44     ` [PATCH v3 2/3] ethdev: add flow api actions to modify TCP/UDP port numbers Rahul Lakkireddy
2018-10-09  8:44     ` [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
2018-10-09 13:04     ` [PATCH v3 0/3] ethdev: add IP address and TCP/UDP port rewrite actions to flow API Ferruh Yigit

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.