Action `ct_commit` currently does not allow specifying zone into
which connection is committed. For example, in LR datapath, the `ct_commit`
will always use the DNAT zone.

This change adds option to use `ct_commit(snat)` or `ct_commit(dnat)` to
explicitly specify the zone into which the connection will be committed.
It also comes with new feature flag OVN_FEATURE_CT_COMMIT_TO_ZONE to avoid
incompatibility between northd and controller in case when controller does
not suport these actions.

Original behavior of `ct_commit` without the arguments remains unchanged.

Signed-off-by: Martin Kalcok <martin.kal...@canonical.com>
---
 controller/chassis.c      |  8 ++++++++
 include/ovn/actions.h     |  9 +++++++++
 include/ovn/features.h    |  1 +
 lib/actions.c             | 29 ++++++++++++++++++++++++++++-
 northd/en-global-config.c | 10 ++++++++++
 northd/en-global-config.h |  1 +
 ovn-sb.xml                | 10 ++++++++++
 tests/ovn.at              |  7 +++++++
 8 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/controller/chassis.c b/controller/chassis.c
index ad75df288..9bb2eba95 100644
--- a/controller/chassis.c
+++ b/controller/chassis.c
@@ -371,6 +371,7 @@ chassis_build_other_config(const struct ovs_chassis_cfg 
*ovs_cfg,
     smap_replace(config, OVN_FEATURE_FDB_TIMESTAMP, "true");
     smap_replace(config, OVN_FEATURE_LS_DPG_COLUMN, "true");
     smap_replace(config, OVN_FEATURE_CT_COMMIT_NAT_V2, "true");
+    smap_replace(config, OVN_FEATURE_CT_COMMIT_TO_ZONE, "true");
 }
 
 /*
@@ -516,6 +517,12 @@ chassis_other_config_changed(const struct ovs_chassis_cfg 
*ovs_cfg,
         return true;
     }
 
+    if (!smap_get_bool(&chassis_rec->other_config,
+                       OVN_FEATURE_CT_COMMIT_TO_ZONE,
+                       false)) {
+        return true;
+    }
+
     return false;
 }
 
@@ -648,6 +655,7 @@ update_supported_sset(struct sset *supported)
     sset_add(supported, OVN_FEATURE_FDB_TIMESTAMP);
     sset_add(supported, OVN_FEATURE_LS_DPG_COLUMN);
     sset_add(supported, OVN_FEATURE_CT_COMMIT_NAT_V2);
+    sset_add(supported, OVN_FEATURE_CT_COMMIT_TO_ZONE);
 }
 
 static void
diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index 49fb96fc6..ce9597cf5 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -259,11 +259,20 @@ struct ovnact_ct_next {
     uint8_t ltable;                /* Logical table ID of next table. */
 };
 
