Blame SOURCES/0263-netdrv-net-mlx5e-CT-Fix-offload-with-CT-action-after.patch

d8f823
From dd674b21a94bd385f3ee22ffa180a2029beef026 Mon Sep 17 00:00:00 2001
d8f823
From: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Date: Tue, 19 May 2020 07:49:25 -0400
d8f823
Subject: [PATCH 263/312] [netdrv] net/mlx5e: CT: Fix offload with CT action
d8f823
 after CT NAT action
d8f823
d8f823
Message-id: <20200519074934.6303-55-ahleihel@redhat.com>
d8f823
Patchwork-id: 310555
d8f823
Patchwork-instance: patchwork
d8f823
O-Subject: [RHEL8.3 BZ 1663246 54/63] net/mlx5e: CT: Fix offload with CT action after CT NAT action
d8f823
Bugzilla: 1663246
d8f823
RH-Acked-by: Marcelo Leitner <mleitner@redhat.com>
d8f823
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
d8f823
RH-Acked-by: John Linville <linville@redhat.com>
d8f823
RH-Acked-by: Ivan Vecera <ivecera@redhat.com>
d8f823
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
d8f823
RH-Acked-by: Kamal Heib <kheib@redhat.com>
d8f823
d8f823
Bugzilla: http://bugzilla.redhat.com/1663246
d8f823
Upstream: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git , branch: master
d8f823
d8f823
commit 9102d836d296fbc94517736d2dd1131ad6b01740
d8f823
Author: Roi Dayan <roid@mellanox.com>
d8f823
Date:   Sun Apr 12 15:39:15 2020 +0300
d8f823
d8f823
    net/mlx5e: CT: Fix offload with CT action after CT NAT action
d8f823
d8f823
    It could be a chain of rules will do action CT again after CT NAT
d8f823
    Before this fix matching will break as we get into the CT table
d8f823
    after NAT changes and not CT NAT.
d8f823
    Fix this by adding pre ct and pre ct nat tables to skip ct/ct_nat
d8f823
    tables and go straight to post_ct table if ct/nat was already done.
d8f823
d8f823
    Signed-off-by: Roi Dayan <roid@mellanox.com>
d8f823
    Reviewed-by: Paul Blakey <paulb@mellanox.com>
d8f823
    Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
d8f823
d8f823
Signed-off-by: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
d8f823
---
d8f823
 drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c | 308 +++++++++++++++++++--
d8f823
 1 file changed, 286 insertions(+), 22 deletions(-)
d8f823
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
d8f823
index 003079b09b67..8f94a4dde2bf 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
d8f823
@@ -24,6 +24,7 @@
d8f823
 #define MLX5_CT_ZONE_MASK GENMASK(MLX5_CT_ZONE_BITS - 1, 0)
d8f823
 #define MLX5_CT_STATE_ESTABLISHED_BIT BIT(1)
d8f823
 #define MLX5_CT_STATE_TRK_BIT BIT(2)
d8f823
+#define MLX5_CT_STATE_NAT_BIT BIT(3)
d8f823
 
d8f823
 #define MLX5_FTE_ID_BITS (mlx5e_tc_attr_to_reg_mappings[FTEID_TO_REG].mlen * 8)
d8f823
 #define MLX5_FTE_ID_MAX GENMASK(MLX5_FTE_ID_BITS - 1, 0)
d8f823
@@ -61,6 +62,15 @@ struct mlx5_ct_zone_rule {
d8f823
 	bool nat;
d8f823
 };
d8f823
 
