[dpdk-dev,v3,3/4] ethdev: add TTL change actions in flow API

Message ID 20180416051639.188034-4-qi.z.zhang@intel.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Qi Zhang April 16, 2018, 5:16 a.m. UTC
  Add couple OpenFlow frienldy TTL change actions.

RTE_FLOW_ACTION_MLPS_TTL_DEC - decrement MPLS TTL.
RTE_FLOW_ACTION_IP_TTL_DEC - decrement IP TTL.
RTE_FLOW_ACTION_TTL_COPY_OUT - copy TTL outwards.
RTE_FLOW_ACTION_TTL_COPY_IN - copy TTL inwards.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 app/test-pmd/cmdline_flow.c                 | 64 +++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst          | 80 +++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 12 +++++
 lib/librte_ether/rte_flow.h                 | 77 +++++++++++++++++++++++++++
 4 files changed, 233 insertions(+)
  

Comments

Shahaf Shuler April 16, 2018, 5:48 a.m. UTC | #1
Hi Qi,

Am wondering if we can make the below more generic and not tailored for specific use cases. 

Monday, April 16, 2018 8:17 AM, Qi Zhang:
> Subject: [dpdk-dev] [PATCH v3 3/4] ethdev: add TTL change actions in flow
> API
> 
> Add couple OpenFlow frienldy TTL change actions.
> 
> RTE_FLOW_ACTION_MLPS_TTL_DEC - decrement MPLS TTL.
> RTE_FLOW_ACTION_IP_TTL_DEC - decrement IP TTL.
> RTE_FLOW_ACTION_TTL_COPY_OUT - copy TTL outwards.
> RTE_FLOW_ACTION_TTL_COPY_IN - copy TTL inwards.
> 
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
>  app/test-pmd/cmdline_flow.c                 | 64 +++++++++++++++++++++++
>  doc/guides/prog_guide/rte_flow.rst          | 80
> +++++++++++++++++++++++++++++
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst | 12 +++++
>  lib/librte_ether/rte_flow.h                 | 77 +++++++++++++++++++++++++++
>  4 files changed, 233 insertions(+)

[...]

