From patchwork Fri Apr 19 12:33:05 2024
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Martin Kalcok
X-Patchwork-Id: 1925525
Return-Path:
X-Original-To: incoming@patchwork.ozlabs.org
Delivered-To: patchwork-incoming@legolas.ozlabs.org
Authentication-Results: legolas.ozlabs.org;
dkim=fail reason="signature verification failed" (2048-bit key;
unprotected) header.d=canonical.com header.i=@canonical.com
header.a=rsa-sha256 header.s=20210705 header.b=kOzJlHkZ;
dkim-atps=neutral
Authentication-Results: legolas.ozlabs.org;
spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org
(client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org;
envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)
Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384)
(No client certificate requested)
by legolas.ozlabs.org (Postfix) with ESMTPS id 4VLYwP3RDYz1yPJ
for ; Fri, 19 Apr 2024 22:33:41 +1000 (AEST)
Received: from localhost (localhost [127.0.0.1])
by smtp2.osuosl.org (Postfix) with ESMTP id DB3D4405F1;
Fri, 19 Apr 2024 12:33:38 +0000 (UTC)
X-Virus-Scanned: amavis at osuosl.org
Received: from smtp2.osuosl.org ([127.0.0.1])
by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP
id Q39bVqTIxFak; Fri, 19 Apr 2024 12:33:37 +0000 (UTC)
X-Comment: SPF check N/A for local connections -
client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org;
envelope-from=ovs-dev-bounces@openvswitch.org; receiver=
DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 0450240148
Authentication-Results: smtp2.osuosl.org;
dkim=fail reason="signature verification failed" (2048-bit key)
header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256
header.s=20210705 header.b=kOzJlHkZ
Received: from lists.linuxfoundation.org (lf-lists.osuosl.org
[IPv6:2605:bc80:3010:104::8cd3:938])
by smtp2.osuosl.org (Postfix) with ESMTPS id 0450240148;
Fri, 19 Apr 2024 12:33:37 +0000 (UTC)
Received: from lf-lists.osuosl.org (localhost [127.0.0.1])
by lists.linuxfoundation.org (Postfix) with ESMTP id CC3E8C0077;
Fri, 19 Apr 2024 12:33:36 +0000 (UTC)
X-Original-To: dev@openvswitch.org
Delivered-To: ovs-dev@lists.linuxfoundation.org
Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])
by lists.linuxfoundation.org (Postfix) with ESMTP id C5A1AC0037
for ; Fri, 19 Apr 2024 12:33:34 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
by smtp2.osuosl.org (Postfix) with ESMTP id 9C70940486
for ; Fri, 19 Apr 2024 12:33:34 +0000 (UTC)
X-Virus-Scanned: amavis at osuosl.org
Received: from smtp2.osuosl.org ([127.0.0.1])
by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP
id qzpmHxQIQZvx for ;
Fri, 19 Apr 2024 12:33:33 +0000 (UTC)
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=185.125.188.121;
helo=smtp-relay-canonical-1.canonical.com;
envelope-from=martin.kalcok@canonical.com; receiver=
DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org C718440148
Authentication-Results: smtp2.osuosl.org;
dmarc=pass (p=none dis=none) header.from=canonical.com
DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org C718440148
Received: from smtp-relay-canonical-1.canonical.com
(smtp-relay-canonical-1.canonical.com [185.125.188.121])
by smtp2.osuosl.org (Postfix) with ESMTPS id C718440148
for ; Fri, 19 Apr 2024 12:33:32 +0000 (UTC)
Received: from localhost.localdomain (178-143-45-28.static.orange.sk
[178.143.45.28])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest
SHA256)
(No client certificate requested)
by smtp-relay-canonical-1.canonical.com (Postfix) with ESMTPSA id C17DE3F0F8;
Fri, 19 Apr 2024 12:33:29 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com;
s=20210705; t=1713530009;
bh=kP3wDjHZOkjN8vcRkL64QXBZaBltI7lmRoyU26nV0H4=;
h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:
MIME-Version;
b=kOzJlHkZz5sRhz+DUjDjZxbw+Q7+OP7x7yBEiQ75dnY4ATiIy0b31cqke+wpstJZv
anGtsQc5dQxJVMUQpFCDXivZpMrhTqQe5h91q96mNivF3S0YpFIcl4QvC7h8pMhsZ2
VPzs4kk7JcB4RIMXsw0oUIjZR5JjtTtsXCsdu8vpAsW5C3bxS/IDEQIMw3RwNzUz2/
C7Pg3FZtsXkXWf5JDkmA4x7o2uOIpKvxYkj08L5foVNnDVCXUQ1wfuVFFxfVzScOm3
7VFAwEGAg7qtnQpC3K8A6Xv42Ob8VktNUj4r6XmRjw5M7R9tBzXSJ3BC4EDcApktJ8
pq8UcKzU8MMfw==
From: Martin Kalcok
To: dceara@redhat.com,
amusil@redhat.com,
dev@openvswitch.org
Date: Fri, 19 Apr 2024 14:33:05 +0200
Message-Id: <20240419123306.46145-1-martin.kalcok@canonical.com>
X-Mailer: git-send-email 2.40.1
In-Reply-To:
References:
MIME-Version: 1.0
Subject: [ovs-dev] [Patch ovn v4 1/2] actions: New action ct_commit_to_zone.
X-BeenThere: ovs-dev@openvswitch.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id:
List-Unsubscribe: ,
List-Archive:
List-Post:
List-Help:
List-Subscribe: ,
Errors-To: ovs-dev-bounces@openvswitch.org
Sender: "dev"
This change adds a new action 'ct_commit_to_zone' that enables users to commit
the flow into a specific zone in the connection tracker.
A new feature flag, OVN_FEATURE_CT_COMMIT_TO_ZONE, is also included to avoid
issues during upgrade in case the northd is upgraded to a version that supports
this action before the controller is upgraded.
Note that this action is meaningful only in the context of Logical Router
datapath. Logical Switch datapath does not use multiple zones and this action
falls back to committing the connection into the default zone for the Logical
Switch.
Signed-off-by: Martin Kalcok
Acked-by: Ales Musil
---
controller/chassis.c | 8 ++
include/ovn/actions.h | 8 +-
include/ovn/features.h | 1 +
lib/actions.c | 155 +++++++++++++++++++++++++-------------
northd/en-global-config.c | 10 +++
northd/en-global-config.h | 1 +
ovn-sb.xml | 22 +++++-
tests/ovn.at | 16 ++++
utilities/ovn-trace.c | 45 ++++++++---
9 files changed, 199 insertions(+), 67 deletions(-)
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 8e794450c..aa5e4ab89 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -68,6 +68,7 @@ struct collector_set_ids;
OVNACT(CT_NEXT, ovnact_ct_next) \
/* CT_COMMIT_V1 is not supported anymore. */ \
OVNACT(CT_COMMIT_V2, ovnact_nest) \
+ OVNACT(CT_COMMIT_TO_ZONE, ovnact_ct_commit_to_zone) \
OVNACT(CT_DNAT, ovnact_ct_nat) \
OVNACT(CT_SNAT, ovnact_ct_nat) \
OVNACT(CT_DNAT_IN_CZONE, ovnact_ct_nat) \
@@ -76,7 +77,7 @@ struct collector_set_ids;
OVNACT(CT_LB_MARK, ovnact_ct_lb) \
OVNACT(SELECT, ovnact_select) \
OVNACT(CT_CLEAR, ovnact_null) \
- OVNACT(CT_COMMIT_NAT, ovnact_ct_commit_nat) \
+ OVNACT(CT_COMMIT_NAT, ovnact_ct_commit_to_zone) \
OVNACT(CLONE, ovnact_nest) \
OVNACT(ARP, ovnact_nest) \
OVNACT(ICMP4, ovnact_nest) \
@@ -290,11 +291,12 @@ struct ovnact_ct_nat {
uint8_t ltable; /* Logical table ID of next table. */
};
-/* OVNACT_CT_COMMIT_NAT. */
-struct ovnact_ct_commit_nat {
+/* OVNACT_CT_COMMIT_TO_ZONE, OVNACT_CT_COMMIT_NAT. */
+struct ovnact_ct_commit_to_zone {
struct ovnact ovnact;
bool dnat_zone;
+ bool do_nat;
uint8_t ltable;
};
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 39bb5bc8a..b9bdcd48d 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -870,6 +870,45 @@ parse_ct_nat(struct action_context *ctx, const char *name,
}
}
+static void
+parse_ct_commit_to_zone(struct action_context *ctx, const char *name,
+ bool do_nat, bool require_param,
+ struct ovnact_ct_commit_to_zone *cn)
+{
+ add_prerequisite(ctx, "ip");
+
+ if (ctx->pp->cur_ltable >= ctx->pp->n_tables) {
+ lexer_error(ctx->lexer,
+ "\"%s\" action not allowed in last table.", name);
+ return;
+ }
+
+ cn->ltable = ctx->pp->cur_ltable + 1;
+ cn->do_nat = do_nat;
+ cn->dnat_zone = true;
+
+ if (require_param) {
+ lexer_force_match(ctx->lexer, LEX_T_LPAREN);
+ } else {
+ if (!lexer_match(ctx->lexer, LEX_T_LPAREN)) {
+ return;
+ }
+ }
+
+ if (lexer_match_id(ctx->lexer, "dnat")) {
+ cn->dnat_zone = true;
+ } else if (lexer_match_id(ctx->lexer, "snat")) {
+ cn->dnat_zone = false;
+ } else {
+ lexer_error(ctx->lexer, "\"%s\" action accepts"
+ " only \"dnat\" or \"snat\" parameter.", name);
+ return;
+ }
+
+ lexer_force_match(ctx->lexer, LEX_T_RPAREN);
+}
+
+
static void
parse_CT_DNAT(struct action_context *ctx)
{
@@ -901,33 +940,17 @@ parse_CT_SNAT_IN_CZONE(struct action_context *ctx)
static void
parse_CT_COMMIT_NAT(struct action_context *ctx)
{
- add_prerequisite(ctx, "ip");
-
- if (ctx->pp->cur_ltable >= ctx->pp->n_tables) {
- lexer_error(ctx->lexer,
- "\"ct_commit_nat\" action not allowed in last table.");
- return;
- }
-
- struct ovnact_ct_commit_nat *cn = ovnact_put_CT_COMMIT_NAT(ctx->ovnacts);
- cn->ltable = ctx->pp->cur_ltable + 1;
- cn->dnat_zone = true;
-
- if (!lexer_match(ctx->lexer, LEX_T_LPAREN)) {
- return;
- }
-
- if (lexer_match_id(ctx->lexer, "dnat")) {
- cn->dnat_zone = true;
- } else if (lexer_match_id(ctx->lexer, "snat")) {
- cn->dnat_zone = false;
- } else {
- lexer_error(ctx->lexer, "\"ct_commit_nat\" action accepts"
- " only \"dnat\" or \"snat\" parameter.");
- return;
- }
+ parse_ct_commit_to_zone(ctx, "ct_commit_nat",
+ true, false,
+ ovnact_put_CT_COMMIT_NAT(ctx->ovnacts));
+}
- lexer_force_match(ctx->lexer, LEX_T_RPAREN);
+static void
+parse_CT_COMMIT_TO_ZONE(struct action_context *ctx)
+{
+ parse_ct_commit_to_zone(ctx, "ct_commit_to_zone",
+ false, true,
+ ovnact_put_CT_COMMIT_TO_ZONE(ctx->ovnacts));
}
static void
@@ -980,12 +1003,20 @@ format_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn, struct ds *s)
}
static void
-format_CT_COMMIT_NAT(const struct ovnact_ct_commit_nat *cn, struct ds *s)
+format_CT_COMMIT_NAT(const struct ovnact_ct_commit_to_zone *cn, struct ds *s)
{
ds_put_cstr(s, "ct_commit_nat");
ds_put_cstr(s, cn->dnat_zone ? "(dnat);" : "(snat);");
}
+static void
+format_CT_COMMIT_TO_ZONE(const struct ovnact_ct_commit_to_zone *cn,
+ struct ds *s)
+{
+ ds_put_cstr(s, "ct_commit_to_zone");
+ ds_put_cstr(s, cn->dnat_zone ? "(dnat);" : "(snat);");
+}
+
static void
encode_ct_nat(const struct ovnact_ct_nat *cn,
const struct ovnact_encode_params *ep,
@@ -1055,6 +1086,39 @@ encode_ct_nat(const struct ovnact_ct_nat *cn,
ofpbuf_push_uninit(ofpacts, ct_offset);
}
+static void
+encode_ct_commit_to_zone(const struct ovnact_ct_commit_to_zone *cn,
+ const struct ovnact_encode_params *ep,
+ struct ofpbuf *ofpacts)
+{
+ const size_t ct_offset = ofpacts->size;
+
+ struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts);
+ ct->recirc_table = cn->ltable + first_ptable(ep, ep->pipeline);
+ ct->zone_src.ofs = 0;
+ ct->zone_src.n_bits = 16;
+ ct->flags = NX_CT_F_COMMIT;
+ ct->alg = 0;
+
+ if (ep->is_switch) {
+ ct->zone_src.field = mf_from_id(MFF_LOG_CT_ZONE);
+ } else {
+ ct->zone_src.field = mf_from_id(cn->dnat_zone
+ ? MFF_LOG_DNAT_ZONE
+ : MFF_LOG_SNAT_ZONE);
+ }
+
+ if (cn->do_nat) {
+ struct ofpact_nat *nat = ofpact_put_NAT(ofpacts);
+ nat->range_af = AF_UNSPEC;
+ nat->flags = 0;
+ }
+
+ ct = ofpbuf_at_assert(ofpacts, ct_offset, sizeof *ct);
+ ofpacts->header = ct;
+ ofpact_finish_CT(ofpacts, &ct);
+}
+
static void
encode_CT_DNAT(const struct ovnact_ct_nat *cn,
const struct ovnact_encode_params *ep,
@@ -1088,34 +1152,19 @@ encode_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn,
}
static void
-encode_CT_COMMIT_NAT(const struct ovnact_ct_commit_nat *cn,
+encode_CT_COMMIT_NAT(const struct ovnact_ct_commit_to_zone *cn,
const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- const size_t ct_offset = ofpacts->size;
-
- struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts);
- ct->recirc_table = cn->ltable + first_ptable(ep, ep->pipeline);
- ct->zone_src.ofs = 0;
- ct->zone_src.n_bits = 16;
- ct->flags = NX_CT_F_COMMIT;
- ct->alg = 0;
-
- if (ep->is_switch) {
- ct->zone_src.field = mf_from_id(MFF_LOG_CT_ZONE);
- } else {
- ct->zone_src.field = mf_from_id(cn->dnat_zone
- ? MFF_LOG_DNAT_ZONE
- : MFF_LOG_SNAT_ZONE);
- }
-
- struct ofpact_nat *nat = ofpact_put_NAT(ofpacts);
- nat->range_af = AF_UNSPEC;
- nat->flags = 0;
+ encode_ct_commit_to_zone(cn, ep, ofpacts);
+}
- ct = ofpbuf_at_assert(ofpacts, ct_offset, sizeof *ct);
- ofpacts->header = ct;
- ofpact_finish_CT(ofpacts, &ct);
+static void
+encode_CT_COMMIT_TO_ZONE(const struct ovnact_ct_commit_to_zone *cn,
+ const struct ovnact_encode_params *ep,
+ struct ofpbuf *ofpacts)
+{
+ encode_ct_commit_to_zone(cn, ep, ofpacts);
}
static void
@@ -1124,7 +1173,7 @@ ovnact_ct_nat_free(struct ovnact_ct_nat *ct_nat OVS_UNUSED)
}
static void
-ovnact_ct_commit_nat_free(struct ovnact_ct_commit_nat *cn OVS_UNUSED)
+ovnact_ct_commit_to_zone_free(struct ovnact_ct_commit_to_zone *cn OVS_UNUSED)
{
}
@@ -5306,6 +5355,8 @@ parse_action(struct action_context *ctx)
parse_CT_NEXT(ctx);
} else if (lexer_match_id(ctx->lexer, "ct_commit")) {
parse_CT_COMMIT(ctx);
+ } else if (lexer_match_id(ctx->lexer, "ct_commit_to_zone")) {
+ parse_CT_COMMIT_TO_ZONE(ctx);
} else if (lexer_match_id(ctx->lexer, "ct_dnat")) {
parse_CT_DNAT(ctx);
} else if (lexer_match_id(ctx->lexer, "ct_snat")) {
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 4c26c6714..ab0c37c8d 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -1432,13 +1432,31 @@
+ ct_commit_to_zone(dnat);
+ ct_commit_to_zone(snat);
+
+
+ Commit the flow to the specific zone in the connection tracker.
+ The packet is then automatically sent to the next tables as if
+ followed by next;
action. The next tables will
+ see the changes in the packet caused by the connection tracker.
+
+
+
+ Note that this action is meaningful only in the Logical Router
+ Datapath as the Logical Switch Datapath does not use separate
+ connection tracking zones. Using this action in Logical Switch
+ Datapath falls back to committing the flow into the logical port's
+ conntrack zone.
+
+
ct_dnat;
ct_dnat(IP);
ct_dnat
sends the packet through the DNAT zone in
connection tracking table to unDNAT any packet that was DNATed in
- the opposite direction. The packet is then automatically sent to
+ the opposite direction. The packet is then automatically sent
to the next tables as if followed by next;
action.
The next tables will see the changes in the packet caused by
the connection tracker.
@@ -1448,7 +1466,7 @@
DNAT zone to change the destination IP address of the packet to
the one provided inside the parentheses and commits the connection.
The packet is then automatically sent to the next tables as if
- followed by next;
action. The next tables will see
+ followed by next;
action. The next tables will see
the changes in the packet caused by the connection tracker.
diff --git a/tests/ovn.at b/tests/ovn.at
index c8cc1d37f..1852457e1 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1316,6 +1316,22 @@ ct_commit { ct_label=0x181716151413121110090807060504030201; };
ct_commit { ip4.dst = 192.168.0.1; };
Field ip4.dst is not modifiable.
+# ct_commit_to_zone
+ct_commit_to_zone(dnat);
+ encodes as ct(commit,table=oflow_in_table,zone=NXM_NX_REG13[[0..15]])
+ has prereqs ip
+ct_commit_to_zone(snat);
+ encodes as ct(commit,table=oflow_in_table,zone=NXM_NX_REG13[[0..15]])
+ has prereqs ip
+ct_commit_to_zone;
+ Syntax error at `;' expecting `('.
+ct_commit_to_zone();
+ "ct_commit_to_zone" action accepts only "dnat" or "snat" parameter.
+ct_commit_to_zone(foo);
+ "ct_commit_to_zone" action accepts only "dnat" or "snat" parameter.
+ct_commit_to_zone(dnat;
+ Syntax error at `;' expecting `)'.
+
# Legact ct_commit_v1 action.
ct_commit();
Syntax error at `(' expecting `;'.
diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c
index ee086a7ae..7aa6e2ca9 100644
--- a/utilities/ovn-trace.c
+++ b/utilities/ovn-trace.c
@@ -2463,24 +2463,20 @@ execute_ct_nat(const struct ovnact_ct_nat *ct_nat,
}
static void
-execute_ct_commit_nat(const struct ovnact_ct_commit_nat *ct_nat,
- const struct ovntrace_datapath *dp, struct flow *uflow,
- enum ovnact_pipeline pipeline, struct ovs_list *super)
+ct_commit_to_zone__(const struct ovnact_ct_commit_to_zone *ct_nat,
+ const struct ovntrace_datapath *dp, struct flow *uflow,
+ enum ovnact_pipeline pipeline, struct ovs_list *super,
+ struct ds *action)
{
struct flow ct_flow = *uflow;
- struct ds s = DS_EMPTY_INITIALIZER;
-
- ds_put_cstr(&s, "ct_commit_nat /* assuming no"
- " un-nat entry, so no change */");
/* ct(nat) implies ct(). */
if (!(ct_flow.ct_state & CS_TRACKED)) {
- ct_flow.ct_state |= next_ct_state(&s);
+ ct_flow.ct_state |= next_ct_state(action);
}
struct ovntrace_node *node = ovntrace_node_append(
- super, OVNTRACE_NODE_TRANSFORMATION, "%s", ds_cstr(&s));
- ds_destroy(&s);
+ super, OVNTRACE_NODE_TRANSFORMATION, "%s", ds_cstr(action));
/* Trace the actions in the next table. */
trace__(dp, &ct_flow, ct_nat->ltable, pipeline, &node->subs);
@@ -2490,6 +2486,30 @@ execute_ct_commit_nat(const struct ovnact_ct_commit_nat *ct_nat,
* flow, not ct_flow. */
}
+static void
+execute_ct_commit_nat(const struct ovnact_ct_commit_to_zone *ct_nat,
+ const struct ovntrace_datapath *dp, struct flow *uflow,
+ enum ovnact_pipeline pipeline, struct ovs_list *super)
+{
+ struct ds s = DS_EMPTY_INITIALIZER;
+ ds_put_cstr(&s, "ct_commit_nat /* assuming no"
+ " un-nat entry, so no change */");
+ ct_commit_to_zone__(ct_nat, dp, uflow, pipeline, super, &s);
+ ds_destroy(&s);
+}
+
+static void
+execute_ct_commit_to_zone(const struct ovnact_ct_commit_to_zone *ct_commit,
+ const struct ovntrace_datapath *dp,
+ struct flow *uflow, enum ovnact_pipeline pipeline,
+ struct ovs_list *super)
+{
+ struct ds s = DS_EMPTY_INITIALIZER;
+ ds_put_format(&s, "ct_commit_to_zone(%s)",
+ ct_commit->dnat_zone ? "dnat" : "snat");
+ ct_commit_to_zone__(ct_commit, dp, uflow, pipeline, super, &s);
+ ds_destroy(&s);
+}
static void
execute_ct_lb(const struct ovnact_ct_lb *ct_lb,
@@ -3147,6 +3167,11 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len,
flow_clear_conntrack(uflow);
break;
+ case OVNACT_CT_COMMIT_TO_ZONE:
+ execute_ct_commit_to_zone(ovnact_get_CT_COMMIT_TO_ZONE(a), dp,
+ uflow, pipeline, super);
+ break;
+
case OVNACT_CT_COMMIT_NAT:
execute_ct_commit_nat(ovnact_get_CT_COMMIT_NAT(a), dp, uflow,
pipeline, super);