d8f823
+struct mlx5_tc_ct_pre {
d8f823
+	struct mlx5_flow_table *fdb;
d8f823
+	struct mlx5_flow_group *flow_grp;
d8f823
+	struct mlx5_flow_group *miss_grp;
d8f823
+	struct mlx5_flow_handle *flow_rule;
d8f823
+	struct mlx5_flow_handle *miss_rule;
d8f823
+	struct mlx5_modify_hdr *modify_hdr;
d8f823
+};
d8f823
+
d8f823
 struct mlx5_ct_ft {
d8f823
 	struct rhash_head node;
d8f823
 	u16 zone;
d8f823
@@ -68,6 +78,8 @@ struct mlx5_ct_ft {
d8f823
 	struct nf_flowtable *nf_ft;
d8f823
 	struct mlx5_tc_ct_priv *ct_priv;
d8f823
 	struct rhashtable ct_entries_ht;
d8f823
+	struct mlx5_tc_ct_pre pre_ct;
d8f823
+	struct mlx5_tc_ct_pre pre_ct_nat;
d8f823
 };
d8f823
 
d8f823
 struct mlx5_ct_entry {
d8f823
@@ -428,6 +440,7 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
d8f823
 	struct mlx5_eswitch *esw = ct_priv->esw;
d8f823
 	struct mlx5_modify_hdr *mod_hdr;
d8f823
 	struct flow_action_entry *meta;
d8f823
+	u16 ct_state = 0;
d8f823
 	int err;
d8f823
 
d8f823
 	meta = mlx5_tc_ct_get_ct_metadata_action(flow_rule);
d8f823
@@ -446,11 +459,13 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
d8f823
 						  &mod_acts);
d8f823
 		if (err)
d8f823
 			goto err_mapping;
d8f823
+
d8f823
+		ct_state |= MLX5_CT_STATE_NAT_BIT;
d8f823
 	}
d8f823
 
d8f823
+	ct_state |= MLX5_CT_STATE_ESTABLISHED_BIT | MLX5_CT_STATE_TRK_BIT;
d8f823
 	err = mlx5_tc_ct_entry_set_registers(ct_priv, &mod_acts,
d8f823
-					     (MLX5_CT_STATE_ESTABLISHED_BIT |
d8f823
-					      MLX5_CT_STATE_TRK_BIT),
d8f823
+					     ct_state,
d8f823
 					     meta->ct_metadata.mark,
d8f823
 					     meta->ct_metadata.labels[0],
d8f823
 					     tupleid);
d8f823
@@ -793,6 +808,238 @@ mlx5_tc_ct_parse_action(struct mlx5e_priv *priv,
d8f823
 	return 0;
d8f823
 }
d8f823
 
