diff mbox series

[ovs-dev,v2,2/8] northd: Assume all chassis support the "ct-no-masked-label" feature.

Message ID 20240711162103.290159-3-dceara@redhat.com
State Changes Requested
Headers show
Series Add ACL Sampling using per-flow IPFIX. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes success github build: passed
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes success github build: passed

Commit Message

Dumitru Ceara July 11, 2024, 4:20 p.m. UTC
This feature is supported in the last two LTS releases and the correct
upgrade procedure mandates that we don't jump across LTS releases.  It's
safe to remove the check in northd.

Also remove logical field definitions for ct_label.<field>s that cannot
appear anymore in the southbound database.

Signed-off-by: Dumitru Ceara <dceara@redhat.com>
---
Changes in v2:
- fixed "Load balancer CT related backwards compatibility" test.
---
 controller/lflow.c          |  39 ++-----
 controller/lflow.h          |   1 -
 controller/ovn-controller.c |  22 ----
 lib/logical-fields.c        |  22 ----
 northd/en-global-config.c   |  23 ----
 northd/en-global-config.h   |   1 -
 northd/inc-proc-northd.c    |   2 -
 northd/northd.c             | 190 +++++++++++--------------------
 ovn-sb.xml                  |  19 ----
 tests/ovn-controller.at     |   8 +-
 tests/ovn-northd.at         | 215 ++++--------------------------------
 tests/ovn.at                |   9 +-
 12 files changed, 95 insertions(+), 456 deletions(-)
diff mbox series

Patch