> 
>  /** 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 ea0e40a52..e81f0e375 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1588,6 +1588,86 @@ contain respective protocol layer.
>     |  ``mask``     | Bit-mask applied to new_val                                       |
>     +---------------+-------------------------------------------------------------------+
> 
> +Action: ``MPLS_TTL_DEC``
> +^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Decrement MPLS TTL, only applies to packets that contain specific MPLS
> +headers.
> +
> +.. _table_rte_flow_action_mpls_ttl_dec:
> +
> +.. table:: MPLS_TTL_DEC
> +
> +   +---------------+---------------------------------------------+
> +   | Field         | Value                                       |
> +
> +===============+=========================================
> ====+
> +   | ``dir_level`` | Specify the level of MPLS header.           |
> +   |               | direction (1b)                              |
> +   |               | 0: match start from outermost.              |
> +   |               | 1: match start from innermost.              |
> +   |               | level: (31b)                                |
> +   |               | 0: outermost or innermost MPLS header       |
> +   |               | 1: next to outmost or innermost MPLS header |
> +   |               | 2: and so on ...                            |
> +   +---------------+---------------------------------------------+

Why not exposing it is as generic operation: increment/decrement for any type of header.
The action struct will receive the flow item type to modify, list of increment/decrement values for each of its fields (+x/-y) along with corresponding mask?

It is true the main use case is TTL decrement for vRouters, however It will save the duplication of the TTL_DEC action below and maybe we will not need to modify the API for future similar actions.


> +
> +Action: ``IP_TTL_DEC``
> +^^^^^^^^^^^^^^^^^^^^^^
> +
> +Decrement IPv4 TTL or IPv6 hop limit field and update the IP checksum,
> +only applies to packets that contain specific MPLS headers.
> +
> +.. _table_rte_flow_action_ip_ttl_dec:
> +
> +.. table:: IP_TTL_DEC
> +
> +   +---------------+----------------------------------------------------------+
> +   | Field         | Value                                                    |
> +
> +===============+=========================================
> =================+
> +   | ``dir_level`` | Specify the level of IPv4 or IPv6 header.                |
> +   |               | direction (1b)                                           |
> +   |               | 0: match start from outermost.                           |
> +   |               | 1: match start from innermost.                           |
> +   |               | level: (31b)                                             |
> +   |               | 0: outermost or innermost Ipv4 or IPv6 header            |
> +   |               | 1: next to outmost or innermost MPLS IPv4 or IPv6 header |
> +   |               | 2: and so on ...                                         |
> +
> + +---------------+-----------------------------------------------------
> + -----+
> +
> +Action: ``TTL_COPY_OUT``
> +^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Copy the TTL from next-to-outermost to outermost header with TTL, copy
> +can be IP to IP, MPLS to MPLS or IP to MPLS, only applies packets that
> +contain required MPLS or IP headers.
> +
> +.. _table_rte_flow_action_ttl_copy_out:
> +
> +.. table:: TTL_COPY_OUT
> +
> +   +---------------+
> +   | Field         |
> +   +===============+
> +   | no properties |
> +   +---------------+

Why only the TTL ? and why only from outermost to next-to-outer-most? 

We can have an action to copy field from flow item to another flow item. 
We will need flow item for src + mask for the field to copy, flow item for dst + mask for the field to set

> +
> +Action: ``TTL_COPY_IN``
> +^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Copy the TTL from outermost to next-to-outermost header with TTL, copy
> +can be IP to IP, MPLS to MPLS or MPLS to IP, only applies packets that
> +contain required MPLS or IP headers.
> +
> +.. _table_rte_flow_action_ttl_copy_in:
> +
> +.. table:: TTL_COPY_IN
> +
> +   +---------------+
> +   | Field         |
> +   +===============+
> +   | no properties |
> +   +---------------+
> +
>  Negative types
>  ~~~~~~~~~~~~~~
> 
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 48688600e..4dd86f10e 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3442,6 +3442,18 @@ This section lists supported actions and their
> attributes, if any.
>    - ``original {boolean}``: use original VF ID if possible.
>    - ``id {unsigned}``: VF ID to redirect packets to.
> 
> +- ``mpls_ttl_dec``: decrement MPLS TTL.
> +
> +  - ``level``: level of MPLS header.
> +
> +- ``ip_ttl_dec``: decrement IPv4 TTL or IPv6 Hot Limit.
> +
> +  - ``level``: level of IPv4 or IPv6 header.
> +
> +- ``ttl_copy_out``: copy TTL outwards.
> +
> +- ``ttl_copy_in``: copy TTL inwards.
> +
>  Destroying flow rules
>  ~~~~~~~~~~~~~~~~~~~~~
> 
> diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h index
> 80cf75ff0..96a236945 100644
> --- a/lib/librte_ether/rte_flow.h
> +++ b/lib/librte_ether/rte_flow.h
> @@ -1250,6 +1250,37 @@ enum rte_flow_action_type {
>  	 * See struct rte_flow_action_field_set.
>  	 */
>  	RTE_FLOW_ACTION_TYPE_FIELD_SET,
> +
> +	/**
> +	 * Decrement MPLS TTL, only applies to packets that contain specific
> +	 * MPLS header.
> +	 *
> +	 * See struct rte_flow_action_mpls_ttl_dec.
> +	 */
> +	RTE_FLOW_ACTION_TYPE_MPLS_TTL_DEC,
> +
> +	/**
> +	 * Decrement IPv4 TTL or IPv6 Hop limit field and update the IP
> +	 * checksum, only applies to packets that contain specific IPv4
> +	 * or IPv6 header.
> +	 *
> +	 * See struct rte_flow_action_ip_ttl_dec.
> +	 */
> +	RTE_FLOW_ACTION_TYPE_IP_TTL_DEC,
> +
> +	/**
> +	 * Copy the TTL from next-to-outermost to outermost header with
> TTL,
> +	 * copy can be IP to IP, MPLS to MPLS or IP to MPLS, only applies
> +	 * packets that contain required protocol headers.
> +	 */
> +	RTE_FLOW_ACTION_TYPE_TTL_COPY_OUT,
> +
> +	/**
> +	 * Copy the TTL from outermost to next-to-outermost header with
> TTL,
> +	 * copy can be IP to IP, MPLS to MPLS or MPLS to IP, only applies
> +	 * packets that contain required protocol headers.
> +	 */
> +	RTE_FLOW_ACTION_TYPE_TTL_COPY_IN,
>  };
> 
>  /**
> @@ -1420,6 +1451,52 @@ struct rte_flow_action_field_set {  };
> 
>  /**
> + * RTE_FLOW_ACTION_TYPE_MPLS_TTL_DEC
> + *
> + * Decrement MPLS TTL, only applies to packets that contain specific
> + * MPLS header.
> + */
> +struct rte_flow_action_mpls_ttl_dec {
> +	/**
> +	 * Specify the level of MPLS header.
> +	 *
> +	 * direction (1b)
> +	 * 0: match start from outermost.
> +	 * 1: match start from innermost.
> +	 *
> +	 * level (31b)
> +	 * 0: outermost|innermost MPLS header.
> +	 * 1: next to outermost|innermost MPLS header.
> +	 * 2: and so on ...
> +	 */
> +	uint32_t dir_level;
> +
> +};
> +
> +/**
> + * RTE_FLOW_ACTION_TYPE_IP_TTL_DEC
> + *
> + * Decrement IPv4 TTL or IPv6 hop limit field and update the IP
> + * checksum, only applies to packets that contain specific IPv4
> + * or IPv6 header.
> + */
> +struct rte_flow_action_ip_ttl_dec {
> +	/**
> +	 * Specify the level of IPv4 or IPv6 header.
> +	 *
> +	 * direction (1b)
> +	 * 0: match start from outermost.
> +	 * 1: match start from innermost.
> +	 *
> +	 * level (31b)
> +	 * 0: outermost|innermost IPv4 or IPv6 header.
> +	 * 1: next to outermost|innermost IPv4 or IPv6 header.
> +	 * 2: and so on ...
> +	 */
> +	uint32_t dir_level;
> +};
> +
> +/**
>   * Definition of a single action.
>   *
>   * A list of actions is terminated by a END action.
> --
> 2.13.6
  
Adrien Mazarguil April 16, 2018, 8:12 a.m. UTC | #2
Hi Shahaf,

On Mon, Apr 16, 2018 at 05:48:19AM +0000, Shahaf Shuler wrote:
> Hi Qi,
> 
> Am wondering if we can make the below more generic and not tailored for specific use cases. 

Regarding this, please see my previous answer [1] where I asked Qi to make
his changes more focused on the use case at hand when it became clear all
this work was targeting OpenFlow.

The OF specification [2] defines the behavior associated with each action,
for instance when a TTL is 0 or decrementing it would yield 0, the packet
must be dropped. Translating this to a generic decrement action for any
packet field is not so easy and not convenient.

Therefore my opinion is that if OF actions as defined by this specification
are supported as hardware capabilities, it makes sense to define dedicated
rte_flow actions for each of them (although "OF" should be part of their
name for clarity).

I'll comment the patch proper in a separate message.

[1] http://dpdk.org/ml/archives/dev/2018-April/096857.html
[2] https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.0.pdf
  
Shahaf Shuler April 16, 2018, 8:56 a.m. UTC | #3
Monday, April 16, 2018 11:12 AM, Adrien Mazarguil:
> Subject: Re: [dpdk-dev] [PATCH v3 3/4] ethdev: add TTL change actions in
> flow API
> 
> Hi Shahaf,
> 
> On Mon, Apr 16, 2018 at 05:48:19AM +0000, Shahaf Shuler wrote:
> > Hi Qi,
> >
> > Am wondering if we can make the below more generic and not tailored for
> specific use cases.
> 
> Regarding this, please see my previous answer [1] where I asked Qi to make
> his changes more focused on the use case at hand when it became clear all
> this work was targeting OpenFlow.

OK,
I missed that. Sorry for jumping in late.

> 
> The OF specification [2] defines the behavior associated with each action, for
> instance when a TTL is 0 or decrementing it would yield 0, the packet must be
> dropped. Translating this to a generic decrement action for any packet field is
> not so easy and not convenient.

I am not sure I understand why. It is to set -1 in the TTL field of the generic action. 
We can define the corner cases more carefully as part of the actions. For example - no wrap around. 
I did not understood the drop if TTL is 0 is part of the action (it is not described the action description[1]).
Is this the case? 

I think it is wrong approach to introduce a "combo" actions (both decrements and drops if value) in rte_flow. 
I would model such  operation by a set of (pseudo code)
1. ACTION_FIELD_DEC_INC , ACTION_GO_TO_GROUP
2. (in next group) matching on the TTL , ACTION_DROP 

> 
> Therefore my opinion is that if OF actions as defined by this specification are
> supported as hardware capabilities, it makes sense to define dedicated
> rte_flow actions for each of them (although "OF" should be part of their
> name for clarity).

I still think we may need in the future to support copy/increment/decrement of fields not specifically related to OF. 
It is better to have APIs which will not change or have double meaning. 


[1]
[1]
+Action: ``IP_TTL_DEC``
+^^^^^^^^^^^^^^^^^^^^^^
+
+Decrement IPv4 TTL or IPv6 hop limit field and update the IP checksum, 
+only applies to packets that contain specific MPLS headers.
+
+.. _table_rte_flow_action_ip_ttl_dec:
+
+.. table:: IP_TTL_DEC


> 
> I'll comment the patch proper in a separate message.
> 
> [1]
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdpd
> k.org%2Fml%2Farchives%2Fdev%2F2018-
> April%2F096857.html&data=02%7C01%7Cshahafs%40mellanox.com%7C6d2b
> 747ae47841bc55e508d5a371d2f4%7Ca652971c7d2e4d9ba6a4d149256f461b%7
> C0%7C0%7C636594631626247567&sdata=3oTbKT6QwS1WiAIrkF885dEU76ep4
> xreuHoHiwDA2Ec%3D&reserved=0
> [2]
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fw
> ww.opennetworking.org%2Fimages%2Fstories%2Fdownloads%2Fsdn-
> resources%2Fonf-specifications%2Fopenflow%2Fopenflow-spec-
> v1.3.0.pdf&data=02%7C01%7Cshahafs%40mellanox.com%7C6d2b747ae4784
> 1bc55e508d5a371d2f4%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C1%
> 7C636594631626247567&sdata=e6uelVwIu1poE2uIvEJELuIzela8H%2B8HclQE5
> EdKEaM%3D&reserved=0
> 
> --
> Adrien Mazarguil
> 6WIND
  
Adrien Mazarguil April 16, 2018, 9:59 a.m. UTC | #4
On Mon, Apr 16, 2018 at 08:56:37AM +0000, Shahaf Shuler wrote:
> Monday, April 16, 2018 11:12 AM, Adrien Mazarguil:
> > Subject: Re: [dpdk-dev] [PATCH v3 3/4] ethdev: add TTL change actions in
> > flow API
> > 
> > Hi Shahaf,
> > 
> > On Mon, Apr 16, 2018 at 05:48:19AM +0000, Shahaf Shuler wrote:
> > > Hi Qi,
> > >
> > > Am wondering if we can make the below more generic and not tailored for
> > specific use cases.
> > 
> > Regarding this, please see my previous answer [1] where I asked Qi to make
> > his changes more focused on the use case at hand when it became clear all
> > this work was targeting OpenFlow.
> 
> OK,
> I missed that. Sorry for jumping in late.
> 
> > 
> > The OF specification [2] defines the behavior associated with each action, for
> > instance when a TTL is 0 or decrementing it would yield 0, the packet must be
> > dropped. Translating this to a generic decrement action for any packet field is
> > not so easy and not convenient.
> 
> I am not sure I understand why. It is to set -1 in the TTL field of the generic action. 
> We can define the corner cases more carefully as part of the actions. For example - no wrap around. 
> I did not understood the drop if TTL is 0 is part of the action (it is not described the action description[1]).
> Is this the case? 

I still need to comment the original patch :)

Basically I would like to make all these actions point to the OpenFlow
action documentation describing them with a disclaimer such as "These are
OpenFlow actions, here's a summary of what they do, see linked OF
documentation for details".

> I think it is wrong approach to introduce a "combo" actions (both decrements and drops if value) in rte_flow. 
> I would model such  operation by a set of (pseudo code)
> 1. ACTION_FIELD_DEC_INC , ACTION_GO_TO_GROUP
> 2. (in next group) matching on the TTL , ACTION_DROP 

If a device really implements something that does "check TTL on protocol $FOO,
decrement it, re-check TTL, update checksum, drop packet if any of the
previous steps failed", then by all means I think a dedicated action is
justified. It's also easier to document as "does what OpenFlow specifies"
and much more convenient to applications.

Another set of actions can be added for devices (or PMDs) with partial
support (e.g. to expose a "dumb" decrement capability as in the original
series).

The real question is are there devices that fully implement OF actions as
described by the linked spec? Can any missing bits be handled by PMDs
without a noticeable performance impact?

> > Therefore my opinion is that if OF actions as defined by this specification are
> > supported as hardware capabilities, it makes sense to define dedicated
> > rte_flow actions for each of them (although "OF" should be part of their
> > name for clarity).
> 
> I still think we may need in the future to support copy/increment/decrement of fields not specifically related to OF. 
> It is better to have APIs which will not change or have double meaning. 

We could add them later on a needed basis. Correct me if I'm wrong, but
right now OF is the only use case everyone has in mind. Application
developers will always favor a set of explicit OF actions over more
convoluted means of achieving the expected behavior.

> [1]
> +Action: ``IP_TTL_DEC``
> +^^^^^^^^^^^^^^^^^^^^^^
> +
> +Decrement IPv4 TTL or IPv6 hop limit field and update the IP checksum, 
> +only applies to packets that contain specific MPLS headers.
> +
> +.. _table_rte_flow_action_ip_ttl_dec:
> +
> +.. table:: IP_TTL_DEC
> 
> 
> > 
> > I'll comment the patch proper in a separate message.
> > 
> > [1]
> > https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdpd
> > k.org%2Fml%2Farchives%2Fdev%2F2018-
> > April%2F096857.html&data=02%7C01%7Cshahafs%40mellanox.com%7C6d2b
> > 747ae47841bc55e508d5a371d2f4%7Ca652971c7d2e4d9ba6a4d149256f461b%7
> > C0%7C0%7C636594631626247567&sdata=3oTbKT6QwS1WiAIrkF885dEU76ep4
> > xreuHoHiwDA2Ec%3D&reserved=0
> > [2]
> > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fw
> > ww.opennetworking.org%2Fimages%2Fstories%2Fdownloads%2Fsdn-
> > resources%2Fonf-specifications%2Fopenflow%2Fopenflow-spec-
> > v1.3.0.pdf&data=02%7C01%7Cshahafs%40mellanox.com%7C6d2b747ae4784
> > 1bc55e508d5a371d2f4%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C1%
> > 7C636594631626247567&sdata=e6uelVwIu1poE2uIvEJELuIzela8H%2B8HclQE5
> > EdKEaM%3D&reserved=0
> > 
> > --
> > Adrien Mazarguil
> > 6WIND
  

Patch

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index a5e21c1fe..fa35ecc6d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -190,6 +190,12 @@  enum index {
 	ACTION_VF_ID,
 	ACTION_METER,
 	ACTION_METER_ID,
+	ACTION_MPLS_TTL_DEC,
+	ACTION_MPLS_TTL_DEC_LVL,
+	ACTION_IP_TTL_DEC,
+	ACTION_IP_TTL_DEC_LVL,
+	ACTION_TTL_COPY_OUT,
+	ACTION_TTL_COPY_IN,
 };
 
 /** Size of pattern[] field in struct rte_flow_item_raw. */