d8f823
+static int tc_ct_pre_ct_add_rules(struct mlx5_ct_ft *ct_ft,
d8f823
+				  struct mlx5_tc_ct_pre *pre_ct,
d8f823
+				  bool nat)
d8f823
+{
d8f823
+	struct mlx5_tc_ct_priv *ct_priv = ct_ft->ct_priv;
d8f823
+	struct mlx5e_tc_mod_hdr_acts pre_mod_acts = {};
d8f823
+	struct mlx5_core_dev *dev = ct_priv->esw->dev;
d8f823
+	struct mlx5_flow_table *fdb = pre_ct->fdb;
d8f823
+	struct mlx5_flow_destination dest = {};
d8f823
+	struct mlx5_flow_act flow_act = {};
d8f823
+	struct mlx5_modify_hdr *mod_hdr;
d8f823
+	struct mlx5_flow_handle *rule;
d8f823
+	struct mlx5_flow_spec *spec;
d8f823
+	u32 ctstate;
d8f823
+	u16 zone;
d8f823
+	int err;
d8f823
+
d8f823
+	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
d8f823
+	if (!spec)
d8f823
+		return -ENOMEM;
d8f823
+
d8f823
+	zone = ct_ft->zone & MLX5_CT_ZONE_MASK;
d8f823
+	err = mlx5e_tc_match_to_reg_set(dev, &pre_mod_acts, ZONE_TO_REG, zone);
d8f823
+	if (err) {
d8f823
+		ct_dbg("Failed to set zone register mapping");
d8f823
+		goto err_mapping;
d8f823
+	}
d8f823
+
d8f823
+	mod_hdr = mlx5_modify_header_alloc(dev,
d8f823
+					   MLX5_FLOW_NAMESPACE_FDB,
d8f823
+					   pre_mod_acts.num_actions,
d8f823
+					   pre_mod_acts.actions);
d8f823
+
d8f823
+	if (IS_ERR(mod_hdr)) {
d8f823
+		err = PTR_ERR(mod_hdr);
d8f823
+		ct_dbg("Failed to create pre ct mod hdr");
d8f823
+		goto err_mapping;
d8f823
+	}
d8f823
+	pre_ct->modify_hdr = mod_hdr;
d8f823
+
d8f823
+	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
d8f823
+			  MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
d8f823
+	flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
d8f823
+	flow_act.modify_hdr = mod_hdr;
d8f823
+	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
d8f823
+
d8f823
+	/* add flow rule */
d8f823
+	mlx5e_tc_match_to_reg_match(spec, ZONE_TO_REG,
d8f823
+				    zone, MLX5_CT_ZONE_MASK);
d8f823
+	ctstate = MLX5_CT_STATE_TRK_BIT;
d8f823
+	if (nat)
d8f823
+		ctstate |= MLX5_CT_STATE_NAT_BIT;
d8f823
+	mlx5e_tc_match_to_reg_match(spec, CTSTATE_TO_REG, ctstate, ctstate);
d8f823
+
d8f823
+	dest.ft = ct_priv->post_ct;
d8f823
+	rule = mlx5_add_flow_rules(fdb, spec, &flow_act, &dest, 1);
d8f823
+	if (IS_ERR(rule)) {
d8f823
+		err = PTR_ERR(rule);
d8f823
+		ct_dbg("Failed to add pre ct flow rule zone %d", zone);
d8f823
+		goto err_flow_rule;
d8f823
+	}
d8f823
+	pre_ct->flow_rule = rule;
d8f823
+
d8f823
+	/* add miss rule */
d8f823
+	memset(spec, 0, sizeof(*spec));
d8f823
+	dest.ft = nat ? ct_priv->ct_nat : ct_priv->ct;
d8f823
+	rule = mlx5_add_flow_rules(fdb, spec, &flow_act, &dest, 1);
d8f823
+	if (IS_ERR(rule)) {
d8f823
+		err = PTR_ERR(rule);
d8f823
+		ct_dbg("Failed to add pre ct miss rule zone %d", zone);
d8f823
+		goto err_miss_rule;
d8f823
+	}
d8f823
+	pre_ct->miss_rule = rule;
d8f823
+
d8f823
+	dealloc_mod_hdr_actions(&pre_mod_acts);
d8f823
+	kvfree(spec);
d8f823
+	return 0;
d8f823
+
d8f823
+err_miss_rule:
d8f823
+	mlx5_del_flow_rules(pre_ct->flow_rule);
d8f823
+err_flow_rule:
d8f823
+	mlx5_modify_header_dealloc(dev, pre_ct->modify_hdr);
d8f823
+err_mapping:
d8f823
+	dealloc_mod_hdr_actions(&pre_mod_acts);
d8f823
+	kvfree(spec);
d8f823
+	return err;
d8f823
+}
d8f823
+
d8f823
+static void
d8f823
+tc_ct_pre_ct_del_rules(struct mlx5_ct_ft *ct_ft,
d8f823
+		       struct mlx5_tc_ct_pre *pre_ct)
d8f823
+{
d8f823
+	struct mlx5_tc_ct_priv *ct_priv = ct_ft->ct_priv;
d8f823
+	struct mlx5_core_dev *dev = ct_priv->esw->dev;
d8f823
+
d8f823
+	mlx5_del_flow_rules(pre_ct->flow_rule);
d8f823
+	mlx5_del_flow_rules(pre_ct->miss_rule);
d8f823
+	mlx5_modify_header_dealloc(dev, pre_ct->modify_hdr);
d8f823
+}
d8f823
+
d8f823
+static int
d8f823
+mlx5_tc_ct_alloc_pre_ct(struct mlx5_ct_ft *ct_ft,
d8f823
+			struct mlx5_tc_ct_pre *pre_ct,
d8f823
+			bool nat)
d8f823
+{
d8f823
+	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
d8f823
+	struct mlx5_tc_ct_priv *ct_priv = ct_ft->ct_priv;
d8f823
+	struct mlx5_core_dev *dev = ct_priv->esw->dev;
d8f823
+	struct mlx5_flow_table_attr ft_attr = {};
d8f823
+	struct mlx5_flow_namespace *ns;
d8f823
+	struct mlx5_flow_table *ft;
d8f823
+	struct mlx5_flow_group *g;
d8f823
+	u32 metadata_reg_c_2_mask;
d8f823
+	u32 *flow_group_in;
d8f823
+	void *misc;
d8f823
+	int err;
d8f823
+
d8f823
+	ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_FDB);
d8f823
+	if (!ns) {
d8f823
+		err = -EOPNOTSUPP;
d8f823
+		ct_dbg("Failed to get FDB flow namespace");
d8f823
+		return err;
d8f823
+	}
d8f823
+
d8f823
+	flow_group_in = kvzalloc(inlen, GFP_KERNEL);
d8f823
+	if (!flow_group_in)
d8f823
+		return -ENOMEM;
d8f823
+
d8f823
+	ft_attr.flags = MLX5_FLOW_TABLE_UNMANAGED;
d8f823
+	ft_attr.prio = FDB_TC_OFFLOAD;
d8f823
+	ft_attr.max_fte = 2;
d8f823
+	ft_attr.level = 1;
d8f823
+	ft = mlx5_create_flow_table(ns, &ft_attr);
d8f823
+	if (IS_ERR(ft)) {
d8f823
+		err = PTR_ERR(ft);
d8f823
+		ct_dbg("Failed to create pre ct table");
d8f823
+		goto out_free;
d8f823
+	}
d8f823
+	pre_ct->fdb = ft;
d8f823
+
d8f823
+	/* create flow group */
d8f823
+	MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0);
d8f823
+	MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 0);
d8f823
+	MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
d8f823
+		 MLX5_MATCH_MISC_PARAMETERS_2);
d8f823
+
d8f823
+	misc = MLX5_ADDR_OF(create_flow_group_in, flow_group_in,
d8f823
+			    match_criteria.misc_parameters_2);
d8f823
+
d8f823
+	metadata_reg_c_2_mask = MLX5_CT_ZONE_MASK;
d8f823
+	metadata_reg_c_2_mask |= (MLX5_CT_STATE_TRK_BIT << 16);
d8f823
+	if (nat)
d8f823
+		metadata_reg_c_2_mask |= (MLX5_CT_STATE_NAT_BIT << 16);
d8f823
+
d8f823
+	MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_2,
d8f823
+		 metadata_reg_c_2_mask);
d8f823
+
d8f823
+	g = mlx5_create_flow_group(ft, flow_group_in);
d8f823
+	if (IS_ERR(g)) {
d8f823
+		err = PTR_ERR(g);
d8f823
+		ct_dbg("Failed to create pre ct group");
d8f823
+		goto err_flow_grp;
d8f823
+	}
d8f823
+	pre_ct->flow_grp = g;
d8f823
+
d8f823
+	/* create miss group */
d8f823
+	memset(flow_group_in, 0, inlen);
d8f823
+	MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 1);
d8f823
+	MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1);
d8f823
+	g = mlx5_create_flow_group(ft, flow_group_in);
d8f823
+	if (IS_ERR(g)) {
d8f823
+		err = PTR_ERR(g);
d8f823
+		ct_dbg("Failed to create pre ct miss group");
d8f823
+		goto err_miss_grp;
d8f823
+	}
d8f823
+	pre_ct->miss_grp = g;
d8f823
+
d8f823
+	err = tc_ct_pre_ct_add_rules(ct_ft, pre_ct, nat);
d8f823
+	if (err)
d8f823
+		goto err_add_rules;
d8f823
+
d8f823
+	kvfree(flow_group_in);
d8f823
+	return 0;
d8f823
+
d8f823
+err_add_rules:
d8f823
+	mlx5_destroy_flow_group(pre_ct->miss_grp);
d8f823
+err_miss_grp:
d8f823
+	mlx5_destroy_flow_group(pre_ct->flow_grp);
d8f823
+err_flow_grp:
d8f823
+	mlx5_destroy_flow_table(ft);
d8f823
+out_free:
d8f823
+	kvfree(flow_group_in);
d8f823
+	return err;
d8f823
+}
d8f823
+
d8f823
+static void
d8f823
+mlx5_tc_ct_free_pre_ct(struct mlx5_ct_ft *ct_ft,
d8f823
+		       struct mlx5_tc_ct_pre *pre_ct)
d8f823
+{
d8f823
+	tc_ct_pre_ct_del_rules(ct_ft, pre_ct);
d8f823
+	mlx5_destroy_flow_group(pre_ct->miss_grp);
d8f823
+	mlx5_destroy_flow_group(pre_ct->flow_grp);
d8f823
+	mlx5_destroy_flow_table(pre_ct->fdb);
d8f823
+}
d8f823
+
d8f823
+static int
d8f823
+mlx5_tc_ct_alloc_pre_ct_tables(struct mlx5_ct_ft *ft)
d8f823
+{
d8f823
+	int err;
d8f823
+
d8f823
+	err = mlx5_tc_ct_alloc_pre_ct(ft, &ft->pre_ct, false);
d8f823
+	if (err)
d8f823
+		return err;
d8f823
+
d8f823
+	err = mlx5_tc_ct_alloc_pre_ct(ft, &ft->pre_ct_nat, true);
d8f823
+	if (err)
d8f823
+		goto err_pre_ct_nat;
d8f823
+
d8f823
+	return 0;
d8f823
+
d8f823
+err_pre_ct_nat:
d8f823
+	mlx5_tc_ct_free_pre_ct(ft, &ft->pre_ct);
d8f823
+	return err;
d8f823
+}
d8f823
+
d8f823
+static void
d8f823
+mlx5_tc_ct_free_pre_ct_tables(struct mlx5_ct_ft *ft)
d8f823
+{
d8f823
+	mlx5_tc_ct_free_pre_ct(ft, &ft->pre_ct_nat);
d8f823
+	mlx5_tc_ct_free_pre_ct(ft, &ft->pre_ct);
d8f823
+}
d8f823
+
d8f823
 static struct mlx5_ct_ft *