diff --git a/controller/lflow.c b/controller/lflow.c
index b4c379044f..9f6564787f 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -100,7 +100,6 @@  consider_logical_flow(const struct sbrec_logical_flow *lflow,
 static void
 consider_lb_hairpin_flows(const struct ovn_controller_lb *lb,
                           const struct hmap *local_datapaths,
-                          bool use_ct_mark,
                           struct ovn_desired_flow_table *flow_table);
 
 static void add_port_sec_flows(const struct shash *binding_lports,
@@ -1631,7 +1630,6 @@  static void
 add_lb_vip_hairpin_flows(const struct ovn_controller_lb *lb,
                          struct ovn_lb_vip *lb_vip,
                          struct ovn_lb_backend *lb_backend,
-                         bool use_ct_mark,
                          struct ovn_desired_flow_table *flow_table)
 {
     uint64_t stub[1024 / 8];
@@ -1722,29 +1720,13 @@  add_lb_vip_hairpin_flows(const struct ovn_controller_lb *lb,
      * - packets must have ip.src == ip.dst at this point.
      * - the destination protocol and port must be of a valid backend that
      *   has the same IP as ip.dst.
-     *
-     * During upgrades logical flows might still use the old way of storing
-     * ct.natted in ct_label.  For backwards compatibility, only use ct_mark
-     * if ovn-northd notified ovn-controller to do that.
      */
-    if (use_ct_mark) {
-        uint32_t lb_ct_mark = OVN_CT_NATTED;
-        match_set_ct_mark_masked(&hairpin_match, lb_ct_mark, lb_ct_mark);
+    uint32_t lb_ct_mark = OVN_CT_NATTED;
+    match_set_ct_mark_masked(&hairpin_match, lb_ct_mark, lb_ct_mark);
 
-        ofctrl_add_flow(flow_table, OFTABLE_CHK_LB_HAIRPIN, 100,
-                        lb->slb->header_.uuid.parts[0], &hairpin_match,
-                        &ofpacts, &lb->slb->header_.uuid);
-    } else {
-        match_set_ct_mark_masked(&hairpin_match, 0, 0);
-        ovs_u128 lb_ct_label = {
-            .u64.lo = OVN_CT_NATTED,
-        };
-        match_set_ct_label_masked(&hairpin_match, lb_ct_label, lb_ct_label);
-
-        ofctrl_add_flow(flow_table, OFTABLE_CHK_LB_HAIRPIN, 100,
-                        lb->slb->header_.uuid.parts[0], &hairpin_match,
-                        &ofpacts, &lb->slb->header_.uuid);
-    }
+    ofctrl_add_flow(flow_table, OFTABLE_CHK_LB_HAIRPIN, 100,
+                    lb->slb->header_.uuid.parts[0], &hairpin_match,
+                    &ofpacts, &lb->slb->header_.uuid);
 
     ofpbuf_uninit(&ofpacts);
 }
@@ -1967,7 +1949,6 @@  add_lb_ct_snat_hairpin_flows(const struct ovn_controller_lb *lb,
 static void
 consider_lb_hairpin_flows(const struct ovn_controller_lb *lb,
                           const struct hmap *local_datapaths,
-                          bool use_ct_mark,
                           struct ovn_desired_flow_table *flow_table)
 {
     for (size_t i = 0; i < lb->n_vips; i++) {
@@ -1976,8 +1957,7 @@  consider_lb_hairpin_flows(const struct ovn_controller_lb *lb,
         for (size_t j = 0; j < lb_vip->n_backends; j++) {
             struct ovn_lb_backend *lb_backend = &lb_vip->backends[j];
 
-            add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend,
-                                     use_ct_mark, flow_table);
+            add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend, flow_table);
         }
     }
 
@@ -1989,13 +1969,11 @@  consider_lb_hairpin_flows(const struct ovn_controller_lb *lb,
 static void
 add_lb_hairpin_flows(const struct hmap *local_lbs,
                      const struct hmap *local_datapaths,
-                     bool use_ct_mark,
                      struct ovn_desired_flow_table *flow_table)
 {
     const struct ovn_controller_lb *lb;
     HMAP_FOR_EACH (lb, hmap_node, local_lbs) {
-        consider_lb_hairpin_flows(lb, local_datapaths,
-                                  use_ct_mark, flow_table);
+        consider_lb_hairpin_flows(lb, local_datapaths, flow_table);
     }
 }
 
@@ -2155,7 +2133,6 @@  lflow_run(struct lflow_ctx_in *l_ctx_in, struct lflow_ctx_out *l_ctx_out)
                        l_ctx_out->flow_table);
     add_lb_hairpin_flows(l_ctx_in->local_lbs,
                          l_ctx_in->local_datapaths,
-                         l_ctx_in->lb_hairpin_use_ct_mark,
                          l_ctx_out->flow_table);
     add_fdb_flows(l_ctx_in->fdb_table, l_ctx_in->local_datapaths,
                   l_ctx_out->flow_table,
@@ -2406,7 +2383,6 @@  lflow_handle_changed_lbs(struct lflow_ctx_in *l_ctx_in,
                   UUID_FMT, UUID_ARGS(&uuid_node->uuid));
         ofctrl_remove_flows(l_ctx_out->flow_table, &uuid_node->uuid);
         consider_lb_hairpin_flows(lb, l_ctx_in->local_datapaths,
-                                  l_ctx_in->lb_hairpin_use_ct_mark,
                                   l_ctx_out->flow_table);
     }
 
@@ -2416,7 +2392,6 @@  lflow_handle_changed_lbs(struct lflow_ctx_in *l_ctx_in,
         VLOG_DBG("Add load balancer hairpin flows for "UUID_FMT,
                  UUID_ARGS(&uuid_node->uuid));
         consider_lb_hairpin_flows(lb, l_ctx_in->local_datapaths,
-                                  l_ctx_in->lb_hairpin_use_ct_mark,
                                   l_ctx_out->flow_table);
     }
 
diff --git a/controller/lflow.h b/controller/lflow.h
index 7c947a9091..c8a2a3f494 100644
--- a/controller/lflow.h
+++ b/controller/lflow.h
@@ -128,7 +128,6 @@  struct lflow_ctx_in {
     const struct smap *template_vars;
     const struct flow_collector_ids *collector_ids;
     const struct hmap *local_lbs;
-    bool lb_hairpin_use_ct_mark;
     bool localnet_learn_fdb;
     bool localnet_learn_fdb_changed;
     bool explicit_arp_ns_output;
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index d6d001b1ac..b3a265230c 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -146,9 +146,6 @@  static const char *ssl_ca_cert_file;
 #define DEFAULT_LFLOW_CACHE_WMARK_PERC 50
 #define DEFAULT_LFLOW_CACHE_TRIM_TO_MS 30000
 
-/* SB Global options defaults. */
-#define DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK true
-
 struct controller_engine_ctx {
     struct lflow_cache *lflow_cache;
     struct if_status_mgr *if_mgr;
@@ -3351,7 +3348,6 @@  non_vif_data_ovs_iface_handler(struct engine_node *node, void *data OVS_UNUSED)
 }
 
 struct ed_type_northd_options {
-    bool lb_hairpin_use_ct_mark;
     bool explicit_arp_ns_output;
 };
 
@@ -3378,12 +3374,6 @@  en_northd_options_run(struct engine_node *node, void *data)
     const struct sbrec_sb_global *sb_global =
         sbrec_sb_global_table_first(sb_global_table);
 
-    n_opts->lb_hairpin_use_ct_mark =
-        sb_global
-        ? smap_get_bool(&sb_global->options, "lb_hairpin_use_ct_mark",
-                        DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK)
-        : DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK;
-
     n_opts->explicit_arp_ns_output =
             sb_global
             ? smap_get_bool(&sb_global->options, "arp_ns_explicit_output",
@@ -3402,17 +3392,6 @@  en_northd_options_sb_sb_global_handler(struct engine_node *node, void *data)
     const struct sbrec_sb_global *sb_global =
         sbrec_sb_global_table_first(sb_global_table);
 
-    bool lb_hairpin_use_ct_mark =
-        sb_global
-        ? smap_get_bool(&sb_global->options, "lb_hairpin_use_ct_mark",
-                        DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK)
-        : DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK;
-
-    if (lb_hairpin_use_ct_mark != n_opts->lb_hairpin_use_ct_mark) {
-        n_opts->lb_hairpin_use_ct_mark = lb_hairpin_use_ct_mark;
-        engine_set_node_state(node, EN_UPDATED);
-    }
-
     bool explicit_arp_ns_output =
             sb_global
             ? smap_get_bool(&sb_global->options, "arp_ns_explicit_output",
@@ -3652,7 +3631,6 @@  init_lflow_ctx(struct engine_node *node,
     l_ctx_in->localnet_learn_fdb = rt_data->localnet_learn_fdb;
     l_ctx_in->localnet_learn_fdb_changed = rt_data->localnet_learn_fdb_changed;
     l_ctx_in->chassis_tunnels = &non_vif_data->chassis_tunnels;
-    l_ctx_in->lb_hairpin_use_ct_mark = n_opts->lb_hairpin_use_ct_mark;
     l_ctx_in->explicit_arp_ns_output = n_opts->explicit_arp_ns_output;
     l_ctx_in->nd_ra_opts = &fo->nd_ra_opts;
     l_ctx_in->dhcp_opts = &dhcp_opts->v4_opts;
diff --git a/lib/logical-fields.c b/lib/logical-fields.c
index 20219a67ad..4acf8a677e 100644
--- a/lib/logical-fields.c
+++ b/lib/logical-fields.c
@@ -168,35 +168,13 @@  ovn_init_symtab(struct shash *symtab)
 
     expr_symtab_add_field_scoped(symtab, "ct_label", MFF_CT_LABEL, NULL,
                                  false, WR_CT_COMMIT);
-    expr_symtab_add_subfield_scoped(symtab, "ct_label.blocked", NULL,
-                                    "ct_label["
-                                        OVN_CT_STR(OVN_CT_BLOCKED_BIT)
-                                    "]",
-                                    WR_CT_COMMIT);
-    expr_symtab_add_subfield_scoped(symtab, "ct_label.natted", NULL,
-                                    "ct_label["
-                                        OVN_CT_STR(OVN_CT_NATTED_BIT)
-                                    "]",
-                                    WR_CT_COMMIT);
     expr_symtab_add_subfield_scoped(symtab, "ct_label.ecmp_reply_eth", NULL,
                                     "ct_label["
                                     OVN_CT_STR(OVN_CT_ECMP_ETH_1ST_BIT) ".."
                                     OVN_CT_STR(OVN_CT_ECMP_ETH_END_BIT) "]",
                                     WR_CT_COMMIT);
-    expr_symtab_add_subfield_scoped(symtab, "ct_label.ecmp_reply_port", NULL,
-                                    "ct_label[80..95]", WR_CT_COMMIT);
     expr_symtab_add_subfield_scoped(symtab, "ct_label.label", NULL,
                                     "ct_label[96..127]", WR_CT_COMMIT);
-    expr_symtab_add_subfield_scoped(symtab, "ct_label.skip_snat", NULL,
-                                    "ct_label["
-                                    OVN_CT_STR(OVN_CT_LB_SKIP_SNAT_BIT)
-                                    "]",
-                                    WR_CT_COMMIT);
-    expr_symtab_add_subfield_scoped(symtab, "ct_label.force_snat", NULL,
-                                    "ct_label["
-                                    OVN_CT_STR(OVN_CT_LB_FORCE_SNAT_BIT)
-                                    "]",
-                                    WR_CT_COMMIT);
 
     expr_symtab_add_field(symtab, "ct_state", MFF_CT_STATE, NULL, false);
 
diff --git a/northd/en-global-config.c b/northd/en-global-config.c
index 784538a142..183b535dee 100644
--- a/northd/en-global-config.c
+++ b/northd/en-global-config.c
@@ -366,7 +366,6 @@  static void
 northd_enable_all_features(struct ed_type_global_config *data)
 {
     data->features = (struct chassis_features) {
-        .ct_no_masked_label = true,
         .mac_binding_timestamp = true,
         .ct_lb_related = true,
         .fdb_timestamp = true,
@@ -390,14 +389,6 @@  build_chassis_features(const struct sbrec_chassis_table *sbrec_chassis_table,
             continue;
         }
 
-        bool ct_no_masked_label =
-            smap_get_bool(&chassis->other_config,
-                          OVN_FEATURE_CT_NO_MASKED_LABEL,
-                          false);
-        if (!ct_no_masked_label && chassis_features->ct_no_masked_label) {
-            chassis_features->ct_no_masked_label = false;
-        }
-
         bool mac_binding_timestamp =
             smap_get_bool(&chassis->other_config,
                           OVN_FEATURE_MAC_BINDING_TIMESTAMP,
@@ -552,16 +543,6 @@  update_sb_config_options_to_sbrec(struct ed_type_global_config *config_data,
     smap_destroy(options);
     smap_clone(options, &config_data->nb_options);
 
-    /* Inform ovn-controllers whether LB flows will use ct_mark (i.e., only
-     * if all chassis support it).  If not explicitly present in the database
-     * the default value to be used for this option is 'true'.
-     */
-    if (!config_data->features.ct_no_masked_label) {
-        smap_replace(options, "lb_hairpin_use_ct_mark", "false");
-    } else {
-        smap_remove(options, "lb_hairpin_use_ct_mark");
-    }
-
     /* Hackaround SB_global.options overwrite by NB_Global.options for
      * 'sbctl_probe_interval' option.
      */
@@ -583,10 +564,6 @@  static bool
 chassis_features_changed(const struct chassis_features *present,
                          const struct chassis_features *updated)
 {
-    if (present->ct_no_masked_label != updated->ct_no_masked_label) {
-        return true;
-    }
-
     if (present->mac_binding_timestamp != updated->mac_binding_timestamp) {
         return true;
     }
diff --git a/northd/en-global-config.h b/northd/en-global-config.h
index 842bcee707..c3cc881371 100644
--- a/northd/en-global-config.h
+++ b/northd/en-global-config.h
@@ -14,7 +14,6 @@  struct nbrec_nb_global;
 struct sbrec_sb_global;
 
 struct chassis_features {
-    bool ct_no_masked_label;
     bool mac_binding_timestamp;
     bool ct_lb_related;
     bool fdb_timestamp;
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index d56e9783a5..180b2be3e9 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -463,8 +463,6 @@  chassis_features_list(struct unixctl_conn *conn, int argc OVS_UNUSED,
     struct chassis_features *features = features_;
     struct ds ds = DS_EMPTY_INITIALIZER;
 
-    ds_put_format(&ds, "ct_no_masked_label:    %s\n",
-                  features->ct_no_masked_label ? "true" : "false");
     ds_put_format(&ds, "ct_lb_related:         %s\n",
                   features->ct_lb_related ? "true" : "false");
     ds_put_format(&ds, "mac_binding_timestamp: %s\n",
diff --git a/northd/northd.c b/northd/northd.c
index 1b5a7480e4..9cc6e6c14f 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3466,16 +3466,14 @@  build_lb_vip_actions(const struct ovn_northd_lb *lb,
                      struct ds *action, char *selection_fields,
                      struct ds *skip_snat_action,
                      struct ds *force_snat_action,
-                     bool ls_dp, const struct chassis_features *features,
+                     bool ls_dp,
                      const struct hmap *svc_monitor_map)
 {
-    const char *ct_lb_action =
-        features->ct_no_masked_label ? "ct_lb_mark" : "ct_lb";
     bool reject = !lb_vip->n_backends && lb_vip->empty_backend_rej;
     bool drop = !lb_vip->n_backends && !lb_vip->empty_backend_rej;
 
     if (lb_vip_nb->lb_health_check) {
-        ds_put_format(action, "%s(backends=", ct_lb_action);
+        ds_put_cstr(action, "ct_lb_mark(backends=");
 
         size_t n_active_backends = 0;
         for (size_t i = 0; i < lb_vip->n_backends; i++) {
@@ -3516,7 +3514,7 @@  build_lb_vip_actions(const struct ovn_northd_lb *lb,
         drop = !n_active_backends && !lb_vip->empty_backend_rej;
         reject = !n_active_backends && lb_vip->empty_backend_rej;
     } else {
-        ds_put_format(action, "%s(backends=%s", ct_lb_action,
+        ds_put_format(action, "ct_lb_mark(backends=%s",
                       lb_vip_nb->backend_ips);
     }
 
@@ -6268,7 +6266,6 @@  build_ls_stateful_rec_pre_lb(const struct ls_stateful_record *ls_stateful_rec,
 
 static void
 build_pre_stateful(struct ovn_datapath *od,
-                   const struct chassis_features *features,
                    struct lflow_table *lflows,
                    struct lflow_ref *lflow_ref)
 {
@@ -6281,16 +6278,12 @@  build_pre_stateful(struct ovn_datapath *od,
 
     /* Note: priority-120 flows are added in build_lb_rules_pre_stateful(). */
 
-    const char *ct_lb_action = features->ct_no_masked_label
-                               ? "ct_lb_mark;"
-                               : "ct_lb;";
-
     ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 110,
-                  REGBIT_CONNTRACK_NAT" == 1", ct_lb_action,
+                  REGBIT_CONNTRACK_NAT" == 1", "ct_lb_mark;",
                   lflow_ref);
 
     ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 110,
-                  REGBIT_CONNTRACK_NAT" == 1", ct_lb_action,
+                  REGBIT_CONNTRACK_NAT" == 1", "ct_lb_mark;",
                   lflow_ref);
 
     /* If REGBIT_CONNTRACK_DEFRAG is set as 1, then the packets should be
@@ -6308,7 +6301,6 @@  build_pre_stateful(struct ovn_datapath *od,
 static void
 build_acl_hints(const struct ls_stateful_record *ls_stateful_rec,
                 const struct ovn_datapath *od,
-                const struct chassis_features *features,
                 struct lflow_table *lflows,
                 struct lflow_ref *lflow_ref)
 {
@@ -6332,7 +6324,6 @@  build_acl_hints(const struct ls_stateful_record *ls_stateful_rec,
 
     for (size_t i = 0; i < ARRAY_SIZE(stages); i++) {
         enum ovn_stage stage = stages[i];
-        const char *match;
 
         /* In any case, advance to the next stage. */
         if (!ls_stateful_rec->has_acls && !ls_stateful_rec->has_lb_vip) {
@@ -6364,10 +6355,8 @@  build_acl_hints(const struct ls_stateful_record *ls_stateful_rec,
          *   REGBIT_ACL_HINT_ALLOW_NEW.
          * - drop ACLs.
          */
-        match = features->ct_no_masked_label
-                ? "!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1"
-                : "!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1";
-        ovn_lflow_add(lflows, od, stage, 6, match,
+        ovn_lflow_add(lflows, od, stage, 6,
+                      "!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1",
                       REGBIT_ACL_HINT_ALLOW_NEW " = 1; "
                       REGBIT_ACL_HINT_DROP " = 1; "
                       "next;", lflow_ref);
@@ -6386,10 +6375,8 @@  build_acl_hints(const struct ls_stateful_record *ls_stateful_rec,
          *   connection must be committed with ct_mark.blocked set so we set
          *   REGBIT_ACL_HINT_BLOCK.
          */
-        match = features->ct_no_masked_label
-                ? "!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0"
-                : "!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0";
-        ovn_lflow_add(lflows, od, stage, 4, match,
+        ovn_lflow_add(lflows, od, stage, 4,
+                      "!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0",
                       REGBIT_ACL_HINT_ALLOW " = 1; "
                       REGBIT_ACL_HINT_BLOCK " = 1; "
                       "next;", lflow_ref);
@@ -6400,10 +6387,8 @@  build_acl_hints(const struct ls_stateful_record *ls_stateful_rec,
         ovn_lflow_add(lflows, od, stage, 3, "!ct.est",
                       REGBIT_ACL_HINT_DROP " = 1; "
                       "next;", lflow_ref);
-        match = features->ct_no_masked_label
-                ? "ct.est && ct_mark.blocked == 1"
-                : "ct.est && ct_label.blocked == 1";
-        ovn_lflow_add(lflows, od, stage, 2, match,
+        ovn_lflow_add(lflows, od, stage, 2,
+                      "ct.est && ct_mark.blocked == 1",
                       REGBIT_ACL_HINT_DROP " = 1; "
                       "next;", lflow_ref);
 
@@ -6411,10 +6396,8 @@  build_acl_hints(const struct ls_stateful_record *ls_stateful_rec,
          * drop ACLs in which case the connection must be committed with
          * ct_mark.blocked set.
          */
-        match = features->ct_no_masked_label
-                ? "ct.est && ct_mark.blocked == 0"
-                : "ct.est && ct_label.blocked == 0";
-        ovn_lflow_add(lflows, od, stage, 1, match,
+        ovn_lflow_add(lflows, od, stage, 1,
+                      "ct.est && ct_mark.blocked == 0",
                       REGBIT_ACL_HINT_BLOCK " = 1; "
                       "next;", lflow_ref);
     }
@@ -6481,13 +6464,10 @@  build_acl_log(struct ds *actions, const struct nbrec_acl *acl,
 static void
 consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,
              const struct nbrec_acl *acl, bool has_stateful,
-             bool ct_masked_mark, const struct shash *meter_groups,
-             uint64_t max_acl_tier, struct ds *match, struct ds *actions,
+             const struct shash *meter_groups, uint64_t max_acl_tier,
+             struct ds *match, struct ds *actions,
              struct lflow_ref *lflow_ref)
 {
-    const char *ct_blocked_match = ct_masked_mark
-                                   ? "ct_mark.blocked"
-                                   : "ct_label.blocked";
     bool ingress = !strcmp(acl->direction, "from-lport") ? true :false;
     enum ovn_stage stage;
 
@@ -6625,8 +6605,7 @@  consider_acl(struct lflow_table *lflows, const struct ovn_datapath *od,
         ds_put_format(match, " && (%s)", acl->match);
 
         ds_truncate(actions, log_verdict_len);
-        ds_put_format(actions, "ct_commit { %s = 1; }; next;",
-                      ct_blocked_match);
+        ds_put_cstr(actions, "ct_commit { ct_mark.blocked = 1; }; next;");
         ovn_lflow_add_with_hint(lflows, od, stage, priority,
                                 ds_cstr(match), ds_cstr(actions),
                                 &acl->header_, lflow_ref);
@@ -6790,7 +6769,6 @@  static void
 build_acl_log_related_flows(const struct ovn_datapath *od,
                             struct lflow_table *lflows,
                             const struct nbrec_acl *acl, bool has_stateful,
-                            bool ct_masked_mark,
                             const struct shash *meter_groups,
                             struct ds *match, struct ds *actions,
                             struct lflow_ref *lflow_ref)
@@ -6807,9 +6785,6 @@  build_acl_log_related_flows(const struct ovn_datapath *od,
      * limitations. In such case the user may choose to avoid using the
      * "log-related" option.
      */
-    const char *ct_blocked_match = ct_masked_mark
-                                   ? "ct_mark.blocked"
-                                   : "ct_label.blocked";
     bool ingress = !strcmp(acl->direction, "from-lport") ? true :false;
     bool log_related = smap_get_bool(&acl->options, "log-related",
                                      false);
@@ -6840,10 +6815,10 @@  build_acl_log_related_flows(const struct ovn_datapath *od,
         S_SWITCH_IN_ACL_EVAL;
     ds_clear(match);
     ds_put_format(match, "ct.est && !ct.rel && !ct.new%s && "
-                  "ct.rpl && %s == 0 && "
+                  "ct.rpl && ct_mark.blocked == 0 && "
                   "ct_label.label == %" PRId64,
                   use_ct_inv_match ? " && !ct.inv" : "",
-                  ct_blocked_match, acl->label);
+                  acl->label);
     ovn_lflow_add_with_hint(lflows, od, log_related_stage,
                             UINT16_MAX - 2,
                             ds_cstr(match), ds_cstr(actions),
@@ -6851,10 +6826,10 @@  build_acl_log_related_flows(const struct ovn_datapath *od,
 
     ds_clear(match);
     ds_put_format(match, "!ct.est && ct.rel && !ct.new%s && "
-                         "%s == 0 && "
+                         "ct_mark.blocked == 0 && "
                          "ct_label.label == %" PRId64,
                          use_ct_inv_match ? " && !ct.inv" : "",
-                         ct_blocked_match, acl->label);
+                         acl->label);
     ovn_lflow_add_with_hint(lflows, od, log_related_stage,
                             UINT16_MAX - 2,
                             ds_cstr(match), ds_cstr(actions),
@@ -6875,9 +6850,6 @@  build_acls(const struct ls_stateful_record *ls_stateful_rec,
                                      : "next;";
     bool has_stateful = (ls_stateful_rec->has_stateful_acl
                          || ls_stateful_rec->has_lb_vip);
-    const char *ct_blocked_match = features->ct_no_masked_label
-                                   ? "ct_mark.blocked"
-                                   : "ct_label.blocked";
     struct ds match   = DS_EMPTY_INITIALIZER;
     struct ds actions = DS_EMPTY_INITIALIZER;
 
@@ -6936,7 +6908,7 @@  build_acls(const struct ls_stateful_record *ls_stateful_rec,
          * Subsequent packets will hit the flow at priority 0 that just
          * uses "next;". */
         ds_clear(&match);
-        ds_put_format(&match, "ip && ct.est && %s == 1", ct_blocked_match);
+        ds_put_format(&match, "ip && ct.est && ct_mark.blocked == 1");
         ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL_EVAL, 1,
                       ds_cstr(&match),
                       REGBIT_CONNTRACK_COMMIT" = 1; "
@@ -6964,9 +6936,8 @@  build_acls(const struct ls_stateful_record *ls_stateful_rec,
          *
          * This is enforced at a higher priority than ACLs can be defined. */
         ds_clear(&match);
-        ds_put_format(&match, "%s(ct.est && ct.rpl && %s == 1)",
-                      use_ct_inv_match ? "ct.inv || " : "",
-                      ct_blocked_match);
+        ds_put_format(&match, "%s(ct.est && ct.rpl && ct_mark.blocked == 1)",
+                      use_ct_inv_match ? "ct.inv || " : "");
         ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL_EVAL, UINT16_MAX - 3,
                       ds_cstr(&match), REGBIT_ACL_VERDICT_DROP " = 1; next;",
                       lflow_ref);
@@ -6985,9 +6956,8 @@  build_acls(const struct ls_stateful_record *ls_stateful_rec,
          * This is enforced at a higher priority than ACLs can be defined. */
         ds_clear(&match);
         ds_put_format(&match, "ct.est && !ct.rel && !ct.new%s && "
-                      "ct.rpl && %s == 0",
-                      use_ct_inv_match ? " && !ct.inv" : "",
-                      ct_blocked_match);
+                      "ct.rpl && ct_mark.blocked == 0",
+                      use_ct_inv_match ? " && !ct.inv" : "");
         ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL_EVAL, UINT16_MAX - 3,
                       ds_cstr(&match), REGBIT_ACL_HINT_DROP" = 0; "
                       REGBIT_ACL_HINT_BLOCK" = 0; "
@@ -7022,9 +6992,9 @@  build_acls(const struct ls_stateful_record *ls_stateful_rec,
             ? REGBIT_ACL_VERDICT_ALLOW" = 1; ct_commit_nat;"
             : REGBIT_ACL_VERDICT_ALLOW" = 1; next;";
         ds_clear(&match);
-        ds_put_format(&match, "!ct.est && ct.rel && !ct.new%s && %s == 0",
-                      use_ct_inv_match ? " && !ct.inv" : "",
-                      ct_blocked_match);
+        ds_put_format(&match, "!ct.est && ct.rel && !ct.new%s "
+                              "&& ct_mark.blocked == 0",
+                      use_ct_inv_match ? " && !ct.inv" : "");
         ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL_EVAL, UINT16_MAX - 3,
                       ds_cstr(&match), ct_in_acl_action, lflow_ref);
         ovn_lflow_add(lflows, od, S_SWITCH_OUT_ACL_EVAL, UINT16_MAX - 3,
@@ -7062,11 +7032,9 @@  build_acls(const struct ls_stateful_record *ls_stateful_rec,
     for (size_t i = 0; i < od->nbs->n_acls; i++) {
         struct nbrec_acl *acl = od->nbs->acls[i];
         build_acl_log_related_flows(od, lflows, acl, has_stateful,
-                                    features->ct_no_masked_label,
                                     meter_groups, &match, &actions,
                                     lflow_ref);
         consider_acl(lflows, od, acl, has_stateful,
-                     features->ct_no_masked_label,
                      meter_groups, ls_stateful_rec->max_acl_tier,
                      &match, &actions, lflow_ref);
     }
@@ -7080,11 +7048,9 @@  build_acls(const struct ls_stateful_record *ls_stateful_rec,
                 const struct nbrec_acl *acl = ls_pg_rec->nb_pg->acls[i];
 
                 build_acl_log_related_flows(od, lflows, acl, has_stateful,
-                                            features->ct_no_masked_label,
                                             meter_groups, &match, &actions,
                                             lflow_ref);
                 consider_acl(lflows, od, acl, has_stateful,
-                             features->ct_no_masked_label,
                              meter_groups, ls_stateful_rec->max_acl_tier,
                              &match, &actions, lflow_ref);
             }
@@ -7195,7 +7161,6 @@  build_qos(struct ovn_datapath *od, struct lflow_table *lflows,
 static void
 build_lb_rules_pre_stateful(struct lflow_table *lflows,
                             struct ovn_lb_datapaths *lb_dps,
-                            bool ct_lb_mark,
                             const struct ovn_datapaths *ls_datapaths,
                             struct ds *match, struct ds *action)
 {
@@ -7240,7 +7205,7 @@  build_lb_rules_pre_stateful(struct lflow_table *lflows,
             ds_put_format(action, REG_ORIG_TP_DPORT " = %s; ",
                           lb_vip->port_str);
         }
-        ds_put_format(action, "%s;", ct_lb_mark ? "ct_lb_mark" : "ct_lb");
+        ds_put_cstr(action, "ct_lb_mark;");
 
         ds_put_format(match, REGBIT_CONNTRACK_NAT" == 1 && %s.dst == %s",
                       ip_match, lb_vip->vip_str);
@@ -7658,8 +7623,8 @@  build_lrouter_lb_affinity_default_flows(struct ovn_datapath *od,
 static void
 build_lb_rules(struct lflow_table *lflows, struct ovn_lb_datapaths *lb_dps,
                const struct ovn_datapaths *ls_datapaths,
-               const struct chassis_features *features, struct ds *match,
-               struct ds *action, const struct shash *meter_groups,
+               struct ds *match, struct ds *action,
+               const struct shash *meter_groups,
                const struct hmap *svc_monitor_map)
 {
     const struct ovn_northd_lb *lb = lb_dps->lb;
@@ -7685,7 +7650,7 @@  build_lb_rules(struct lflow_table *lflows, struct ovn_lb_datapaths *lb_dps,
         const char *meter = NULL;
         bool reject = build_lb_vip_actions(lb, lb_vip, lb_vip_nb, action,
                                            lb->selection_fields,
-                                           NULL, NULL, true, features,
+                                           NULL, NULL, true,
                                            svc_monitor_map);
 
         ds_put_format(match, "ct.new && %s.dst == %s", ip_match,
@@ -7737,14 +7702,9 @@  build_lb_rules(struct lflow_table *lflows, struct ovn_lb_datapaths *lb_dps,
 }
 
 static void
-build_stateful(struct ovn_datapath *od,
-               const struct chassis_features *features,
-               struct lflow_table *lflows,
+build_stateful(struct ovn_datapath *od, struct lflow_table *lflows,
                struct lflow_ref *lflow_ref)
 {
-    const char *ct_block_action = features->ct_no_masked_label
-                                  ? "ct_mark.blocked"
-                                  : "ct_label.blocked";
     struct ds actions = DS_EMPTY_INITIALIZER;
 
     /* Ingress LB, Ingress and Egress stateful Table (Priority 0): Packets are
@@ -7761,9 +7721,8 @@  build_stateful(struct ovn_datapath *od,
      * We always set ct_mark.blocked to 0 here as
      * any packet that makes it this far is part of a connection we
      * want to allow to continue. */
-    ds_put_format(&actions, "ct_commit { %s = 0; "
-                            "ct_label.label = " REG_LABEL "; }; next;",
-                  ct_block_action);
+    ds_put_cstr(&actions, "ct_commit { ct_mark.blocked = 0; "
+                          "ct_label.label = " REG_LABEL "; }; next;");
     ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100,
                   REGBIT_CONNTRACK_COMMIT" == 1 && "
                   REGBIT_ACL_LABEL" == 1",
@@ -7780,7 +7739,7 @@  build_stateful(struct ovn_datapath *od,
      * any packet that makes it this far is part of a connection we
      * want to allow to continue. */
     ds_clear(&actions);
-    ds_put_format(&actions, "ct_commit { %s = 0; }; next;", ct_block_action);
+    ds_put_cstr(&actions, "ct_commit { ct_mark.blocked = 0; }; next;");
     ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100,
                   REGBIT_CONNTRACK_COMMIT" == 1 && "
                   REGBIT_ACL_LABEL" == 0",
@@ -8769,7 +8728,6 @@  build_lswitch_lflows_l2_unknown(struct ovn_datapath *od,
 static void
 build_lswitch_lflows_pre_acl_and_acl(
     struct ovn_datapath *od,
-    const struct chassis_features *features,
     struct lflow_table *lflows,
     const struct shash *meter_groups,
     struct lflow_ref *lflow_ref)
@@ -8777,9 +8735,9 @@  build_lswitch_lflows_pre_acl_and_acl(
     ovs_assert(od->nbs);
     build_pre_acls(od, lflows, lflow_ref);
     build_pre_lb(od, meter_groups, lflows, lflow_ref);
-    build_pre_stateful(od, features, lflows, lflow_ref);
+    build_pre_stateful(od, lflows, lflow_ref);
     build_qos(od, lflows, lflow_ref);
-    build_stateful(od, features, lflows, lflow_ref);
+    build_stateful(od, lflows, lflow_ref);
     build_vtep_hairpin(od, lflows, lflow_ref);
 }
 
@@ -10666,7 +10624,6 @@  find_static_route_outport(struct ovn_datapath *od, const struct hmap *lr_ports,
 static void
 add_ecmp_symmetric_reply_flows(struct lflow_table *lflows,
                                struct ovn_datapath *od,
-                               bool ct_masked_mark,
                                const char *port_ip,
                                struct ovn_port *out_port,
                                const struct parsed_route *route,
@@ -10678,9 +10635,6 @@  add_ecmp_symmetric_reply_flows(struct lflow_table *lflows,
     struct ds actions = DS_EMPTY_INITIALIZER;
     struct ds ecmp_reply = DS_EMPTY_INITIALIZER;
     char *cidr = normalize_v46_prefix(&route->prefix, route->plen);
-    const char *ct_ecmp_reply_port_match = ct_masked_mark
-                                           ? "ct_mark.ecmp_reply_port"
-                                           : "ct_label.ecmp_reply_port";
 
     /* If symmetric ECMP replies are enabled, then packets that arrive over
      * an ECMP route need to go through conntrack.
@@ -10709,9 +10663,9 @@  add_ecmp_symmetric_reply_flows(struct lflow_table *lflows,
     ds_put_cstr(&match, " && !ct.rpl && (ct.new || ct.est)");
     ds_put_format(&actions,
             "ct_commit { ct_label.ecmp_reply_eth = eth.src; "
-            " %s = %" PRId64 ";}; "
+            "ct_mark.ecmp_reply_port = %" PRId64 ";}; "
             "next;",
-            ct_ecmp_reply_port_match, out_port->sb->tunnel_key);
+            out_port->sb->tunnel_key);
     ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100,
                             ds_cstr(&match), ds_cstr(&actions),
                             &st_route->header_,
@@ -10721,8 +10675,8 @@  add_ecmp_symmetric_reply_flows(struct lflow_table *lflows,
      * for where to route the packet.
      */
     ds_put_format(&ecmp_reply,
-                  "ct.rpl && %s == %"PRId64,
-                  ct_ecmp_reply_port_match, out_port->sb->tunnel_key);
+                  "ct.rpl && ct_mark.ecmp_reply_port == %"PRId64,
+                  out_port->sb->tunnel_key);
     ds_clear(&match);
     ds_put_format(&match, "%s && %s", ds_cstr(&ecmp_reply),
                   ds_cstr(route_match));
@@ -10767,8 +10721,7 @@  add_ecmp_symmetric_reply_flows(struct lflow_table *lflows,
 
 static void
 build_ecmp_route_flow(struct lflow_table *lflows, struct ovn_datapath *od,
-                      bool ct_masked_mark, const struct hmap *lr_ports,
-                      struct ecmp_groups_node *eg,
+                      const struct hmap *lr_ports, struct ecmp_groups_node *eg,
                       struct lflow_ref *lflow_ref)
 
 {
@@ -10824,8 +10777,7 @@  build_ecmp_route_flow(struct lflow_table *lflows, struct ovn_datapath *od,
         if (smap_get(&od->nbr->options, "chassis") &&
             route_->ecmp_symmetric_reply && sset_add(&visited_ports,
                                                      out_port->key)) {
-            add_ecmp_symmetric_reply_flows(lflows, od, ct_masked_mark,
-                                           lrp_addr_s, out_port,
+            add_ecmp_symmetric_reply_flows(lflows, od, lrp_addr_s, out_port,
                                            route_, &route_match,
                                            lflow_ref);
         }
@@ -11152,7 +11104,6 @@  build_lrouter_nat_flows_for_lb(
     struct lflow_table *lflows,
     struct ds *match, struct ds *action,
     const struct shash *meter_groups,
-    const struct chassis_features *features,
     const struct hmap *svc_monitor_map)
 {
     const struct ovn_northd_lb *lb = lb_dps->lb;
@@ -11175,7 +11126,7 @@  build_lrouter_nat_flows_for_lb(
 
     bool reject = build_lb_vip_actions(lb, lb_vip, vips_nb, action,
                                        lb->selection_fields, &skip_snat_act,
-                                       &force_snat_act, false, features,
+                                       &force_snat_act, false,
                                        svc_monitor_map);
 
     /* Higher priority rules are added for load-balancing in DNAT
@@ -11297,7 +11248,6 @@  build_lswitch_flows_for_lb(struct ovn_lb_datapaths *lb_dps,
                            struct lflow_table *lflows,
                            const struct shash *meter_groups,
                            const struct ovn_datapaths *ls_datapaths,
-                           const struct chassis_features *features,
                            const struct hmap *svc_monitor_map,
                            struct ds *match, struct ds *action)
 {
@@ -11340,9 +11290,8 @@  build_lswitch_flows_for_lb(struct ovn_lb_datapaths *lb_dps,
      * a higher priority rule for load balancing below also commits the
      * connection, so it is okay if we do not hit the above match on
      * REGBIT_CONNTRACK_COMMIT. */
-    build_lb_rules_pre_stateful(lflows, lb_dps, features->ct_no_masked_label,
-                                ls_datapaths, match, action);
-    build_lb_rules(lflows, lb_dps, ls_datapaths, features, match, action,
+    build_lb_rules_pre_stateful(lflows, lb_dps, ls_datapaths, match, action);
+    build_lb_rules(lflows, lb_dps, ls_datapaths, match, action,
                    meter_groups, svc_monitor_map);
 }
 
@@ -11386,7 +11335,6 @@  build_lrouter_flows_for_lb(struct ovn_lb_datapaths *lb_dps,
                            const struct shash *meter_groups,
                            const struct ovn_datapaths *lr_datapaths,
                            const struct lr_stateful_table *lr_stateful_table,
-                           const struct chassis_features *features,
                            const struct hmap *svc_monitor_map,
                            struct ds *match, struct ds *action)
 {
@@ -11402,7 +11350,7 @@  build_lrouter_flows_for_lb(struct ovn_lb_datapaths *lb_dps,
 
         build_lrouter_nat_flows_for_lb(lb_vip, lb_dps, &lb->vips_nb[i],
                                        lr_datapaths, lr_stateful_table, lflows,
-                                       match, action, meter_groups, features,
+                                       match, action, meter_groups,
                                        svc_monitor_map);
 
         if (!build_empty_lb_event_flow(lb_vip, lb, match, action)) {
@@ -12717,9 +12665,8 @@  build_ip_routing_flows_for_lrp(
 
 static void
 build_static_route_flows_for_lrouter(
-        struct ovn_datapath *od, const struct chassis_features *features,
-        struct lflow_table *lflows, const struct hmap *lr_ports,
-        const struct hmap *bfd_connections,
+        struct ovn_datapath *od, struct lflow_table *lflows,
+        const struct hmap *lr_ports, const struct hmap *bfd_connections,
         struct lflow_ref *lflow_ref)
 {
     ovs_assert(od->nbr);
@@ -12768,8 +12715,7 @@  build_static_route_flows_for_lrouter(
     HMAP_FOR_EACH (group, hmap_node, &ecmp_groups) {
         /* add a flow in IP_ROUTING, and one flow for each member in
          * IP_ROUTING_ECMP. */
-        build_ecmp_route_flow(lflows, od, features->ct_no_masked_label,
-                              lr_ports, group, lflow_ref);
+        build_ecmp_route_flow(lflows, od, lr_ports, group, lflow_ref);
     }
     const struct unique_routes_node *ur;
     HMAP_FOR_EACH (ur, hmap_node, &unique_routes) {
@@ -15222,9 +15168,6 @@  build_lrouter_nat_defrag_and_lb(
     const struct chassis_features *features,
     struct lflow_ref *lflow_ref)
 {
-    const char *ct_flag_reg = features->ct_no_masked_label
-                              ? "ct_mark"
-                              : "ct_label";
     /* Ingress DNAT (Priority 50/70).
      *
      * Allow traffic that is related to an existing conntrack entry.
@@ -15240,13 +15183,13 @@  build_lrouter_nat_defrag_and_lb(
         ds_put_cstr(match, "ct.rel && !ct.est && !ct.new");
         size_t match_len = match->length;
 
-        ds_put_format(match, " && %s.skip_snat == 1", ct_flag_reg);
+        ds_put_cstr(match, " && ct_mark.skip_snat == 1");
         ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match),
                       "flags.skip_snat_for_lb = 1; ct_commit_nat;",
                       lflow_ref);
 
         ds_truncate(match, match_len);
-        ds_put_format(match, " && %s.force_snat == 1", ct_flag_reg);
+        ds_put_cstr(match, " && ct_mark.force_snat == 1");
         ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match),
                       "flags.force_snat_for_lb = 1; ct_commit_nat;",
                       lflow_ref);
@@ -15264,17 +15207,16 @@  build_lrouter_nat_defrag_and_lb(
     if (lr_stateful_rec->has_lb_vip) {
         ds_clear(match);
 
-        ds_put_format(match, "ct.est && !ct.rel && !ct.new && %s.natted",
-                      ct_flag_reg);
+        ds_put_cstr(match, "ct.est && !ct.rel && !ct.new && ct_mark.natted");
         size_t match_len = match->length;
 
-        ds_put_format(match, " && %s.skip_snat == 1", ct_flag_reg);
+        ds_put_cstr(match, " && ct_mark.skip_snat == 1");
         ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match),
                       "flags.skip_snat_for_lb = 1; next;",
                       lflow_ref);
 
         ds_truncate(match, match_len);
-        ds_put_format(match, " && %s.force_snat == 1", ct_flag_reg);
+        ds_put_cstr(match, " && ct_mark.force_snat == 1");
         ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match),
                       "flags.force_snat_for_lb = 1; next;",
                       lflow_ref);
@@ -15552,10 +15494,7 @@  build_lrouter_nat_defrag_and_lb(
 
     if (use_common_zone && od->nbr->n_nat) {
         ds_clear(match);
-        const char *ct_natted = features->ct_no_masked_label ?
-                                "ct_mark.natted" :
-                                "ct_label.natted";
-        ds_put_format(match, "ip && %s == 1", ct_natted);
+        ds_put_cstr(match, "ip && ct_mark.natted == 1");
         /* This flow is unique since it is in the egress pipeline but checks
          * the value of ct_label.natted, which would have been set in the
          * ingress pipeline. If a change is ever introduced that clears or
@@ -15837,7 +15776,7 @@  build_ls_stateful_flows(const struct ls_stateful_record *ls_stateful_rec,
                                    ls_stateful_rec->lflow_ref);
     build_ls_stateful_rec_pre_lb(ls_stateful_rec, od, lflows,
                                  ls_stateful_rec->lflow_ref);
-    build_acl_hints(ls_stateful_rec, od, features, lflows,
+    build_acl_hints(ls_stateful_rec, od, lflows,
                     ls_stateful_rec->lflow_ref);
     build_acls(ls_stateful_rec, od, features, lflows, ls_pgs,
                meter_groups, ls_stateful_rec->lflow_ref);
@@ -15877,7 +15816,7 @@  build_lswitch_and_lrouter_iterate_by_ls(struct ovn_datapath *od,
                                         struct lswitch_flow_build_info *lsi)
 {
     ovs_assert(od->nbs);
-    build_lswitch_lflows_pre_acl_and_acl(od, lsi->features, lsi->lflows,
+    build_lswitch_lflows_pre_acl_and_acl(od, lsi->lflows,
                                          lsi->meter_groups, NULL);
 
     build_fwd_group_lflows(od, lsi->lflows, NULL);
@@ -15908,8 +15847,7 @@  build_lswitch_and_lrouter_iterate_by_lr(struct ovn_datapath *od,
                                            lsi->meter_groups, NULL);
     build_ND_RA_flows_for_lrouter(od, lsi->lflows, NULL);
     build_ip_routing_pre_flows_for_lrouter(od, lsi->lflows, NULL);
-    build_static_route_flows_for_lrouter(od, lsi->features,
-                                         lsi->lflows, lsi->lr_ports,
+    build_static_route_flows_for_lrouter(od, lsi->lflows, lsi->lr_ports,
                                          lsi->bfd_connections,
                                          NULL);
     build_mcast_lookup_flows_for_lrouter(od, lsi->lflows, &lsi->match,
@@ -16114,13 +16052,11 @@  build_lflows_thread(void *arg)
                                                lsi->meter_groups,
                                                lsi->lr_datapaths,
                                                lsi->lr_stateful_table,
-                                               lsi->features,
                                                lsi->svc_monitor_map,
                                                &lsi->match, &lsi->actions);
                     build_lswitch_flows_for_lb(lb_dps, lsi->lflows,
                                                lsi->meter_groups,
                                                lsi->ls_datapaths,
-                                               lsi->features,
                                                lsi->svc_monitor_map,
                                                &lsi->match, &lsi->actions);
                 }
@@ -16351,10 +16287,10 @@  build_lswitch_and_lrouter_flows(
                                               lsi.lr_datapaths, &lsi.match);
             build_lrouter_flows_for_lb(lb_dps, lsi.lflows, lsi.meter_groups,
                                        lsi.lr_datapaths, lsi.lr_stateful_table,
-                                       lsi.features, lsi.svc_monitor_map,
+                                       lsi.svc_monitor_map,
                                        &lsi.match, &lsi.actions);
             build_lswitch_flows_for_lb(lb_dps, lsi.lflows, lsi.meter_groups,
-                                       lsi.ls_datapaths, lsi.features,
+                                       lsi.ls_datapaths,
                                        lsi.svc_monitor_map,
                                        &lsi.match, &lsi.actions);
         }
@@ -16757,13 +16693,11 @@  lflow_handle_northd_lb_changes(struct ovsdb_idl_txn *ovnsb_txn,
                                    lflow_input->meter_groups,
                                    lflow_input->lr_datapaths,
                                    lflow_input->lr_stateful_table,
-                                   lflow_input->features,
                                    lflow_input->svc_monitor_map,
                                    &match, &actions);
         build_lswitch_flows_for_lb(lb_dps, lflows,
                                    lflow_input->meter_groups,
                                    lflow_input->ls_datapaths,
-                                   lflow_input->features,
                                    lflow_input->svc_monitor_map,
                                    &match, &actions);
 
diff --git a/ovn-sb.xml b/ovn-sb.xml
index 73a1be5ed9..90f113afd4 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -229,25 +229,6 @@ 
         </column>
       </group>
 
-      <group title="Options for configuring Load Balancers">
-        <p>
-          These options apply when <code>ovn-controller</code> configures
-          load balancer related flows.
-        </p>
-
-        <column name="options" key="lb_hairpin_use_ct_mark">
-          By default this option is turned on (even if not present in the
-          database) unless its value is explicitly set to <code>false</code>.
-
-          This value is automatically set to <code>false</code> by
-          <code>ovn-northd</code> when action <code>ct_lb_mark</code> cannot be
-          used for new load balancer sessions and action <code>ct_lb</code>
-          will be used instead.  <code>ovn-controller</code> then
-          knows that it should check <code>ct_label.natted</code> to detect
-          load balanced traffic.
-        </column>
-      </group>
-
       <group title="Options for configuring ovn-sbctl">
         <p>
           These options apply when <code>ovn-sbctl</code> connects to
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index 2cb86dc98c..9cb099e68a 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -2195,7 +2195,7 @@  check as northd ovn-appctl -t ovn-northd resume
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 
-AT_SETUP([ovn-controller - I-P handle lb_hairpin_use_ct_mark change])
+AT_SETUP([ovn-controller - I-P handle arp_ns_explicit_output change])
 
 ovn_start
 
@@ -2226,8 +2226,8 @@  lflow_run_new=$(read_counter lflow_run)
 AT_CHECK([echo $(($lflow_run_new - $lflow_run_old))], [0], [0
 ])
 
-# lb_hairpin_use_ct_mark update in sb_global:options should trigger lflow_run.
-# The below steps should cause lb_hairpin_use_ct_mark change twice. One by
+# arp_ns_explicit_output update in sb_global:options should trigger lflow_run.
+# The below steps should cause arp_ns_explicit_output change twice. One by
 # ovn-sbctl, and the other by ovn-northd to change it back.
 
 # In some cases, both changes are catched by ovn-controller in the same run,
@@ -2235,7 +2235,7 @@  AT_CHECK([echo $(($lflow_run_new - $lflow_run_old))], [0], [0
 
 OVS_WAIT_UNTIL([
     lflow_run_old=$(read_counter lflow_run)
-    check ovn-sbctl set SB_Global . options:lb_hairpin_use_ct_mark=false
+    check ovn-sbctl set SB_Global . options:arp_ns_explicit_output=false
     check ovn-nbctl --wait=hv sync
     lflow_run_new=$(read_counter lflow_run)
     test x"$(($lflow_run_new - $lflow_run_old))" = x2
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 7dc94e1f56..c294d1a644 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -1394,8 +1394,7 @@  ovn-nbctl --wait=sb lsp-add sw1 sw1-p1 -- lsp-set-addresses sw1-p1 \
 "02:00:00:00:00:03 20.0.0.3"
 
 # service_monitors state online requires corresponding port_binding to be "up"
-ovn-sbctl chassis-add hv1 geneve 127.0.0.1 -- \
-    set chassis hv1 other_config:ct-no-masked-label=true
+ovn-sbctl chassis-add hv1 geneve 127.0.0.1
 ovn-sbctl lsp-bind sw0-p1 hv1
 ovn-sbctl lsp-bind sw1-p1 hv1
 wait_row_count nb:Logical_Switch_Port 1 name=sw0-p1 'up=true'
@@ -5614,7 +5613,6 @@  AT_CHECK([grep "lr_out_snat" lr0flows | ovn_strip_lflows], [0], [dnl
 ])
 
 check ovn-sbctl chassis-add gw1 geneve 127.0.0.1 \
-  -- set chassis gw1 other_config:ct-no-masked-label="true" \
   -- set chassis gw1 other_config:ovn-ct-lb-related="true" \
   -- set chassis gw1 other_config:ct-commit-to-zone="true"
 
@@ -6724,18 +6722,6 @@  AT_CHECK([grep -e "lr_in_defrag" lr0flows | ovn_strip_lflows], [0], [dnl
   table=??(lr_in_defrag       ), priority=100  , match=(reg7 == 0 && ip4.dst == 1.0.0.1/32), action=(ct_next;)
 ])
 
-dnl The chassis was created with other_config:ct-no-masked-label=false, the flows
-dnl should be using ct_label.ecmp_reply_port.
-AT_CHECK([grep -e "lr_in_arp_resolve.*ecmp" lr0flows | ovn_strip_lflows], [0], [dnl
-  table=??(lr_in_arp_resolve  ), priority=200  , match=(ct.rpl && ct_label.ecmp_reply_port == 1), action=(push(xxreg1); xxreg1 = ct_label; eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;)
-])
-
-dnl Simulate an ovn-controller upgrade to a version that supports
-dnl ct-no-masked-label.  ovn-northd should start using ct_mark.ecmp_reply_port.
-
-check ovn-sbctl set chassis ch1 other_config:ct-no-masked-label=true
-check ovn-nbctl --wait=sb sync
-ovn-sbctl dump-flows lr0 > lr0flows
 AT_CHECK([grep -e "lr_in_arp_resolve.*ecmp" lr0flows | ovn_strip_lflows], [0], [dnl
   table=??(lr_in_arp_resolve  ), priority=200  , match=(ct.rpl && ct_mark.ecmp_reply_port == 1), action=(push(xxreg1); xxreg1 = ct_label; eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;)
 ])
@@ -8959,162 +8945,6 @@  ovn_strip_lflows ], [0], [dnl
 AT_CLEANUP
 ])
 
-
-OVN_FOR_EACH_NORTHD_NO_HV([
-AT_SETUP([Load balancer ct_lb_mark backwards compatibility])
-AT_KEYWORDS([lb])
-ovn_start
-
-check ovn-nbctl                                               \
-  -- ls-add ls                                                \
-  -- lr-add lr -- set logical_router lr options:chassis=local \
-  -- lb-add lb-test 66.66.66.66 42.42.42.2                    \
-  -- ls-lb-add ls lb-test                                     \
-  -- lr-lb-add lr lb-test
-
-AS_BOX([No chassis registered - use ct_lb_mark and ct_mark.natted])
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb | ovn_strip_lflows], [0], [dnl
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
-  table=??(ls_in_lb           ), priority=110  , match=(ct.new && ip4.dst == 66.66.66.66), action=(reg0[[1]] = 0; ct_lb_mark(backends=42.42.42.2);)
-  table=??(ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1), action=(ct_lb_mark;)
-  table=??(ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip4.dst == 66.66.66.66), action=(reg1 = 66.66.66.66; ct_lb_mark;)
-  table=??(ls_out_pre_stateful), priority=110  , match=(reg0[[2]] == 1), action=(ct_lb_mark;)
-])
-
-AS_BOX([Chassis registered that doesn't support ct_lb_mark - use ct_lb and ct_label.natted])
-check ovn-sbctl chassis-add hv geneve 127.0.0.1
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb | ovn_strip_lflows], [0], [dnl
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 66.66.66.66), action=(ct_lb(backends=42.42.42.2);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
-  table=??(ls_in_lb           ), priority=110  , match=(ct.new && ip4.dst == 66.66.66.66), action=(reg0[[1]] = 0; ct_lb(backends=42.42.42.2);)
-  table=??(ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1), action=(ct_lb;)
-  table=??(ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip4.dst == 66.66.66.66), action=(reg1 = 66.66.66.66; ct_lb;)
-  table=??(ls_out_pre_stateful), priority=110  , match=(reg0[[2]] == 1), action=(ct_lb;)
-])
-
-check ovn-nbctl --wait=sb set logical_router lr options:lb_force_snat_ip="42.42.42.1"
-AT_CHECK([ovn-sbctl lflow-list | grep lr_in_dnat | ovn_strip_lflows], [0], [dnl
-  table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 66.66.66.66), action=(flags.force_snat_for_lb = 1; ct_lb(backends=42.42.42.2; force_snat);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
-])
-check ovn-nbctl remove logical_router lr options lb_force_snat_ip
-
-check ovn-nbctl --wait=sb set load_balancer lb-test options:skip_snat="true"
-AT_CHECK([ovn-sbctl lflow-list | grep lr_in_dnat | ovn_strip_lflows], [0], [dnl
-  table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 66.66.66.66), action=(flags.skip_snat_for_lb = 1; ct_lb(backends=42.42.42.2; skip_snat);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
-])
-check ovn-nbctl remove load_balancer lb-test options skip_snat
-
-AS_BOX([Chassis upgrades and supports ct_lb_mark - use ct_lb_mark and ct_mark.natted])
-check ovn-sbctl set chassis hv other_config:ct-no-masked-label=true
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb | ovn_strip_lflows], [0], [dnl
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
-  table=??(ls_in_lb           ), priority=110  , match=(ct.new && ip4.dst == 66.66.66.66), action=(reg0[[1]] = 0; ct_lb_mark(backends=42.42.42.2);)
-  table=??(ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1), action=(ct_lb_mark;)
-  table=??(ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip4.dst == 66.66.66.66), action=(reg1 = 66.66.66.66; ct_lb_mark;)
-  table=??(ls_out_pre_stateful), priority=110  , match=(reg0[[2]] == 1), action=(ct_lb_mark;)
-])
-
-AT_CLEANUP
-])
-
-OVN_FOR_EACH_NORTHD_NO_HV([
-AT_SETUP([ACL ct_mark.blocked backwards compatibility])
-AT_KEYWORDS([acl])
-ovn_start
-
-check ovn-nbctl                                               \
-  -- ls-add ls                                                \
-  -- acl-add ls from-lport 1 1 allow-related                  \
-  -- --apply-after-lb acl-add ls from-lport 1 1 allow-related \
-  -- acl-add ls to-lport 1 1 allow-related
-
-AS_BOX([No chassis registered - use ct_mark.blocked])
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list | grep 'ls.*acl.*blocked' | ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] = 1; ct_commit_nat;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=1    , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=2    , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=4    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=6    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=1    , match=(ip && ct.est && ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg8[[16]] = 1; ct_commit_nat;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=1    , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=2    , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=4    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=6    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
-])
-
-AS_BOX([Chassis registered that doesn't support ct_mark.blocked - use ct_label.blocked])
-check ovn-sbctl chassis-add hv geneve 127.0.0.1
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list | grep 'ls.*acl.*blocked' | ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && ct_label.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(reg8[[17]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=1    , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=2    , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=4    , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=6    , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=1    , match=(ip && ct.est && ct_label.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(reg8[[17]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=1    , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=2    , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=4    , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=6    , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
-])
-
-AS_BOX([Chassis upgrades and supports ct_mark.blocked - use ct_mark.blocked])
-check ovn-sbctl set chassis hv other_config:ct-no-masked-label=true
-check ovn-nbctl --wait=sb sync
-AT_CHECK([ovn-sbctl lflow-list | grep 'ls.*acl.*blocked' | ovn_strip_lflows], [0], [dnl
-  table=??(ls_in_acl_eval     ), priority=1    , match=(ip && ct.est && ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=1    , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=2    , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=4    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;)
-  table=??(ls_in_acl_hint     ), priority=6    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=1    , match=(ip && ct.est && ct_mark.blocked == 1), action=(reg0[[1]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=1    , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=2    , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=4    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;)
-  table=??(ls_out_acl_hint    ), priority=6    , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
-])
-
-AT_CLEANUP
-])
-
 OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([Localnet MAC learning option])
 ovn_start
@@ -10177,47 +10007,46 @@  AT_CHECK([grep -e "lr_in_defrag" -e "lr_in_dnat" lflows1], [0], [dnl
   table=??(lr_in_defrag       ), priority=0    , match=(1), action=(next;)
   table=??(lr_in_defrag       ), priority=100  , match=(ip && ip4.dst == 192.168.0.1), action=(ct_dnat;)
   table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 192.168.0.1), action=(ct_lb(backends=192.168.1.10);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
+  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 192.168.0.1), action=(ct_lb_mark(backends=192.168.1.10);)
+  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;)
+  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
+  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
 ])
 
 check ovn-nbctl --wait=sb set logical_router lr options:lb_force_snat_ip="192.168.1.1"
 AT_CHECK([ovn-sbctl lflow-list | grep lr_in_dnat | ovn_strip_lflows], [0], [dnl
   table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 192.168.0.1), action=(flags.force_snat_for_lb = 1; ct_lb(backends=192.168.1.10; force_snat);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
+  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 192.168.0.1), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=192.168.1.10; force_snat);)
+  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;)
+  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
+  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
 ])
 check ovn-nbctl remove logical_router lr options lb_force_snat_ip
 
 check ovn-nbctl --wait=sb set load_balancer lb-test options:skip_snat="true"
 AT_CHECK([ovn-sbctl lflow-list | grep lr_in_dnat | ovn_strip_lflows], [0], [dnl
   table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
-  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 192.168.0.1), action=(flags.skip_snat_for_lb = 1; ct_lb(backends=192.168.1.10; skip_snat);)
-  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted), action=(next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
-  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_label.natted && ct_label.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
+  table=??(lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel && ip4 && ip4.dst == 192.168.0.1), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=192.168.1.10; skip_snat);)
+  table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;)
+  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
+  table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; next;)
 ])
 check ovn-nbctl remove load_balancer lb-test options skip_snat
 
 AT_CHECK([grep -e "ls_in_acl" -e "ls_out_acl" lflows1 | grep "priority=65532"], [0], [dnl
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
   table=??(ls_in_acl_after_lb_eval), priority=65532, match=(reg0[[17]] == 1), action=(reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
-  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(reg8[[17]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg0[[17]] = 1; reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; reg0[[17]] = 1; reg8[[16]] = 1; next;)
+  table=??(ls_in_acl_eval     ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
   table=??(ls_in_acl_eval     ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg8[[16]] = 1; next;)
-  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(reg8[[17]] = 1; next;)
+  table=??(ls_out_acl_eval    ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(reg8[[16]] = 1; next;)
+  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg8[[16]] = 1; next;)
+  table=??(ls_out_acl_eval    ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(reg8[[17]] = 1; next;)
   table=??(ls_out_acl_eval    ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(reg8[[16]] = 1; next;)
 ])
 
 AS_BOX([Chassis upgrades and supports CT related])
-check ovn-sbctl set chassis hv other_config:ct-no-masked-label=true
 check ovn-sbctl set chassis hv other_config:ovn-ct-lb-related=true
 check ovn-nbctl --wait=sb sync
 ovn-sbctl dump-flows | ovn_strip_lflows > lflows2
@@ -10257,14 +10086,12 @@  ovn_start
 
 AS_BOX([Local chassis])
 check ovn-sbctl chassis-add hv1 geneve 127.0.0.1 \
-  -- set chassis hv1 other_config:ct-no-masked-label=true \
   -- set chassis hv1 other_config:ovn-ct-lb-related=true \
   -- set chassis hv1 other_config:mac-binding-timestamp=true
 
 check ovn-nbctl --wait=sb sync
 
 AT_CHECK([as northd ovn-appctl -t ovn-northd debug/chassis-features-list], [0], [dnl
-ct_no_masked_label:    true
 ct_lb_related:         true
 mac_binding_timestamp: true
 ])
@@ -10272,14 +10099,12 @@  mac_binding_timestamp: true
 AS_BOX([Remote chassis])
 check ovn-sbctl chassis-add hv2 geneve 127.0.0.2 \
   -- set chassis hv2 other_config:is-remote=true \
-  -- set chassis hv2 other_config:ct-no-masked-label=false \
   -- set chassis hv2 other_config:ovn-ct-lb-related=false \
   -- set chassis hv2 other_config:mac-binding-timestamp=false
 
 check ovn-nbctl --wait=sb sync
 
 AT_CHECK([as northd ovn-appctl -t ovn-northd debug/chassis-features-list], [0], [dnl
-ct_no_masked_label:    true
 ct_lb_related:         true
 mac_binding_timestamp: true
 ])
@@ -12633,7 +12458,7 @@  check_engine_stats northd recompute nocompute
 check_engine_stats lflow recompute nocompute
 
 check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
-check ovn-sbctl set chassis . other_config:ct-no-masked-label=true
+check ovn-sbctl set chassis . other_config:ct-commit-to-zone=true
 check ovn-nbctl --wait=sb sync
 check_engine_stats global_config norecompute compute
 check_engine_stats mac_binding_aging recompute nocompute
diff --git a/tests/ovn.at b/tests/ovn.at
index 185ba4a21e..cecf09a446 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -327,13 +327,8 @@  ct.rpl = ct_state[3]
 ct.snat = ct_state[6]
 ct.trk = ct_state[5]
 ct_label = NXM_NX_CT_LABEL
-ct_label.blocked = ct_label[0]
 ct_label.ecmp_reply_eth = ct_label[32..79]
-ct_label.ecmp_reply_port = ct_label[80..95]
-ct_label.force_snat = ct_label[3]
 ct_label.label = ct_label[96..127]
-ct_label.natted = ct_label[1]
-ct_label.skip_snat = ct_label[2]
 ct_mark = NXM_NX_CT_MARK
 ct_mark.blocked = ct_mark[0]
 ct_mark.ecmp_reply_port = ct_mark[16..31]
@@ -1362,10 +1357,10 @@  ct_commit(ct_label=18446744073709551616);
 
 ct_mark = 12345
     Field ct_mark is not modifiable.
+ct_mark.blocked = 1/1
+    Field ct_mark.blocked is not modifiable.
 ct_label = 0xcafe
     Field ct_label is not modifiable.
-ct_label.blocked = 1/1
-    Field ct_label.blocked is not modifiable.
 
 # ct_dnat
 ct_dnat;