+/* Conntrack zone to be used for commiting CT entries by the action.
+ * DEFAULT uses default zone for given datapath. */
+enum ovnact_ct_zone {
+    OVNACT_CT_ZONE_DEFAULT,
+    OVNACT_CT_ZONE_SNAT,
+    OVNACT_CT_ZONE_DNAT,
+};
+
 /* OVNACT_CT_COMMIT_V1. */
 struct ovnact_ct_commit_v1 {
     struct ovnact ovnact;
     uint32_t ct_mark, ct_mark_mask;
     ovs_be128 ct_label, ct_label_mask;
+    enum ovnact_ct_zone zone;
 };
 
 /* Type of NAT used for the particular action.
diff --git a/include/ovn/features.h b/include/ovn/features.h
index 08f1d8288..35a5d8ba0 100644
--- a/include/ovn/features.h
+++ b/include/ovn/features.h
@@ -28,6 +28,7 @@
 #define OVN_FEATURE_FDB_TIMESTAMP "fdb-timestamp"
 #define OVN_FEATURE_LS_DPG_COLUMN "ls-dpg-column"
 #define OVN_FEATURE_CT_COMMIT_NAT_V2 "ct-commit-nat-v2"
+#define OVN_FEATURE_CT_COMMIT_TO_ZONE "ct-commit-to-zone"
 
 /* OVS datapath supported features.  Based on availability OVN might generate
  * different types of openflows.
diff --git a/lib/actions.c b/lib/actions.c
index a45874dfb..9e27a68a5 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -707,6 +707,7 @@ static void
 parse_ct_commit_v1_arg(struct action_context *ctx,
                        struct ovnact_ct_commit_v1 *cc)
 {
+    cc->zone = OVNACT_CT_ZONE_DEFAULT;
     if (lexer_match_id(ctx->lexer, "ct_mark")) {
         if (!lexer_force_match(ctx->lexer, LEX_T_EQUALS)) {
             return;
@@ -737,6 +738,10 @@ parse_ct_commit_v1_arg(struct action_context *ctx,
             return;
         }
         lexer_get(ctx->lexer);
+    } else if (lexer_match_id(ctx->lexer, "snat")) {
+        cc->zone = OVNACT_CT_ZONE_SNAT;
+    } else if (lexer_match_id(ctx->lexer, "dnat")) {
+        cc->zone = OVNACT_CT_ZONE_DNAT;
     } else {
         lexer_syntax_error(ctx->lexer, NULL);
     }
@@ -800,6 +805,18 @@ format_CT_COMMIT_V1(const struct ovnact_ct_commit_v1 *cc, 
struct ds *s)
             ds_put_hex(s, &cc->ct_label_mask, sizeof cc->ct_label_mask);
         }
     }
+    if (cc->zone != OVNACT_CT_ZONE_DEFAULT) {
+        if (ds_last(s) != '(') {
+            ds_put_cstr(s, ", ");
+        }
+
+        if (cc->zone == OVNACT_CT_ZONE_SNAT) {
+            ds_put_cstr(s, "snat");
+        } else if (cc->zone == OVNACT_CT_ZONE_DNAT) {
+            ds_put_cstr(s, "dnat");
+        }
+    }
+
     if (!ds_chomp(s, '(')) {
         ds_put_char(s, ')');
     }
@@ -814,7 +831,17 @@ encode_CT_COMMIT_V1(const struct ovnact_ct_commit_v1 *cc,
     struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts);
     ct->flags = NX_CT_F_COMMIT;
     ct->recirc_table = NX_CT_RECIRC_NONE;
-    ct->zone_src.field = mf_from_id(MFF_LOG_CT_ZONE);
+
+    if (ep->is_switch) {
+        ct->zone_src.field = mf_from_id(MFF_LOG_CT_ZONE);
+    } else {
+        if (cc->zone == OVNACT_CT_ZONE_SNAT) {
+            ct->zone_src.field = mf_from_id(MFF_LOG_SNAT_ZONE);
+        } else {
+            ct->zone_src.field = mf_from_id(MFF_LOG_DNAT_ZONE);
+        }
+    }
+
     ct->zone_src.ofs = 0;
     ct->zone_src.n_bits = 16;
 
diff --git a/northd/en-global-config.c b/northd/en-global-config.c
index 34e393b33..193deaebc 100644
--- a/northd/en-global-config.c
+++ b/northd/en-global-config.c
@@ -370,6 +370,7 @@ northd_enable_all_features(struct ed_type_global_config 
*data)
         .fdb_timestamp = true,
         .ls_dpg_column = true,
         .ct_commit_nat_v2 = true,
+        .ct_commit_to_zone = true,
     };
 }
 
@@ -439,6 +440,15 @@ build_chassis_features(const struct sbrec_chassis_table 
*sbrec_chassis_table,
             chassis_features->ct_commit_nat_v2) {
             chassis_features->ct_commit_nat_v2 = false;
         }
+
+        bool ct_commit_to_zone =
+                smap_get_bool(&chassis->other_config,
+                              OVN_FEATURE_CT_COMMIT_TO_ZONE,
+                              false);
+        if (!ct_commit_to_zone &&
+            chassis_features->ct_commit_to_zone) {
+            chassis_features->ct_commit_to_zone = false;
+        }
     }
 }
 
diff --git a/northd/en-global-config.h b/northd/en-global-config.h
index 38d732808..842bcee70 100644
--- a/northd/en-global-config.h
+++ b/northd/en-global-config.h
@@ -20,6 +20,7 @@ struct chassis_features {
     bool fdb_timestamp;
     bool ls_dpg_column;
     bool ct_commit_nat_v2;
+    bool ct_commit_to_zone;
 };
 
 struct global_config_tracked_data {
diff --git a/ovn-sb.xml b/ovn-sb.xml
index ac4e585f2..f5f2208da 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -1405,6 +1405,8 @@
         <dt><code>ct_commit { ct_mark=<var>value[/mask]</var>; };</code></dt>
         <dt><code>ct_commit { ct_label=<var>value[/mask]</var>; };</code></dt>
         <dt><code>ct_commit { ct_mark=<var>value[/mask]</var>; 
ct_label=<var>value[/mask]</var>; };</code></dt>
+        <dt><code>ct_commit(snat);</code></dt>
+        <dt><code>ct_commit(dnat);</code></dt>
         <dd>
           <p>
             Commit the flow to the connection tracking entry associated with it
@@ -1421,6 +1423,14 @@
             in order to have specific bits set.
           </p>
 
+          <p>
+            In Logical Router Datapath, parameters <code>ct_commit(snat)</code>
+            or <code>ct_commit(dnat) </code> can be used to explicitly specify
+            into which zone should be connection committed. Without this
+            parameter, the connection is committed to the default zone for the
+            Datapath. These parameters have no effect in Logical Switch 
Datapath.
+          </p>
+
           <p>
             Note that if you want processing to continue in the next table,
             you must execute the <code>next</code> action after
diff --git a/tests/ovn.at b/tests/ovn.at
index d26c95054..11e6430ed 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1349,6 +1349,13 @@ ct_commit(ct_label=18446744073709551615);
 ct_commit(ct_label=18446744073709551616);
     Decimal constants must be less than 2**64.
 
+ct_commit(dnat);
+    encodes as ct(commit,zone=NXM_NX_REG13[0..15])
+    has prereqs ip
+ct_commit(snat);
+    encodes as ct(commit,zone=NXM_NX_REG13[0..15])
+    has prereqs ip
+
 ct_mark = 12345
     Field ct_mark is not modifiable.
 ct_label = 0xcafe
-- 
2.40.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to