d8f823
 mlx5_tc_ct_add_ft_cb(struct mlx5_tc_ct_priv *ct_priv, u16 zone,
d8f823
 		     struct nf_flowtable *nf_ft)
d8f823
@@ -815,6 +1062,10 @@ mlx5_tc_ct_add_ft_cb(struct mlx5_tc_ct_priv *ct_priv, u16 zone,
d8f823
 	ft->ct_priv = ct_priv;
d8f823
 	refcount_set(&ft->refcount, 1);
d8f823
 
d8f823
+	err = mlx5_tc_ct_alloc_pre_ct_tables(ft);
d8f823
+	if (err)
d8f823
+		goto err_alloc_pre_ct;
d8f823
+
d8f823
 	err = rhashtable_init(&ft->ct_entries_ht, &cts_ht_params);
d8f823
 	if (err)
d8f823
 		goto err_init;
d8f823
@@ -836,6 +1087,8 @@ mlx5_tc_ct_add_ft_cb(struct mlx5_tc_ct_priv *ct_priv, u16 zone,
d8f823
 err_insert:
d8f823
 	rhashtable_destroy(&ft->ct_entries_ht);
d8f823
 err_init:
d8f823
+	mlx5_tc_ct_free_pre_ct_tables(ft);
d8f823
+err_alloc_pre_ct:
d8f823
 	kfree(ft);
d8f823
 	return ERR_PTR(err);
d8f823
 }
d8f823
@@ -861,21 +1114,40 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
d8f823
 	rhashtable_free_and_destroy(&ft->ct_entries_ht,
d8f823
 				    mlx5_tc_ct_flush_ft_entry,
d8f823
 				    ct_priv);
d8f823
+	mlx5_tc_ct_free_pre_ct_tables(ft);
d8f823
 	kfree(ft);
d8f823
 }
