[8/9] net/mlx5: add Forward Database table type

Message ID 1555276357-4892-9-git-send-email-orika@mellanox.com (mailing list archive)
State Superseded, archived
Delegated to: Shahaf Shuler
Headers
Series net/mlx5: add Direct Verbs E-Switch support |

Checks

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

Commit Message

Ori Kam April 14, 2019, 9:12 p.m. UTC
  Actions like encap/decap, modify header require setting the flow table
type. Until now we supported only Nic RX and Nic TX, this commits adds
the support for FDB table type for those actions.

Signed-off-by: Ori Kam <orika@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow_dv.c | 54 ++++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 14 deletions(-)
  

Comments

Yongseok Koh April 18, 2019, 1:16 a.m. UTC | #1
On Sun, Apr 14, 2019 at 09:12:36PM +0000, Ori Kam wrote:
> Actions like encap/decap, modify header require setting the flow table
> type. Until now we supported only Nic RX and Nic TX, this commits adds
> the support for FDB table type for those actions.
> 
> Signed-off-by: Ori Kam <orika@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5_flow_dv.c | 54 ++++++++++++++++++++++++++++++-----------
>  1 file changed, 40 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
> index f4b7f06..d4dc439 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -40,6 +40,10 @@
>  #define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0
>  #endif
>  
> +#ifndef HAVE_MLX5DV_DR_ESWITCH
> +#define MLX5DV_FLOW_TABLE_TYPE_FDB 0
> +#endif
> +
>  union flow_dv_attr {
>  	struct {
>  		uint32_t valid:1;
> @@ -943,7 +947,9 @@ struct field_modify_info modify_tcp[] = {
>  	struct mlx5dv_dr_ns *ns;
>  
>  	resource->flags = flow->group ? 0 : 1;
> -	if (flow->ingress)
> +	if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_FDB)
> +		ns = sh->fdb_ns;
> +	else if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_RX)
>  		ns = sh->rx_ns;
>  	else
>  		ns = sh->tx_ns;
> @@ -1364,6 +1370,8 @@ struct field_modify_info modify_tcp[] = {
>   *   Pointer to action structure.
>   * @param[in, out] dev_flow
>   *   Pointer to the mlx5_flow.
> + * @param[in] transfer
> + *   Mark if the flow is E-Switch flow.
>   * @param[out] error
>   *   Pointer to the error structure.
>   *
> @@ -1374,6 +1382,7 @@ struct field_modify_info modify_tcp[] = {
>  flow_dv_create_action_l2_encap(struct rte_eth_dev *dev,
>  			       const struct rte_flow_action *action,
>  			       struct mlx5_flow *dev_flow,
> +			       uint8_t transfer,
>  			       struct rte_flow_error *error)
>  {
>  	const struct rte_flow_item *encap_data;
> @@ -1384,6 +1393,8 @@ struct field_modify_info modify_tcp[] = {
>  		.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_TX,
>  	};
>  
> +	if (transfer)
> +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;

Why overwrite?
You could've done it above:

	struct mlx5_flow_dv_encap_decap_resource res = {
		.reformat_type =
			MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL,
  		.ft_type = transfer ? MLX5DV_FLOW_TABLE_TYPE_FDB :
				      MLX5DV_FLOW_TABLE_TYPE_NIC_TX,
	};

Same for the rest.

>  	if (action->type == RTE_FLOW_ACTION_TYPE_RAW_ENCAP) {
>  		raw_encap_data =
>  			(const struct rte_flow_action_raw_encap *)action->conf;
> @@ -1416,6 +1427,8 @@ struct field_modify_info modify_tcp[] = {
>   *   Pointer to rte_eth_dev structure.
>   * @param[in, out] dev_flow
>   *   Pointer to the mlx5_flow.
> + * @param[in] transfer
> + *   Mark if the flow is E-Switch flow.
>   * @param[out] error
>   *   Pointer to the error structure.
>   *
> @@ -1425,6 +1438,7 @@ struct field_modify_info modify_tcp[] = {
>  static int
>  flow_dv_create_action_l2_decap(struct rte_eth_dev *dev,
>  			       struct mlx5_flow *dev_flow,
> +			       uint8_t transfer,
>  			       struct rte_flow_error *error)
>  {
>  	struct mlx5_flow_dv_encap_decap_resource res = {
> @@ -1434,6 +1448,8 @@ struct field_modify_info modify_tcp[] = {
>  		.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_RX,
>  	};
>  
> +	if (transfer)
> +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
>  	if (flow_dv_encap_decap_resource_register(dev, &res, dev_flow, error))
>  		return rte_flow_error_set(error, EINVAL,
>  					  RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -1474,8 +1490,11 @@ struct field_modify_info modify_tcp[] = {
>  	res.reformat_type = attr->egress ?
>  		MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL :
>  		MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2;
> -	res.ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
> -				     MLX5DV_FLOW_TABLE_TYPE_NIC_RX;
> +	if (attr->transfer)
> +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
> +	else
> +		res.ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
> +					     MLX5DV_FLOW_TABLE_TYPE_NIC_RX;
>  	if (flow_dv_encap_decap_resource_register(dev, &res, dev_flow, error))
>  		return rte_flow_error_set(error, EINVAL,
>  					  RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -1810,11 +1829,14 @@ struct field_modify_info modify_tcp[] = {
>  	struct mlx5_priv *priv = dev->data->dev_private;
>  	struct mlx5_ibv_shared *sh = priv->sh;
>  	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
> +	struct mlx5dv_dr_ns *ns;
>  
> -	struct mlx5dv_dr_ns *ns =
> -		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX  ?
> -		sh->tx_ns : sh->rx_ns;
> -
> +	if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_FDB)
> +		ns = sh->fdb_ns;
> +	else if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX)
> +		ns = sh->tx_ns;
> +	else
> +		ns = sh->rx_ns;
>  	/* Lookup a matching resource from cache. */
>  	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
>  		if (resource->ft_type == cache_resource->ft_type &&
> @@ -3615,6 +3637,8 @@ struct field_modify_info modify_tcp[] = {
>  	union flow_dv_attr flow_attr = { .attr = 0 };
>  	struct mlx5_flow_dv_tag_resource tag_resource;
>  
> +	if (attr->transfer)
> +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;

This res has nothing to do with encap/decap but it is
mlx5_flow_dv_modify_hdr_resource.

Thanks,
Yongseok

>  	if (priority == MLX5_FLOW_PRIO_RSVD)
>  		priority = priv->config.flow_prio - 1;
>  	for (; !actions_end ; actions++) {
> @@ -3720,7 +3744,9 @@ struct field_modify_info modify_tcp[] = {
>  		case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
>  		case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
>  			if (flow_dv_create_action_l2_encap(dev, actions,
> -							   dev_flow, error))
> +							   dev_flow,
> +							   attr->transfer,
> +							   error))
>  				return -rte_errno;
>  			dev_flow->dv.actions[actions_n++] =
>  				dev_flow->dv.encap_decap->verbs_action;
> @@ -3732,6 +3758,7 @@ struct field_modify_info modify_tcp[] = {
>  		case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
>  		case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP:
>  			if (flow_dv_create_action_l2_decap(dev, dev_flow,
> +							   attr->transfer,
>  							   error))
>  				return -rte_errno;
>  			dev_flow->dv.actions[actions_n++] =
> @@ -3751,9 +3778,9 @@ struct field_modify_info modify_tcp[] = {
>  					dev_flow->dv.encap_decap->verbs_action;
>  			} else {
>  				/* Handle encap without preceding decap. */
> -				if (flow_dv_create_action_l2_encap(dev, actions,
> -								   dev_flow,
> -								   error))
> +				if (flow_dv_create_action_l2_encap
> +				    (dev, actions, dev_flow, attr->transfer,
> +				     error))
>  					return -rte_errno;
>  				dev_flow->dv.actions[actions_n++] =
>  					dev_flow->dv.encap_decap->verbs_action;
> @@ -3768,9 +3795,8 @@ struct field_modify_info modify_tcp[] = {
>  			}
>  			/* Handle decap only if it isn't followed by encap. */
>  			if (action->type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP) {
> -				if (flow_dv_create_action_l2_decap(dev,
> -								   dev_flow,
> -								   error))
> +				if (flow_dv_create_action_l2_decap
> +				    (dev, dev_flow, attr->transfer, error))
>  					return -rte_errno;
>  				dev_flow->dv.actions[actions_n++] =
>  					dev_flow->dv.encap_decap->verbs_action;
> -- 
> 1.8.3.1
>
  
Ori Kam April 18, 2019, 5:13 a.m. UTC | #2
Hi Yongseok,

PSB

> -----Original Message-----
> From: Yongseok Koh
> Sent: Thursday, April 18, 2019 4:16 AM
> To: Ori Kam <orika@mellanox.com>
> Cc: Shahaf Shuler <shahafs@mellanox.com>; Matan Azrad
> <matan@mellanox.com>; Slava Ovsiienko <viacheslavo@mellanox.com>; Moti
> Haimovsky <motih@mellanox.com>; dev@dpdk.org
> Subject: Re: [PATCH 8/9] net/mlx5: add Forward Database table type
> 
> On Sun, Apr 14, 2019 at 09:12:36PM +0000, Ori Kam wrote:
> > Actions like encap/decap, modify header require setting the flow table
> > type. Until now we supported only Nic RX and Nic TX, this commits adds
> > the support for FDB table type for those actions.
> >
> > Signed-off-by: Ori Kam <orika@mellanox.com>
> > ---
> >  drivers/net/mlx5/mlx5_flow_dv.c | 54 ++++++++++++++++++++++++++++++--
> ---------
> >  1 file changed, 40 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/net/mlx5/mlx5_flow_dv.c
> b/drivers/net/mlx5/mlx5_flow_dv.c
> > index f4b7f06..d4dc439 100644
> > --- a/drivers/net/mlx5/mlx5_flow_dv.c
> > +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> > @@ -40,6 +40,10 @@
> >  #define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0
> >  #endif
> >
> > +#ifndef HAVE_MLX5DV_DR_ESWITCH
> > +#define MLX5DV_FLOW_TABLE_TYPE_FDB 0
> > +#endif
> > +
> >  union flow_dv_attr {
> >  	struct {
> >  		uint32_t valid:1;
> > @@ -943,7 +947,9 @@ struct field_modify_info modify_tcp[] = {
> >  	struct mlx5dv_dr_ns *ns;
> >
> >  	resource->flags = flow->group ? 0 : 1;
> > -	if (flow->ingress)
> > +	if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_FDB)
> > +		ns = sh->fdb_ns;
> > +	else if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_RX)
> >  		ns = sh->rx_ns;
> >  	else
> >  		ns = sh->tx_ns;
> > @@ -1364,6 +1370,8 @@ struct field_modify_info modify_tcp[] = {
> >   *   Pointer to action structure.
> >   * @param[in, out] dev_flow
> >   *   Pointer to the mlx5_flow.
> > + * @param[in] transfer
> > + *   Mark if the flow is E-Switch flow.
> >   * @param[out] error
> >   *   Pointer to the error structure.
> >   *
> > @@ -1374,6 +1382,7 @@ struct field_modify_info modify_tcp[] = {
> >  flow_dv_create_action_l2_encap(struct rte_eth_dev *dev,
> >  			       const struct rte_flow_action *action,
> >  			       struct mlx5_flow *dev_flow,
> > +			       uint8_t transfer,
> >  			       struct rte_flow_error *error)
> >  {
> >  	const struct rte_flow_item *encap_data;
> > @@ -1384,6 +1393,8 @@ struct field_modify_info modify_tcp[] = {
> >  		.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_TX,
> >  	};
> >
> > +	if (transfer)
> > +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
> 
> Why overwrite?
> You could've done it above:
> 
> 	struct mlx5_flow_dv_encap_decap_resource res = {
> 		.reformat_type =
> 
> 	MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNN
> EL,
>   		.ft_type = transfer ? MLX5DV_FLOW_TABLE_TYPE_FDB :
> 				      MLX5DV_FLOW_TABLE_TYPE_NIC_TX,
> 	};
> 
> Same for the rest.
>

Will fix.

> >  	if (action->type == RTE_FLOW_ACTION_TYPE_RAW_ENCAP) {
> >  		raw_encap_data =
> >  			(const struct rte_flow_action_raw_encap *)action-
> >conf;
> > @@ -1416,6 +1427,8 @@ struct field_modify_info modify_tcp[] = {
> >   *   Pointer to rte_eth_dev structure.
> >   * @param[in, out] dev_flow
> >   *   Pointer to the mlx5_flow.
> > + * @param[in] transfer
> > + *   Mark if the flow is E-Switch flow.
> >   * @param[out] error
> >   *   Pointer to the error structure.
> >   *
> > @@ -1425,6 +1438,7 @@ struct field_modify_info modify_tcp[] = {
> >  static int
> >  flow_dv_create_action_l2_decap(struct rte_eth_dev *dev,
> >  			       struct mlx5_flow *dev_flow,
> > +			       uint8_t transfer,
> >  			       struct rte_flow_error *error)
> >  {
> >  	struct mlx5_flow_dv_encap_decap_resource res = {
> > @@ -1434,6 +1448,8 @@ struct field_modify_info modify_tcp[] = {
> >  		.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_RX,
> >  	};
> >
> > +	if (transfer)
> > +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
> >  	if (flow_dv_encap_decap_resource_register(dev, &res, dev_flow,
> error))
> >  		return rte_flow_error_set(error, EINVAL,
> >  					  RTE_FLOW_ERROR_TYPE_ACTION,
> > @@ -1474,8 +1490,11 @@ struct field_modify_info modify_tcp[] = {
> >  	res.reformat_type = attr->egress ?
> >
> 	MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNN
> EL :
> >
> 	MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_
> L2;
> > -	res.ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
> > -				     MLX5DV_FLOW_TABLE_TYPE_NIC_RX;
> > +	if (attr->transfer)
> > +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
> > +	else
> > +		res.ft_type = attr->egress ?
> MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
> > +
> MLX5DV_FLOW_TABLE_TYPE_NIC_RX;
> >  	if (flow_dv_encap_decap_resource_register(dev, &res, dev_flow,
> error))
> >  		return rte_flow_error_set(error, EINVAL,
> >  					  RTE_FLOW_ERROR_TYPE_ACTION,
> > @@ -1810,11 +1829,14 @@ struct field_modify_info modify_tcp[] = {
> >  	struct mlx5_priv *priv = dev->data->dev_private;
> >  	struct mlx5_ibv_shared *sh = priv->sh;
> >  	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
> > +	struct mlx5dv_dr_ns *ns;
> >
> > -	struct mlx5dv_dr_ns *ns =
> > -		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX  ?
> > -		sh->tx_ns : sh->rx_ns;
> > -
> > +	if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_FDB)
> > +		ns = sh->fdb_ns;
> > +	else if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX)
> > +		ns = sh->tx_ns;
> > +	else
> > +		ns = sh->rx_ns;
> >  	/* Lookup a matching resource from cache. */
> >  	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
> >  		if (resource->ft_type == cache_resource->ft_type &&
> > @@ -3615,6 +3637,8 @@ struct field_modify_info modify_tcp[] = {
> >  	union flow_dv_attr flow_attr = { .attr = 0 };
> >  	struct mlx5_flow_dv_tag_resource tag_resource;
> >
> > +	if (attr->transfer)
> > +		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
> 
> This res has nothing to do with encap/decap but it is
> mlx5_flow_dv_modify_hdr_resource.
> 
Yes like I wrote in the commit, I'm adding the table support for all actions 
including the modify.

> Thanks,
> Yongseok
> 
> >  	if (priority == MLX5_FLOW_PRIO_RSVD)
> >  		priority = priv->config.flow_prio - 1;
> >  	for (; !actions_end ; actions++) {
> > @@ -3720,7 +3744,9 @@ struct field_modify_info modify_tcp[] = {
> >  		case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
> >  		case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
> >  			if (flow_dv_create_action_l2_encap(dev, actions,
> > -							   dev_flow, error))
> > +							   dev_flow,
> > +							   attr->transfer,
> > +							   error))
> >  				return -rte_errno;
> >  			dev_flow->dv.actions[actions_n++] =
> >  				dev_flow->dv.encap_decap->verbs_action;
> > @@ -3732,6 +3758,7 @@ struct field_modify_info modify_tcp[] = {
> >  		case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
> >  		case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP:
> >  			if (flow_dv_create_action_l2_decap(dev, dev_flow,
> > +							   attr->transfer,
> >  							   error))
> >  				return -rte_errno;
> >  			dev_flow->dv.actions[actions_n++] =
> > @@ -3751,9 +3778,9 @@ struct field_modify_info modify_tcp[] = {
> >  					dev_flow->dv.encap_decap-
> >verbs_action;
> >  			} else {
> >  				/* Handle encap without preceding decap. */
> > -				if (flow_dv_create_action_l2_encap(dev,
> actions,
> > -								   dev_flow,
> > -								   error))
> > +				if (flow_dv_create_action_l2_encap
> > +				    (dev, actions, dev_flow, attr->transfer,
> > +				     error))
> >  					return -rte_errno;
> >  				dev_flow->dv.actions[actions_n++] =
> >  					dev_flow->dv.encap_decap-
> >verbs_action;
> > @@ -3768,9 +3795,8 @@ struct field_modify_info modify_tcp[] = {
> >  			}
> >  			/* Handle decap only if it isn't followed by encap. */
> >  			if (action->type !=
> RTE_FLOW_ACTION_TYPE_RAW_ENCAP) {
> > -				if (flow_dv_create_action_l2_decap(dev,
> > -								   dev_flow,
> > -								   error))
> > +				if (flow_dv_create_action_l2_decap
> > +				    (dev, dev_flow, attr->transfer, error))
> >  					return -rte_errno;
> >  				dev_flow->dv.actions[actions_n++] =
> >  					dev_flow->dv.encap_decap-
> >verbs_action;
> > --
> > 1.8.3.1
> >
  

Patch

diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index f4b7f06..d4dc439 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -40,6 +40,10 @@ 
 #define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0
 #endif
 
+#ifndef HAVE_MLX5DV_DR_ESWITCH
+#define MLX5DV_FLOW_TABLE_TYPE_FDB 0
+#endif
+
 union flow_dv_attr {
 	struct {
 		uint32_t valid:1;
@@ -943,7 +947,9 @@  struct field_modify_info modify_tcp[] = {
 	struct mlx5dv_dr_ns *ns;
 
 	resource->flags = flow->group ? 0 : 1;
-	if (flow->ingress)
+	if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_FDB)
+		ns = sh->fdb_ns;
+	else if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_RX)
 		ns = sh->rx_ns;
 	else
 		ns = sh->tx_ns;
@@ -1364,6 +1370,8 @@  struct field_modify_info modify_tcp[] = {
  *   Pointer to action structure.
  * @param[in, out] dev_flow
  *   Pointer to the mlx5_flow.
+ * @param[in] transfer
+ *   Mark if the flow is E-Switch flow.
  * @param[out] error
  *   Pointer to the error structure.
  *
@@ -1374,6 +1382,7 @@  struct field_modify_info modify_tcp[] = {
 flow_dv_create_action_l2_encap(struct rte_eth_dev *dev,
 			       const struct rte_flow_action *action,
 			       struct mlx5_flow *dev_flow,
+			       uint8_t transfer,
 			       struct rte_flow_error *error)
 {
 	const struct rte_flow_item *encap_data;
@@ -1384,6 +1393,8 @@  struct field_modify_info modify_tcp[] = {
 		.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_TX,
 	};
 
+	if (transfer)
+		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
 	if (action->type == RTE_FLOW_ACTION_TYPE_RAW_ENCAP) {
 		raw_encap_data =
 			(const struct rte_flow_action_raw_encap *)action->conf;
@@ -1416,6 +1427,8 @@  struct field_modify_info modify_tcp[] = {
  *   Pointer to rte_eth_dev structure.
  * @param[in, out] dev_flow
  *   Pointer to the mlx5_flow.
+ * @param[in] transfer
+ *   Mark if the flow is E-Switch flow.
  * @param[out] error
  *   Pointer to the error structure.
  *
@@ -1425,6 +1438,7 @@  struct field_modify_info modify_tcp[] = {
 static int
 flow_dv_create_action_l2_decap(struct rte_eth_dev *dev,
 			       struct mlx5_flow *dev_flow,
+			       uint8_t transfer,
 			       struct rte_flow_error *error)
 {
 	struct mlx5_flow_dv_encap_decap_resource res = {
@@ -1434,6 +1448,8 @@  struct field_modify_info modify_tcp[] = {
 		.ft_type = MLX5DV_FLOW_TABLE_TYPE_NIC_RX,
 	};
 
+	if (transfer)
+		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
 	if (flow_dv_encap_decap_resource_register(dev, &res, dev_flow, error))
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1474,8 +1490,11 @@  struct field_modify_info modify_tcp[] = {
 	res.reformat_type = attr->egress ?
 		MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL :
 		MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2;
-	res.ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
-				     MLX5DV_FLOW_TABLE_TYPE_NIC_RX;
+	if (attr->transfer)
+		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
+	else
+		res.ft_type = attr->egress ? MLX5DV_FLOW_TABLE_TYPE_NIC_TX :
+					     MLX5DV_FLOW_TABLE_TYPE_NIC_RX;
 	if (flow_dv_encap_decap_resource_register(dev, &res, dev_flow, error))
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1810,11 +1829,14 @@  struct field_modify_info modify_tcp[] = {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_ibv_shared *sh = priv->sh;
 	struct mlx5_flow_dv_modify_hdr_resource *cache_resource;
+	struct mlx5dv_dr_ns *ns;
 
-	struct mlx5dv_dr_ns *ns =
-		resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX  ?
-		sh->tx_ns : sh->rx_ns;
-
+	if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_FDB)
+		ns = sh->fdb_ns;
+	else if (resource->ft_type == MLX5DV_FLOW_TABLE_TYPE_NIC_TX)
+		ns = sh->tx_ns;
+	else
+		ns = sh->rx_ns;
 	/* Lookup a matching resource from cache. */
 	LIST_FOREACH(cache_resource, &sh->modify_cmds, next) {
 		if (resource->ft_type == cache_resource->ft_type &&
@@ -3615,6 +3637,8 @@  struct field_modify_info modify_tcp[] = {
 	union flow_dv_attr flow_attr = { .attr = 0 };
 	struct mlx5_flow_dv_tag_resource tag_resource;
 
+	if (attr->transfer)
+		res.ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
 	if (priority == MLX5_FLOW_PRIO_RSVD)
 		priority = priv->config.flow_prio - 1;
 	for (; !actions_end ; actions++) {
@@ -3720,7 +3744,9 @@  struct field_modify_info modify_tcp[] = {
 		case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
 		case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
 			if (flow_dv_create_action_l2_encap(dev, actions,
-							   dev_flow, error))
+							   dev_flow,
+							   attr->transfer,
+							   error))
 				return -rte_errno;
 			dev_flow->dv.actions[actions_n++] =
 				dev_flow->dv.encap_decap->verbs_action;
@@ -3732,6 +3758,7 @@  struct field_modify_info modify_tcp[] = {
 		case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
 		case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP:
 			if (flow_dv_create_action_l2_decap(dev, dev_flow,
+							   attr->transfer,
 							   error))
 				return -rte_errno;
 			dev_flow->dv.actions[actions_n++] =
@@ -3751,9 +3778,9 @@  struct field_modify_info modify_tcp[] = {
 					dev_flow->dv.encap_decap->verbs_action;
 			} else {
 				/* Handle encap without preceding decap. */
-				if (flow_dv_create_action_l2_encap(dev, actions,
-								   dev_flow,
-								   error))
+				if (flow_dv_create_action_l2_encap
+				    (dev, actions, dev_flow, attr->transfer,
+				     error))
 					return -rte_errno;
 				dev_flow->dv.actions[actions_n++] =
 					dev_flow->dv.encap_decap->verbs_action;
@@ -3768,9 +3795,8 @@  struct field_modify_info modify_tcp[] = {
 			}
 			/* Handle decap only if it isn't followed by encap. */
 			if (action->type != RTE_FLOW_ACTION_TYPE_RAW_ENCAP) {
-				if (flow_dv_create_action_l2_decap(dev,
-								   dev_flow,
-								   error))
+				if (flow_dv_create_action_l2_decap
+				    (dev, dev_flow, attr->transfer, error))
 					return -rte_errno;
 				dev_flow->dv.actions[actions_n++] =
 					dev_flow->dv.encap_decap->verbs_action;