[v2,01/11] ethdev: add flex item modify field support

Message ID 20230119045824.665663-2-rongweil@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series add flex item support |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Rongwei Liu Jan. 19, 2023, 4:58 a.m. UTC
  Add flex item as modify field destination.
Add "struct rte_flow_item_flex_handle *flex_handle" into
"struct rte_flow_action_modify_data" as union with existed
"level" member. This new member is dedicated for modifying
flex item.

Add flex item modify field cmdline support. Now user can use
testpmd cli to specify which flex item to be modified, either
source or destination.

Syntax is as below:
modify_field op set dst_type flex_item dst_level 0
dst_offset 16 src_type value src_value 0x123456781020 width 8

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c            | 89 ++++++++++++++++++++++++--
 doc/guides/prog_guide/rte_flow.rst     | 38 ++++++-----
 doc/guides/rel_notes/release_23_03.rst |  4 ++
 lib/ethdev/rte_flow.h                  |  8 ++-
 4 files changed, 113 insertions(+), 26 deletions(-)
  

Comments

Andrew Rybchenko Jan. 20, 2023, 9:07 a.m. UTC | #1
On 1/19/23 07:58, Rongwei Liu wrote:
> Add flex item as modify field destination.
> Add "struct rte_flow_item_flex_handle *flex_handle" into
> "struct rte_flow_action_modify_data" as union with existed
> "level" member. This new member is dedicated for modifying
> flex item.
> 
> Add flex item modify field cmdline support. Now user can use
> testpmd cli to specify which flex item to be modified, either
> source or destination.
> 
> Syntax is as below:
> modify_field op set dst_type flex_item dst_level 0
> dst_offset 16 src_type value src_value 0x123456781020 width 8
> 
> Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> Acked-by: Ori Kam <orika@nvidia.com>

[snip]

> diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
> index b8c5b68d6c..c673205e5e 100644
> --- a/doc/guides/rel_notes/release_23_03.rst
> +++ b/doc/guides/rel_notes/release_23_03.rst
> @@ -56,6 +56,10 @@ New Features
>        =======================================================
>   
>   

It should be just one empty line here

> +* ethdev: added a new field:

"added a new field' is too generic.

> +
> +  - modify flex item: ``rte_flow_action_modify_data.flex_handle``
> +

And two empty lines here.

>   Removed Items
>   -------------
>   
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index b60987db4b..c66a65351d 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
>   	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
>   	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
>   	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
> +	RTE_FLOW_FIELD_FLEX_ITEM,	/**< Flex item. */
>   };
>   
>   /**
> @@ -3541,8 +3542,11 @@ struct rte_flow_action_modify_data {
>   	RTE_STD_C11
>   	union {
>   		struct {
> -			/** Encapsulation level or tag index. */
> -			uint32_t level;
> +			/**< Encapsulation level or tag index or flex item handle. */

Have you tried to generate documentation? If it is a union documentation 
it should be /**, not /**<.
In general, it is better to document union from overall
point of view. What is it logically? Do not define union
as just a union of its fields.

> +			union {
> +				uint32_t level;
> +				struct rte_flow_item_flex_handle *flex_handle;

Union items documentation missing.

> +			};
>   			/** Number of bits to skip from a field. */
>   			uint32_t offset;
>   		};
  
Rongwei Liu Jan. 30, 2023, 4:29 a.m. UTC | #2
Hi Andrew

BR
Rongwei

> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Friday, January 20, 2023 17:08
> To: Rongwei Liu <rongweil@nvidia.com>; Matan Azrad <matan@nvidia.com>;
> Slava Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>;
> NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman
> Singh <aman.deep.singh@intel.com>; Yuying Zhang
> <yuying.zhang@intel.com>; Ferruh Yigit <ferruh.yigit@amd.com>
> Cc: dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v2 01/11] ethdev: add flex item modify field support
> 
> External email: Use caution opening links or attachments
> 
> 
> On 1/19/23 07:58, Rongwei Liu wrote:
> > Add flex item as modify field destination.
> > Add "struct rte_flow_item_flex_handle *flex_handle" into "struct
> > rte_flow_action_modify_data" as union with existed "level" member.
> > This new member is dedicated for modifying flex item.
> >
> > Add flex item modify field cmdline support. Now user can use testpmd
> > cli to specify which flex item to be modified, either source or
> > destination.
> >
> > Syntax is as below:
> > modify_field op set dst_type flex_item dst_level 0 dst_offset 16
> > src_type value src_value 0x123456781020 width 8
> >
> > Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> > Acked-by: Ori Kam <orika@nvidia.com>
> 
> [snip]
> 
> > diff --git a/doc/guides/rel_notes/release_23_03.rst
> > b/doc/guides/rel_notes/release_23_03.rst
> > index b8c5b68d6c..c673205e5e 100644
> > --- a/doc/guides/rel_notes/release_23_03.rst
> > +++ b/doc/guides/rel_notes/release_23_03.rst
> > @@ -56,6 +56,10 @@ New Features
> >        =======================================================
> >
> >
> 
> It should be just one empty line here
> 
Sure.
> > +* ethdev: added a new field:
> 
> "added a new field' is too generic.
> 
> > +
> > +  - modify flex item: ``rte_flow_action_modify_data.flex_handle``
> > +
> 
> And two empty lines here.
> 
Sure.
> >   Removed Items
> >   -------------
> >
> > diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > b60987db4b..c66a65351d 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
> >       RTE_FLOW_FIELD_IPV6_ECN,        /**< IPv6 ECN. */
> >       RTE_FLOW_FIELD_GTP_PSC_QFI,     /**< GTP QFI. */
> >       RTE_FLOW_FIELD_METER_COLOR,     /**< Meter color marker. */
> > +     RTE_FLOW_FIELD_FLEX_ITEM,       /**< Flex item. */
> >   };
> >
> >   /**
> > @@ -3541,8 +3542,11 @@ struct rte_flow_action_modify_data {
> >       RTE_STD_C11
> >       union {
> >               struct {
> > -                     /** Encapsulation level or tag index. */
> > -                     uint32_t level;
> > +                     /**< Encapsulation level or tag index or flex
> > + item handle. */
> 
> Have you tried to generate documentation? If it is a union documentation it
> should be /**, not /**<.
Sure. Sorry, I followed wrong existed examples.
> In general, it is better to document union from overall point of view. What is it
> logically? Do not define union as just a union of its fields.
Currently, 'flex_handle' is documents in rte_flow.rst file " table:: destination/source field definition" as a new row.  
From API aspect, when modifying flex item, user should specify the pointer of the flex item instead of ID.
That' why it was added as a union. 
> 
> > +                     union {
> > +                             uint32_t level;
> > +                             struct rte_flow_item_flex_handle
> > + *flex_handle;
> 
> Union items documentation missing.
See above. Do we need another place to document the union again?
> 
> > +                     };
> >                       /** Number of bits to skip from a field. */
> >                       uint32_t offset;
> >               };
  
Rongwei Liu Jan. 30, 2023, 4:35 a.m. UTC | #3
Hi Andrew

BR
Rongwei

> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Friday, January 20, 2023 17:08
> To: Rongwei Liu <rongweil@nvidia.com>; Matan Azrad <matan@nvidia.com>;
> Slava Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>;
> NBU-Contact-Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman
> Singh <aman.deep.singh@intel.com>; Yuying Zhang
> <yuying.zhang@intel.com>; Ferruh Yigit <ferruh.yigit@amd.com>
> Cc: dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v2 01/11] ethdev: add flex item modify field support
> 
> External email: Use caution opening links or attachments
> 
> 
> On 1/19/23 07:58, Rongwei Liu wrote:
> > Add flex item as modify field destination.
> > Add "struct rte_flow_item_flex_handle *flex_handle" into "struct
> > rte_flow_action_modify_data" as union with existed "level" member.
> > This new member is dedicated for modifying flex item.
> >
> > Add flex item modify field cmdline support. Now user can use testpmd
> > cli to specify which flex item to be modified, either source or
> > destination.
> >
> > Syntax is as below:
> > modify_field op set dst_type flex_item dst_level 0 dst_offset 16
> > src_type value src_value 0x123456781020 width 8
> >
> > Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
> > Acked-by: Ori Kam <orika@nvidia.com>
> 
> [snip]
> 
> > diff --git a/doc/guides/rel_notes/release_23_03.rst
> > b/doc/guides/rel_notes/release_23_03.rst
> > index b8c5b68d6c..c673205e5e 100644
> > --- a/doc/guides/rel_notes/release_23_03.rst
> > +++ b/doc/guides/rel_notes/release_23_03.rst
> > @@ -56,6 +56,10 @@ New Features
> >        =======================================================
> >
> >
> 
> It should be just one empty line here
> 
> > +* ethdev: added a new field:
> 
> "added a new field' is too generic.
> 
> > +
> > +  - modify flex item: ``rte_flow_action_modify_data.flex_handle``
> > +
> 
> And two empty lines here.
> 
> >   Removed Items
> >   -------------
> >
> > diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > b60987db4b..c66a65351d 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -3528,6 +3528,7 @@ enum rte_flow_field_id {
> >       RTE_FLOW_FIELD_IPV6_ECN,        /**< IPv6 ECN. */
> >       RTE_FLOW_FIELD_GTP_PSC_QFI,     /**< GTP QFI. */
> >       RTE_FLOW_FIELD_METER_COLOR,     /**< Meter color marker. */
> > +     RTE_FLOW_FIELD_FLEX_ITEM,       /**< Flex item. */
> >   };
> >
> >   /**
> > @@ -3541,8 +3542,11 @@ struct rte_flow_action_modify_data {
> >       RTE_STD_C11
> >       union {
> >               struct {
> > -                     /** Encapsulation level or tag index. */
> > -                     uint32_t level;
> > +                     /**< Encapsulation level or tag index or flex
> > + item handle. */
> 
> Have you tried to generate documentation? If it is a union documentation it
> should be /**, not /**<.
> In general, it is better to document union from overall point of view. What is it
> logically? Do not define union as just a union of its fields.
> 
> > +                     union {
> > +                             uint32_t level;
> > +                             struct rte_flow_item_flex_handle
> > + *flex_handle;
> 
> Union items documentation missing.
Added it in the "rte_flow.rst" following ``level`` segment.
> 
> > +                     };
> >                       /** Number of bits to skip from a field. */
> >                       uint32_t offset;
> >               };
  
Rongwei Liu Jan. 30, 2023, 1:19 p.m. UTC | #4
Support flex item matching and modify field in async flow.
Syntax follows sync flow exactly.

v3: enhance format, add flex_handle document.

Rongwei Liu (11):
  ethdev: add flex item modify field support
  app/testpmd: pass flex handle into matching mask
  net/mlx5: enable hws flex item create
  net/mlx5: add IPv6 protocol as flex item input
  net/mlx5: adopt new flex item prm definition
  net/mlx5/hws: add hws flex item matching support
  net/mlx5: add flex item modify field implementation
  net/mlx5: return error for sws modify field
  app/testpmd: raw encap with flex item support
  doc/mlx5: update mlx5 doc
  app/testpmd: adjust cleanup sequence when quitting

 app/test-pmd/cmdline_flow.c            | 123 +++++++++++++---
 app/test-pmd/testpmd.c                 |   2 +-
 doc/guides/nics/mlx5.rst               |   1 +
 doc/guides/prog_guide/rte_flow.rst     |  41 +++---
 doc/guides/rel_notes/release_23_03.rst |   4 +
 drivers/common/mlx5/mlx5_devx_cmds.c   |  14 +-
 drivers/common/mlx5/mlx5_devx_cmds.h   |   7 +-
 drivers/common/mlx5/mlx5_prm.h         |  29 +++-
 drivers/net/mlx5/hws/mlx5dr_definer.c  |  83 +++++++++++
 drivers/net/mlx5/linux/mlx5_os.c       |  27 ++--
 drivers/net/mlx5/mlx5.c                |  17 ++-
 drivers/net/mlx5/mlx5.h                |   9 +-
 drivers/net/mlx5/mlx5_flow.h           |   4 +
 drivers/net/mlx5/mlx5_flow_dv.c        | 186 ++++++++++++++++++++++---
 drivers/net/mlx5/mlx5_flow_flex.c      | 149 +++++++++++++++++---
 drivers/net/mlx5/mlx5_flow_hw.c        |  64 ++++++++-
 lib/ethdev/rte_flow.h                  |   8 +-
 17 files changed, 664 insertions(+), 104 deletions(-)
  

