From patchwork Fri Nov 19 16:32:08 2021
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Numan Siddique
X-Patchwork-Id: 1557298
Return-Path:
X-Original-To: incoming@patchwork.ozlabs.org
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
Authentication-Results: ozlabs.org;
spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org
(client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org;
envelope-from=ovs-dev-bounces@openvswitch.org; receiver=)
Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest
SHA256)
(No client certificate requested)
by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Hwhz45ZWCz9sVc
for ; Sat, 20 Nov 2021 03:32:32 +1100 (AEDT)
Received: from localhost (localhost [127.0.0.1])
by smtp3.osuosl.org (Postfix) with ESMTP id 6694761C3B;
Fri, 19 Nov 2021 16:32:30 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
Received: from smtp3.osuosl.org ([127.0.0.1])
by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id L6c73-9dJUT2; Fri, 19 Nov 2021 16:32:29 +0000 (UTC)
Received: from lists.linuxfoundation.org (lf-lists.osuosl.org
[IPv6:2605:bc80:3010:104::8cd3:938])
by smtp3.osuosl.org (Postfix) with ESMTPS id 0D98F61BEB;
Fri, 19 Nov 2021 16:32:28 +0000 (UTC)
Received: from lf-lists.osuosl.org (localhost [127.0.0.1])
by lists.linuxfoundation.org (Postfix) with ESMTP id D1926C001E;
Fri, 19 Nov 2021 16:32:27 +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 F1AAEC0012
for ; Fri, 19 Nov 2021 16:32:25 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
by smtp2.osuosl.org (Postfix) with ESMTP id DE44E40956
for ; Fri, 19 Nov 2021 16:32:25 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
Received: from smtp2.osuosl.org ([127.0.0.1])
by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id aTnjQ-mt-rw8 for ;
Fri, 19 Nov 2021 16:32:24 +0000 (UTC)
X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0
Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net
[217.70.183.200])
by smtp2.osuosl.org (Postfix) with ESMTPS id 14099400F3
for ; Fri, 19 Nov 2021 16:32:23 +0000 (UTC)
Received: (Authenticated sender: numans@ovn.org)
by relay7-d.mail.gandi.net (Postfix) with ESMTPSA id 0551620009;
Fri, 19 Nov 2021 16:32:19 +0000 (UTC)
From: numans@ovn.org
To: dev@openvswitch.org
Date: Fri, 19 Nov 2021 11:32:08 -0500
Message-Id: <20211119163208.240670-1-numans@ovn.org>
X-Mailer: git-send-email 2.33.1
MIME-Version: 1.0
Subject: [ovs-dev] [PATCH ovn v3 1/2] actions: Add new actions -
ct_dnat_in_czone and ct_snat_in_czone.
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"
From: Numan Siddique
These actions are very similar to ct_dnat and ct_snat respectively
with one difference. These new actions use the same zone id
for natting. Upcoming patch will make use of these actions.
Acked-by: Mark Michelson
Signed-off-by: Numan Siddique
---
v2 -> v3
----
* Added Mark's Ack
v1 -> v2
----
* No changes.
include/ovn/actions.h | 2 ++
include/ovn/logical-fields.h | 2 ++
lib/actions.c | 59 +++++++++++++++++++++++++-----
ovn-sb.xml | 44 +++++++++++++++++++++++
tests/ovn.at | 69 ++++++++++++++++++++++++++++++++++++
utilities/ovn-trace.c | 18 ++++++++--
6 files changed, 184 insertions(+), 10 deletions(-)
diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index f023a37b9..ede5eb93c 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -66,6 +66,8 @@ struct ovn_extend_table;
OVNACT(CT_COMMIT_V2, ovnact_nest) \
OVNACT(CT_DNAT, ovnact_ct_nat) \
OVNACT(CT_SNAT, ovnact_ct_nat) \
+ OVNACT(CT_DNAT_IN_CZONE, ovnact_ct_nat) \
+ OVNACT(CT_SNAT_IN_CZONE, ovnact_ct_nat) \
OVNACT(CT_LB, ovnact_ct_lb) \
OVNACT(SELECT, ovnact_select) \
OVNACT(CT_CLEAR, ovnact_null) \
diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h
index ef97117b9..c9675f81c 100644
--- a/include/ovn/logical-fields.h
+++ b/include/ovn/logical-fields.h
@@ -36,6 +36,8 @@ enum ovn_controller_event {
* (32 bits). */
#define MFF_LOG_SNAT_ZONE MFF_REG12 /* conntrack snat zone for gateway router
* (32 bits). */
+#define MFF_LOG_NAT_ZONE MFF_LOG_DNAT_ZONE /* conntrack zone for both snat
+ * and dnat. */
#define MFF_LOG_CT_ZONE MFF_REG13 /* Logical conntrack zone for lports
* (32 bits). */
#define MFF_LOG_INPORT MFF_REG14 /* Logical input port (32 bits). */
diff --git a/lib/actions.c b/lib/actions.c
index 7cf6be308..6b9a426ae 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -917,6 +917,20 @@ parse_CT_SNAT(struct action_context *ctx)
parse_ct_nat(ctx, "ct_snat", ovnact_put_CT_SNAT(ctx->ovnacts));
}
+static void
+parse_CT_DNAT_IN_CZONE(struct action_context *ctx)
+{
+ parse_ct_nat(ctx, "ct_dnat_in_czone",
+ ovnact_put_CT_DNAT_IN_CZONE(ctx->ovnacts));
+}
+
+static void
+parse_CT_SNAT_IN_CZONE(struct action_context *ctx)
+{
+ parse_ct_nat(ctx, "ct_snat_in_czone",
+ ovnact_put_CT_SNAT_IN_CZONE(ctx->ovnacts));
+}
+
static void
format_ct_nat(const struct ovnact_ct_nat *cn, const char *name, struct ds *s)
{
@@ -954,21 +968,30 @@ format_CT_SNAT(const struct ovnact_ct_nat *cn, struct ds *s)
format_ct_nat(cn, "ct_snat", s);
}
+static void
+format_CT_DNAT_IN_CZONE(const struct ovnact_ct_nat *cn, struct ds *s)
+{
+ format_ct_nat(cn, "ct_dnat_in_czone", s);
+}
+
+static void
+format_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn, struct ds *s)
+{
+ format_ct_nat(cn, "ct_snat_in_czone", s);
+}
+
static void
encode_ct_nat(const struct ovnact_ct_nat *cn,
const struct ovnact_encode_params *ep,
- bool snat, struct ofpbuf *ofpacts)
+ bool snat, enum mf_field_id zone_src,
+ struct ofpbuf *ofpacts)
{
const size_t ct_offset = ofpacts->size;
ofpbuf_pull(ofpacts, ct_offset);
struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts);
ct->recirc_table = cn->ltable + first_ptable(ep, ep->pipeline);
- if (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.field = mf_from_id(zone_src);
ct->zone_src.ofs = 0;
ct->zone_src.n_bits = 16;
ct->flags = 0;
@@ -1020,7 +1043,7 @@ encode_CT_DNAT(const struct ovnact_ct_nat *cn,
const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- encode_ct_nat(cn, ep, false, ofpacts);
+ encode_ct_nat(cn, ep, false, MFF_LOG_DNAT_ZONE, ofpacts);
}
static void
@@ -1028,7 +1051,23 @@ encode_CT_SNAT(const struct ovnact_ct_nat *cn,
const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- encode_ct_nat(cn, ep, true, ofpacts);
+ encode_ct_nat(cn, ep, true, MFF_LOG_SNAT_ZONE, ofpacts);
+}
+
+static void
+encode_CT_DNAT_IN_CZONE(const struct ovnact_ct_nat *cn,
+ const struct ovnact_encode_params *ep,
+ struct ofpbuf *ofpacts)
+{
+ encode_ct_nat(cn, ep, false, MFF_LOG_NAT_ZONE, ofpacts);
+}
+
+static void
+encode_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn,
+ const struct ovnact_encode_params *ep,
+ struct ofpbuf *ofpacts)
+{
+ encode_ct_nat(cn, ep, true, MFF_LOG_NAT_ZONE, ofpacts);
}
static void
@@ -4017,6 +4056,10 @@ parse_action(struct action_context *ctx)
parse_CT_DNAT(ctx);
} else if (lexer_match_id(ctx->lexer, "ct_snat")) {
parse_CT_SNAT(ctx);
+ } else if (lexer_match_id(ctx->lexer, "ct_dnat_in_czone")) {
+ parse_CT_DNAT_IN_CZONE(ctx);
+ } else if (lexer_match_id(ctx->lexer, "ct_snat_in_czone")) {
+ parse_CT_SNAT_IN_CZONE(ctx);
} else if (lexer_match_id(ctx->lexer, "ct_lb")) {
parse_ct_lb_action(ctx);
} else if (lexer_match_id(ctx->lexer, "ct_clear")) {
diff --git a/ovn-sb.xml b/ovn-sb.xml
index 150051f26..9ddacdf09 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -1383,6 +1383,50 @@
+ ct_dnat_in_czone;
+ ct_dnat_in_czone(IP);
+
+
+ ct_dnat_in_czone
sends the packet through the common
+ NAT zone (used for both DNAT and SNAT) in connection tracking table
+ to unDNAT any packet that was DNATed in the opposite direction.
+ The packet is then automatically sent to 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.
+
+
+ ct_dnat_in_czone(IP)
sends the packet
+ through the common NAT 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 the changes in the packet caused by the
+ connection tracker.
+
+
+
+ ct_snat_in_czone;
+ ct_snat_in_czone(IP);
+
+
+ ct_snat_in_czone
sends the packet through the common
+ NAT zone to unSNAT any packet that was SNATed in the opposite
+ direction. The packet is automatically sent to the next tables as
+ if followed by the next;
action. The next tables
+ will see the changes in the packet caused by the connection
+ tracker.
+
+
+ ct_snat_in_czone(IP)
sends the packet\
+ through the common NAT zone to change the source IP address of
+ the packet to the one provided inside the parenthesis 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 the changes in the packet caused by the connection
+ tracker.
+
+
+
ct_clear;
Clears connection tracking state.
diff --git a/tests/ovn.at b/tests/ovn.at
index ae832918c..0d606b42f 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1193,6 +1193,40 @@ ct_dnat(192.168.1.2, 1000);
ct_dnat(192.168.1.2, 1000-100);
Syntax error at `100' range high should be greater than range low.
+# ct_dnat_in_czone
+ct_dnat_in_czone;
+ encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
+ has prereqs ip
+ct_dnat_in_czone(192.168.1.2);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
+ has prereqs ip
+ct_dnat_in_czone(fd11::2);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=fd11::2))
+ has prereqs ip
+ct_dnat_in_czone(192.168.1.2, 1-3000);
+ formats as ct_dnat_in_czone(192.168.1.2,1-3000);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1-3000))
+ has prereqs ip
+
+ct_dnat_in_czone(192.168.1.2, 192.168.1.3);
+ Syntax error at `192.168.1.3' expecting Integer for port range.
+ct_dnat_in_czone(foo);
+ Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_dnat_in_czone(foo, bar);
+ Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_dnat_in_czone();
+ Syntax error at `)' expecting IPv4 or IPv6 address.
+ct_dnat_in_czone(192.168.1.2, foo);
+ Syntax error at `foo' expecting Integer for port range.
+ct_dnat_in_czone(192.168.1.2, 1000-foo);
+ Syntax error at `foo' expecting Integer for port range.
+ct_dnat_in_czone(192.168.1.2, 1000);
+ formats as ct_dnat_in_czone(192.168.1.2,1000);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1000))
+ has prereqs ip
+ct_dnat_in_czone(192.168.1.2, 1000-100);
+ Syntax error at `100' range high should be greater than range low.
+
# ct_snat
ct_snat;
encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
@@ -1226,6 +1260,41 @@ ct_snat(192.168.1.2, 1000);
has prereqs ip
ct_snat(192.168.1.2, 1000-100);
Syntax error at `100' range high should be greater than range low.
+
+# ct_snat_in_czone
+ct_snat_in_czone;
+ encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
+ has prereqs ip
+ct_snat_in_czone(192.168.1.2);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2))
+ has prereqs ip
+ct_snat_in_czone(fd11::2);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=fd11::2))
+ has prereqs ip
+ct_snat_in_czone(192.168.1.2, 1-3000);
+ formats as ct_snat_in_czone(192.168.1.2,1-3000);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2:1-3000))
+ has prereqs ip
+
+ct_snat_in_czone(192.168.1.2, 192.168.1.3);
+ Syntax error at `192.168.1.3' expecting Integer for port range.
+ct_snat_in_czone(foo);
+ Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_snat_in_czone(foo, bar);
+ Syntax error at `foo' expecting IPv4 or IPv6 address.
+ct_snat_in_czone();
+ Syntax error at `)' expecting IPv4 or IPv6 address.
+ct_snat_in_czone(192.168.1.2, foo);
+ Syntax error at `foo' expecting Integer for port range.
+ct_snat_in_czone(192.168.1.2, 1000-foo);
+ Syntax error at `foo' expecting Integer for port range.
+ct_snat_in_czone(192.168.1.2, 1000);
+ formats as ct_snat_in_czone(192.168.1.2,1000);
+ encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2:1000))
+ has prereqs ip
+ct_snat_in_czone(192.168.1.2, 1000-100);
+ Syntax error at `100' range high should be greater than range low.
+
# ct_clear
ct_clear;
encodes as ct_clear
diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c
index 65a1822ea..617ad834c 100644
--- a/utilities/ovn-trace.c
+++ b/utilities/ovn-trace.c
@@ -2286,7 +2286,10 @@ execute_ct_nat(const struct ovnact_ct_nat *ct_nat,
const struct ovntrace_datapath *dp, struct flow *uflow,
enum ovnact_pipeline pipeline, struct ovs_list *super)
{
- bool is_dst = ct_nat->ovnact.type == OVNACT_CT_DNAT;
+ bool is_dst = (ct_nat->ovnact.type == OVNACT_CT_DNAT ||
+ ct_nat->ovnact.type == OVNACT_CT_DNAT_IN_CZONE);
+ bool nat_in_czone = (ct_nat->ovnact.type == OVNACT_CT_DNAT_IN_CZONE ||
+ ct_nat->ovnact.type == OVNACT_CT_SNAT_IN_CZONE);
if (!is_dst && dp->has_local_l3gateway && ct_nat->family == AF_UNSPEC) {
/* "ct_snat;" has no visible effect in a gateway router. */
return;
@@ -2297,7 +2300,8 @@ execute_ct_nat(const struct ovnact_ct_nat *ct_nat,
* and figure out the changes if any. */
struct flow ct_flow = *uflow;
struct ds s = DS_EMPTY_INITIALIZER;
- ds_put_format(&s, "ct_%cnat", direction[0]);
+ ds_put_format(&s, "ct_%cnat%s", direction[0],
+ nat_in_czone ? "in_czone" : "");
if (ct_nat->family != AF_UNSPEC) {
if (ct_nat->family == AF_INET) {
ds_put_format(&s, "(ip4.%s="IP_FMT")", direction,
@@ -2610,6 +2614,16 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len,
execute_ct_nat(ovnact_get_CT_SNAT(a), dp, uflow, pipeline, super);
break;
+ case OVNACT_CT_DNAT_IN_CZONE:
+ execute_ct_nat(ovnact_get_CT_DNAT_IN_CZONE(a), dp, uflow,
+ pipeline, super);
+ break;
+
+ case OVNACT_CT_SNAT_IN_CZONE:
+ execute_ct_nat(ovnact_get_CT_SNAT_IN_CZONE(a), dp, uflow,
+ pipeline, super);
+ break;
+
case OVNACT_CT_LB:
execute_ct_lb(ovnact_get_CT_LB(a), dp, uflow, pipeline, super);
break;