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