Patch

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..323c07253d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -601,10 +601,12 @@  enum index {
 	ACTION_MODIFY_FIELD_DST_TYPE,
 	ACTION_MODIFY_FIELD_DST_TYPE_VALUE,
 	ACTION_MODIFY_FIELD_DST_LEVEL,
+	ACTION_MODIFY_FIELD_DST_LEVEL_VALUE,
 	ACTION_MODIFY_FIELD_DST_OFFSET,
 	ACTION_MODIFY_FIELD_SRC_TYPE,
 	ACTION_MODIFY_FIELD_SRC_TYPE_VALUE,
 	ACTION_MODIFY_FIELD_SRC_LEVEL,
+	ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE,
 	ACTION_MODIFY_FIELD_SRC_OFFSET,
 	ACTION_MODIFY_FIELD_SRC_VALUE,
 	ACTION_MODIFY_FIELD_SRC_POINTER,
@@ -807,7 +809,8 @@  static const char *const modify_field_ids[] = {
 	"udp_port_src", "udp_port_dst",
 	"vxlan_vni", "geneve_vni", "gtp_teid",
 	"tag", "mark", "meta", "pointer", "value",
-	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL
+	"ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color",
+	"hash_result", "flex_item", NULL
 };
 
 static const char *const meter_colors[] = {
@@ -2282,6 +2285,10 @@  parse_vc_modify_field_id(struct context *ctx, const struct token *token,
 				const char *str, unsigned int len, void *buf,
 				unsigned int size);
 static int
+parse_vc_modify_field_level(struct context *ctx, const struct token *token,
+				const char *str, unsigned int len, void *buf,
+				unsigned int size);
+static int
 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,
 			 const char *str, unsigned int len, void *buf,
 			 unsigned int size);
@@ -5976,11 +5983,15 @@  static const struct token token_list[] = {
 		.name = "dst_level",
 		.help = "destination field level",
 		.next = NEXT(action_modify_field_dst,
-			     NEXT_ENTRY(COMMON_UNSIGNED)),
-		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
-					dst.level)),
+			     NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = {
+		.name = "{dst_level}",
+		.help = "destination field level value",
+		.call = parse_vc_modify_field_level,
+		.comp = comp_none,
+	},
 	[ACTION_MODIFY_FIELD_DST_OFFSET] = {
 		.name = "dst_offset",
 		.help = "destination field bit offset",
@@ -6007,11 +6018,15 @@  static const struct token token_list[] = {
 		.name = "src_level",
 		.help = "source field level",
 		.next = NEXT(action_modify_field_src,
-			     NEXT_ENTRY(COMMON_UNSIGNED)),
-		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,
-					src.level)),
+			     NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = {
+		.name = "{src_level}",
+		.help = "source field level value",
+		.call = parse_vc_modify_field_level,
+		.comp = comp_none,
+	},
 	[ACTION_MODIFY_FIELD_SRC_OFFSET] = {
 		.name = "src_offset",
 		.help = "source field bit offset",
@@ -8477,6 +8492,66 @@  parse_vc_modify_field_id(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse level for modify_field command. */
+static int
+parse_vc_modify_field_level(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len, void *buf,
+			 unsigned int size)
+{
+	struct rte_flow_action_modify_field *action;
+	struct flex_item *fp;
+	uint32_t val;
+	struct buffer *out = buf;
+	char *end;
+
+	(void)token;
+	(void)size;
+	if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE &&
+		ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)
+		return -1;
+	if (!ctx->object)
+		return len;
+	action = ctx->object;
+	errno = 0;
+	val = strtoumax(str, &end, 0);
+	if (errno || (size_t)(end - str) != len)
+		return -1;
+	/* No need to validate action template mask value */
+	if (out->args.vc.masks) {
+		if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)
+			action->dst.level = val;
+		else
+			action->src.level = val;
+		return len;
+	}
+	if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE &&
+		action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) ||
+		(ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE &&
+		action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) {
+		if (val >= FLEX_MAX_PARSERS_NUM) {
+			printf("Bad flex item handle\n");
+			return -1;
+		}
+		fp = flex_items[ctx->port][val];
+		if (!fp) {
+			printf("Bad flex item handle\n");
+			return -1;
+		}
+	}
+	if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) {
+		if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM)
+			action->dst.level = val;
+		else
+			action->dst.flex_handle = fp->flex_handle;
+	} else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) {
+		if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM)
+			action->src.level = val;
+		else
+			action->src.flex_handle = fp->flex_handle;
+	}
+	return len;
+}
+
 /** Parse the conntrack update, not a rte_flow_action. */
 static int
 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..e9baf31001 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2952,23 +2952,27 @@  value as sequence of bytes {xxx, xxx, 0x85, xxx, xxx, xxx}.
 
 .. table:: destination/source field definition
 