d8f823
 
d8f823
 /* We translate the tc filter with CT action to the following HW model:
d8f823
  *
d8f823
- * +-------------------+      +--------------------+    +--------------+
d8f823
- * + pre_ct (tc chain) +----->+ CT (nat or no nat) +--->+ post_ct      +----->
d8f823
- * + original match    +  |   + tuple + zone match + |  + fte_id match +  |
d8f823
- * +-------------------+  |   +--------------------+ |  +--------------+  |
d8f823
- *                        v                          v                    v
d8f823
- *                       set chain miss mapping  set mark             original
d8f823
- *                       set fte_id              set label            filter
d8f823
- *                       set zone                set established      actions
d8f823
- *                       set tunnel_id           do nat (if needed)
d8f823
- *                       do decap
d8f823
+ * +---------------------+
d8f823
+ * + fdb prio (tc chain) +
d8f823
+ * + original match      +
d8f823
+ * +---------------------+
d8f823
+ *      | set chain miss mapping
d8f823
+ *      | set fte_id
d8f823
+ *      | set tunnel_id
d8f823
+ *      | do decap
d8f823
+ *      v
d8f823
+ * +---------------------+
d8f823
+ * + pre_ct/pre_ct_nat   +  if matches     +---------------------+
d8f823
+ * + zone+nat match      +---------------->+ post_ct (see below) +
d8f823
+ * +---------------------+  set zone       +---------------------+
d8f823
+ *      | set zone
d8f823
+ *      v
d8f823
+ * +--------------------+
d8f823
+ * + CT (nat or no nat) +
d8f823
+ * + tuple + zone match +
d8f823
+ * +--------------------+
d8f823
+ *      | set mark
d8f823
+ *      | set label
d8f823
+ *      | set established
d8f823
+ *      | do nat (if needed)
d8f823
+ *      v
d8f823
+ * +--------------+
d8f823
+ * + post_ct      + original filter actions
d8f823
+ * + fte_id match +------------------------>
d8f823
+ * +--------------+
d8f823
  */