@@ -654,6 +660,10 @@  static const enum index next_action[] = {
 	ACTION_PF,
 	ACTION_VF,
 	ACTION_METER,
+	ACTION_MPLS_TTL_DEC,
+	ACTION_IP_TTL_DEC,
+	ACTION_TTL_COPY_OUT,
+	ACTION_TTL_COPY_IN,
 	ZERO,
 };
 
@@ -694,6 +704,16 @@  static const enum index action_meter[] = {
 	ZERO,
 };
 
+static const enum index action_mpls_ttl_dec[] = {
+	ACTION_MPLS_TTL_DEC_LVL,
+	ZERO,
+};
+
+static const enum index action_ip_ttl_dec[] = {
+	ACTION_IP_TTL_DEC_LVL,
+	ZERO,
+};
+
 static int parse_init(struct context *, const struct token *,
 		      const char *, unsigned int,
 		      void *, unsigned int);
@@ -1807,6 +1827,50 @@  static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_MPLS_TTL_DEC] = {
+		.name = "mpls_ttl_dec",
+		.help = "decrement MPLS TTL",
+		.priv = PRIV_ACTION(MPLS_TTL_DEC,
+				sizeof(struct rte_flow_action_mpls_ttl_dec)),
+		.next = NEXT(action_mpls_ttl_dec),
+		.call = parse_vc,
+	},
+	[ACTION_MPLS_TTL_DEC_LVL] = {
+		.name = "level",
+		.help = "level of MPLS header",
+		.next = NEXT(action_mpls_ttl_dec, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
+		.call = parse_vc,
+	},
+	[ACTION_IP_TTL_DEC] = {
+		.name = "ip_ttl_dec",
+		.help = "decrement IPv4 TTL or IPv6 Hop Limit",
+		.priv = PRIV_ACTION(MPLS_TTL_DEC,
+				sizeof(struct rte_flow_action_ip_ttl_dec)),
+		.next = NEXT(action_ip_ttl_dec),
+		.call = parse_vc,
+	},
+	[ACTION_IP_TTL_DEC_LVL] = {
+		.name = "level",
+		.help = "level of IPv4 or IPv6 header",
+		.next = NEXT(action_ip_ttl_dec, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
+		.call = parse_vc,
+	},
+	[ACTION_TTL_COPY_OUT] = {
+		.name = "ttl_copy_out",
+		.help = "copy TTL  outwards",
+		.priv = PRIV_ACTION(DROP, 0),
+		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+		.call = parse_vc,
+	},
+	[ACTION_TTL_COPY_IN] = {
+		.name = "ttl_copy_in",
+		.help = "copy TTL  inwards",
+		.priv = PRIV_ACTION(DROP, 0),
+		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+		.call = parse_vc,
+	},
 };
 
 /** 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 ea0e40a52..e81f0e375 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1588,6 +1588,86 @@  contain respective protocol layer.
    |  ``mask``     | Bit-mask applied to new_val                                       |
    +---------------+-------------------------------------------------------------------+
 
+Action: ``MPLS_TTL_DEC``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Decrement MPLS TTL, only applies to packets that contain specific MPLS
+headers.
+
+.. _table_rte_flow_action_mpls_ttl_dec:
+
+.. table:: MPLS_TTL_DEC
+
+   +---------------+---------------------------------------------+
+   | Field         | Value                                       |
+   +===============+=============================================+
+   | ``dir_level`` | Specify the level of MPLS header.           |
+   |               | direction (1b)                              |
+   |               | 0: match start from outermost.              |
+   |               | 1: match start from innermost.              |
+   |               | level: (31b)                                |
+   |               | 0: outermost or innermost MPLS header       |
+   |               | 1: next to outmost or innermost MPLS header |
+   |               | 2: and so on ...                            |
+   +---------------+---------------------------------------------+
+
+Action: ``IP_TTL_DEC``
+^^^^^^^^^^^^^^^^^^^^^^
+
+Decrement IPv4 TTL or IPv6 hop limit field and update the IP checksum,
+only applies to packets that contain specific MPLS headers.
+
+.. _table_rte_flow_action_ip_ttl_dec:
+
+.. table:: IP_TTL_DEC
+
+   +---------------+----------------------------------------------------------+
+   | Field         | Value                                                    |
+   +===============+==========================================================+
+   | ``dir_level`` | Specify the level of IPv4 or IPv6 header.                |
+   |               | direction (1b)                                           |
+   |               | 0: match start from outermost.                           |
+   |               | 1: match start from innermost.                           |
+   |               | level: (31b)                                             |
+   |               | 0: outermost or innermost Ipv4 or IPv6 header            |
+   |               | 1: next to outmost or innermost MPLS IPv4 or IPv6 header |
+   |               | 2: and so on ...                                         |
+   +---------------+----------------------------------------------------------+
+
+Action: ``TTL_COPY_OUT``
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Copy the TTL from next-to-outermost to outermost header with TTL, copy can
+be IP to IP, MPLS to MPLS or IP to MPLS, only applies packets that contain
+required MPLS or IP headers.
+
+.. _table_rte_flow_action_ttl_copy_out:
+
+.. table:: TTL_COPY_OUT
+
+   +---------------+
+   | Field         |
+   +===============+
+   | no properties |
+   +---------------+
+
+Action: ``TTL_COPY_IN``
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Copy the TTL from outermost to next-to-outermost header with TTL, copy can
+be IP to IP, MPLS to MPLS or MPLS to IP, only applies packets that contain
+required MPLS or IP headers.
+
+.. _table_rte_flow_action_ttl_copy_in:
+
+.. table:: TTL_COPY_IN
+
+   +---------------+
+   | Field         |
+   +===============+
+   | no properties |
+   +---------------+
+
 Negative types
 ~~~~~~~~~~~~~~
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 48688600e..4dd86f10e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3442,6 +3442,18 @@  This section lists supported actions and their attributes, if any.
   - ``original {boolean}``: use original VF ID if possible.
   - ``id {unsigned}``: VF ID to redirect packets to.
 
+- ``mpls_ttl_dec``: decrement MPLS TTL.
+
+  - ``level``: level of MPLS header.
+
+- ``ip_ttl_dec``: decrement IPv4 TTL or IPv6 Hot Limit.
+
+  - ``level``: level of IPv4 or IPv6 header.
+
+- ``ttl_copy_out``: copy TTL outwards.
+
+- ``ttl_copy_in``: copy TTL inwards.
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 80cf75ff0..96a236945 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -1250,6 +1250,37 @@  enum rte_flow_action_type {
 	 * See struct rte_flow_action_field_set.
 	 */
 	RTE_FLOW_ACTION_TYPE_FIELD_SET,
+
+	/**
+	 * Decrement MPLS TTL, only applies to packets that contain specific
+	 * MPLS header.
+	 *
+	 * See struct rte_flow_action_mpls_ttl_dec.
+	 */
+	RTE_FLOW_ACTION_TYPE_MPLS_TTL_DEC,
+
+	/**
+	 * Decrement IPv4 TTL or IPv6 Hop limit field and update the IP
+	 * checksum, only applies to packets that contain specific IPv4
+	 * or IPv6 header.
+	 *
+	 * See struct rte_flow_action_ip_ttl_dec.
+	 */
+	RTE_FLOW_ACTION_TYPE_IP_TTL_DEC,
+
+	/**
+	 * Copy the TTL from next-to-outermost to outermost header with TTL,
+	 * copy can be IP to IP, MPLS to MPLS or IP to MPLS, only applies
+	 * packets that contain required protocol headers.
+	 */
+	RTE_FLOW_ACTION_TYPE_TTL_COPY_OUT,
+
+	/**
+	 * Copy the TTL from outermost to next-to-outermost header with TTL,
+	 * copy can be IP to IP, MPLS to MPLS or MPLS to IP, only applies
+	 * packets that contain required protocol headers.
+	 */
+	RTE_FLOW_ACTION_TYPE_TTL_COPY_IN,
 };
 
 /**
@@ -1420,6 +1451,52 @@  struct rte_flow_action_field_set {
 };
 
 /**
+ * RTE_FLOW_ACTION_TYPE_MPLS_TTL_DEC
+ *
+ * Decrement MPLS TTL, only applies to packets that contain specific
+ * MPLS header.
+ */
+struct rte_flow_action_mpls_ttl_dec {
+	/**
+	 * Specify the level of MPLS header.
+	 *
+	 * direction (1b)
+	 * 0: match start from outermost.
+	 * 1: match start from innermost.
+	 *
+	 * level (31b)
+	 * 0: outermost|innermost MPLS header.
+	 * 1: next to outermost|innermost MPLS header.
+	 * 2: and so on ...
+	 */
+	uint32_t dir_level;
+
+};
+
+/**
+ * RTE_FLOW_ACTION_TYPE_IP_TTL_DEC
+ *
+ * Decrement IPv4 TTL or IPv6 hop limit field and update the IP
+ * checksum, only applies to packets that contain specific IPv4
+ * or IPv6 header.
+ */
+struct rte_flow_action_ip_ttl_dec {
+	/**
+	 * Specify the level of IPv4 or IPv6 header.
+	 *
+	 * direction (1b)
+	 * 0: match start from outermost.
+	 * 1: match start from innermost.
+	 *
+	 * level (31b)
+	 * 0: outermost|innermost IPv4 or IPv6 header.
+	 * 1: next to outermost|innermost IPv4 or IPv6 header.
+	 * 2: and so on ...
+	 */
+	uint32_t dir_level;
+};
+
+/**
  * Definition of a single action.
  *
  * A list of actions is terminated by a END action.