-   +---------------+----------------------------------------------------------+
-   | Field         | Value                                                    |
-   +===============+==========================================================+
-   | ``field``     | ID: packet field, mark, meta, tag, immediate, pointer    |
-   +---------------+----------------------------------------------------------+
-   | ``level``     | encapsulation level of a packet field or tag array index |
-   +---------------+----------------------------------------------------------+
-   | ``offset``    | number of bits to skip at the beginning                  |
-   +---------------+----------------------------------------------------------+
-   | ``value``     | immediate value buffer (source field only, not           |
-   |               | applicable to destination) for RTE_FLOW_FIELD_VALUE      |
-   |               | field type                                               |
-   +---------------+----------------------------------------------------------+
-   | ``pvalue``    | pointer to immediate value data (source field only, not  |
-   |               | applicable to destination) for RTE_FLOW_FIELD_POINTER    |
-   |               | field type                                               |
-   +---------------+----------------------------------------------------------+
+   +-----------------+----------------------------------------------------------+
+   | Field           | Value                                                    |
+   +=================+==========================================================+
+   | ``field``       | ID: packet field, mark, meta, tag, immediate, pointer    |
+   +-----------------+----------------------------------------------------------+
+   | ``level``       | encapsulation level of a packet field or tag array index |
+   +-----------------+----------------------------------------------------------+
+   | ``flex_handle`` | flex item handle of a packet field                       |
+   +-----------------+----------------------------------------------------------+
+   | ``offset``      | number of bits to skip at the beginning                  |
+   +-----------------+----------------------------------------------------------+
+   | ``value``       | immediate value buffer (source field only, not           |
+   |                 | applicable to destination) for RTE_FLOW_FIELD_VALUE      |
+   |                 | field type                                               |
+   |                 | This field is only 16 bytes, maybe not big enough for    |
+   |                 | all NICs' flex item                                      |
+   +-----------------+----------------------------------------------------------+
+   | ``pvalue``      | pointer to immediate value data (source field only, not  |
+   |                 | applicable to destination) for RTE_FLOW_FIELD_POINTER    |
+   |                 | field type                                               |
+   +-----------------+----------------------------------------------------------+
 
 Action: ``CONNTRACK``
 ^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index b8c5b68d6c..c673205e5e 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -56,6 +56,10 @@  New Features
      =======================================================
 
 
+* ethdev: added a new field:
+
+  - modify flex item: ``rte_flow_action_modify_data.flex_handle``
+
 Removed Items
 -------------
 
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..c66a65351d 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -3528,6 +3528,7 @@  enum rte_flow_field_id {
 	RTE_FLOW_FIELD_IPV6_ECN,	/**< IPv6 ECN. */
 	RTE_FLOW_FIELD_GTP_PSC_QFI,	/**< GTP QFI. */
 	RTE_FLOW_FIELD_METER_COLOR,	/**< Meter color marker. */
+	RTE_FLOW_FIELD_FLEX_ITEM,	/**< Flex item. */
 };
 
 /**
@@ -3541,8 +3542,11 @@  struct rte_flow_action_modify_data {
 	RTE_STD_C11
 	union {
 		struct {
-			/** Encapsulation level or tag index. */
-			uint32_t level;
+			/**< Encapsulation level or tag index or flex item handle. */
+			union {
+				uint32_t level;
+				struct rte_flow_item_flex_handle *flex_handle;
+			};
 			/** Number of bits to skip from a field. */
 			uint32_t offset;
 		};