d8f823
 static int
d8f823
 __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
d8f823
@@ -890,7 +1162,7 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
d8f823
 	struct mlx5_flow_spec *post_ct_spec = NULL;
d8f823
 	struct mlx5_eswitch *esw = ct_priv->esw;
d8f823
 	struct mlx5_esw_flow_attr *pre_ct_attr;
d8f823
-	struct  mlx5_modify_hdr *mod_hdr;
d8f823
+	struct mlx5_modify_hdr *mod_hdr;
d8f823
 	struct mlx5_flow_handle *rule;
d8f823
 	struct mlx5_ct_flow *ct_flow;
d8f823
 	int chain_mapping = 0, err;
d8f823
@@ -953,14 +1225,6 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
d8f823
 		goto err_mapping;
d8f823
 	}
d8f823
 
d8f823
-	err = mlx5e_tc_match_to_reg_set(esw->dev, &pre_mod_acts, ZONE_TO_REG,
d8f823
-					attr->ct_attr.zone &
d8f823
-					MLX5_CT_ZONE_MASK);
d8f823
-	if (err) {
d8f823
-		ct_dbg("Failed to set zone register mapping");
d8f823
-		goto err_mapping;
d8f823
-	}
d8f823
-
d8f823
 	err = mlx5e_tc_match_to_reg_set(esw->dev, &pre_mod_acts,
d8f823
 					FTEID_TO_REG, fte_id);
d8f823
 	if (err) {
d8f823
@@ -1020,7 +1284,7 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
d8f823
 
d8f823
 	/* Change original rule point to ct table */
d8f823
 	pre_ct_attr->dest_chain = 0;
d8f823
-	pre_ct_attr->dest_ft = nat ? ct_priv->ct_nat : ct_priv->ct;
d8f823
+	pre_ct_attr->dest_ft = nat ? ft->pre_ct_nat.fdb : ft->pre_ct.fdb;
d8f823
 	ct_flow->pre_ct_rule = mlx5_eswitch_add_offloaded_rule(esw,
d8f823
 							       orig_spec,
d8f823
 							       pre_ct_attr);
d8f823
-- 
d8f823
2.13.6
d8f823