From patchwork Thu Nov 18 18:13:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1556760 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::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) 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 RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Hw7GD34GRz9sPf for ; Fri, 19 Nov 2021 05:13:40 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 567A2403DA; Thu, 18 Nov 2021 18:13:36 +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 KeNqdj8jw-S8; Thu, 18 Nov 2021 18:13:34 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTPS id 324504037C; Thu, 18 Nov 2021 18:13:33 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E71E5C002E; Thu, 18 Nov 2021 18:13:32 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 801F6C0012 for ; Thu, 18 Nov 2021 18:13:31 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 5C646403CA for ; Thu, 18 Nov 2021 18:13:31 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id POFdiiwUBrxi for ; Thu, 18 Nov 2021 18:13:30 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by smtp4.osuosl.org (Postfix) with ESMTPS id CCAF840386 for ; Thu, 18 Nov 2021 18:13:29 +0000 (UTC) Received: (Authenticated sender: numans@ovn.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id BFFA4C0011; Thu, 18 Nov 2021 18:13:24 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Thu, 18 Nov 2021 13:13:05 -0500 Message-Id: <20211118181305.92940-1-numans@ovn.org> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn v2 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. Signed-off-by: Numan Siddique Acked-by: Mark Michelson --- 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; From patchwork Thu Nov 18 18:13:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1556762 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=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (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 4Hw7GY4xWTz9sPf for ; Fri, 19 Nov 2021 05:13:57 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id E9B2E80D32; Thu, 18 Nov 2021 18:13:55 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1BjxdMscOT4y; Thu, 18 Nov 2021 18:13:53 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 6432180C9B; Thu, 18 Nov 2021 18:13:52 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3133CC0031; Thu, 18 Nov 2021 18:13:52 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5AF56C002E for ; Thu, 18 Nov 2021 18:13:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 29FD9405D6 for ; Thu, 18 Nov 2021 18:13:49 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JtI0FJWyUWxv for ; Thu, 18 Nov 2021 18:13:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by smtp4.osuosl.org (Postfix) with ESMTPS id EE75140386 for ; Thu, 18 Nov 2021 18:13:45 +0000 (UTC) Received: (Authenticated sender: numans@ovn.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id ED535C000F; Thu, 18 Nov 2021 18:13:42 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Thu, 18 Nov 2021 13:13:31 -0500 Message-Id: <20211118181331.93028-1-numans@ovn.org> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn v2 2/2] northd: Use ct_(snat/dnat)_in_czone action for distributed routers. 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 Make of use of these new actions for the distributed routers for NAT. These new actions ensure that both sNAT and dNAT happens in the same zone. This approach solves a couple of problems: - The datapath flows generated for external traffic which requires dNAT (N -> S) or sNAT (S -> N) are completely HWOL'able. - Since there is only one zone, it would avoid multiple recirculations (improving the performance). If the packet needs to be both sNATted and dNATted (for hairpin traffic with source and destination on the same chassis), then sNAT is done in a separate zone. To detect this scenario, this patch adds a few extra logical flows. For each dnat_and_snat entry prior to this patch ovn-northd was generating 9 logical flows and with this patch it now generates 12 logical flows. Similar approach can be taken for gateway routers. Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1984953 Signed-off-by: Numan Siddique --- v1 -> v2 ------ * Rebased and resolved conflicts. include/ovn/logical-fields.h | 1 + lib/logical-fields.c | 4 + northd/northd.c | 147 +++++++-- northd/ovn-northd.8.xml | 201 +++++++++--- tests/ovn-northd.at | 575 +++++++++++++++++++---------------- tests/ovn.at | 2 +- tests/system-ovn.at | 64 ++-- 7 files changed, 607 insertions(+), 387 deletions(-) diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h index c9675f81c..2118f7933 100644 --- a/include/ovn/logical-fields.h +++ b/include/ovn/logical-fields.h @@ -70,6 +70,7 @@ enum mff_log_flags_bits { MLF_LOOKUP_FDB_BIT = 8, MLF_SKIP_SNAT_FOR_LB_BIT = 9, MLF_LOCALPORT_BIT = 10, + MLF_USE_SNAT_ZONE = 11, }; /* MFF_LOG_FLAGS_REG flag assignments */ diff --git a/lib/logical-fields.c b/lib/logical-fields.c index 7b3d431e0..352a48c89 100644 --- a/lib/logical-fields.c +++ b/lib/logical-fields.c @@ -125,6 +125,10 @@ ovn_init_symtab(struct shash *symtab) MLF_SKIP_SNAT_FOR_LB_BIT); expr_symtab_add_subfield(symtab, "flags.skip_snat_for_lb", NULL, flags_str); + snprintf(flags_str, sizeof flags_str, "flags[%d]", + MLF_USE_SNAT_ZONE); + expr_symtab_add_subfield(symtab, "flags.use_snat_zone", NULL, + flags_str); /* Connection tracking state. */ expr_symtab_add_field_scoped(symtab, "ct_mark", MFF_CT_MARK, NULL, false, diff --git a/northd/northd.c b/northd/northd.c index 0ff61deec..e4d051a94 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -159,11 +159,14 @@ enum ovn_stage { PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 18, "lr_in_arp_request") \ \ /* Logical router egress stages. */ \ - PIPELINE_STAGE(ROUTER, OUT, UNDNAT, 0, "lr_out_undnat") \ - PIPELINE_STAGE(ROUTER, OUT, POST_UNDNAT, 1, "lr_out_post_undnat") \ - PIPELINE_STAGE(ROUTER, OUT, SNAT, 2, "lr_out_snat") \ - PIPELINE_STAGE(ROUTER, OUT, EGR_LOOP, 3, "lr_out_egr_loop") \ - PIPELINE_STAGE(ROUTER, OUT, DELIVERY, 4, "lr_out_delivery") + PIPELINE_STAGE(ROUTER, OUT, CHECK_DNAT_LOCAL, 0, \ + "lr_out_chk_dnat_local") \ + PIPELINE_STAGE(ROUTER, OUT, UNDNAT, 1, "lr_out_undnat") \ + PIPELINE_STAGE(ROUTER, OUT, POST_UNDNAT, 2, "lr_out_post_undnat") \ + PIPELINE_STAGE(ROUTER, OUT, SNAT, 3, "lr_out_snat") \ + PIPELINE_STAGE(ROUTER, OUT, POST_SNAT, 4, "lr_out_post_snat") \ + PIPELINE_STAGE(ROUTER, OUT, EGR_LOOP, 5, "lr_out_egr_loop") \ + PIPELINE_STAGE(ROUTER, OUT, DELIVERY, 6, "lr_out_delivery") #define PIPELINE_STAGE(DP_TYPE, PIPELINE, STAGE, TABLE, NAME) \ S_##DP_TYPE##_##PIPELINE##_##STAGE \ @@ -210,6 +213,7 @@ enum ovn_stage { #define REGBIT_PKT_LARGER "reg9[1]" #define REGBIT_LOOKUP_NEIGHBOR_RESULT "reg9[2]" #define REGBIT_LOOKUP_NEIGHBOR_IP_RESULT "reg9[3]" +#define REGBIT_DST_NAT_IP_LOCAL "reg9[4]" /* Register to store the eth address associated to a router port for packets * received in S_ROUTER_IN_ADMISSION. @@ -9568,9 +9572,10 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, undnat_match_p, est_actions, &lb->nlb->header_); } else { - ovn_lflow_add_with_hint(lflows, od, S_ROUTER_OUT_UNDNAT, 120, - undnat_match_p, "ct_dnat;", - &lb->nlb->header_); + ovn_lflow_add_with_hint( + lflows, od, S_ROUTER_OUT_UNDNAT, 120, undnat_match_p, + od->is_gw_router ? "ct_dnat;" : "ct_dnat_in_czone;", + &lb->nlb->header_); } free(undnat_match_p); next: @@ -9865,7 +9870,7 @@ lrouter_nat_add_ext_ip_match(struct ovn_datapath *od, uint16_t priority; /* Priority of logical flows corresponding to exempted_ext_ips is - * +1 of the corresponding regulr NAT rule. + * +2 of the corresponding regular NAT rule. * For example, if we have following NAT rule and we associate * exempted external ips to it: * "ovn-nbctl lr-nat-add router dnat_and_snat 10.15.24.139 50.0.0.11" @@ -9873,17 +9878,17 @@ lrouter_nat_add_ext_ip_match(struct ovn_datapath *od, * And now we associate exempted external ip address set to it. * Now corresponding to above rule we will have following logical * flows: - * lr_out_snat...priority=162, match=(..ip4.dst == $exempt_range), + * lr_out_snat...priority=163, match=(..ip4.dst == $exempt_range), * action=(next;) * lr_out_snat...priority=161, match=(..), action=(ct_snat(....);) * */ if (is_src) { /* S_ROUTER_IN_DNAT uses priority 100 */ - priority = 100 + 1; + priority = 100 + 2; } else { /* S_ROUTER_OUT_SNAT uses priority (mask + 1 + 128 + 1) */ - priority = count_1bits(ntohl(mask)) + 2; + priority = count_1bits(ntohl(mask)) + 3; if (!od->is_gw_router) { priority += 128; @@ -12268,9 +12273,9 @@ build_lrouter_in_unsnat_flow(struct hmap *lflows, struct ovn_datapath *od, /* Traffic received on l3dgw_port is subject to NAT. */ ds_clear(match); ds_clear(actions); - ds_put_format(match, "ip && ip%s.dst == %s && inport == %s", - is_v6 ? "6" : "4", nat->external_ip, - od->l3dgw_ports[0]->json_key); + ds_put_format(match, "ip && ip%s.dst == %s && inport == %s && " + "flags.loopback == 0", is_v6 ? "6" : "4", + nat->external_ip, od->l3dgw_ports[0]->json_key); if (!distributed && od->n_l3dgw_ports) { /* Flows for NAT rules that are centralized are only * programmed on the gateway chassis. */ @@ -12282,12 +12287,31 @@ build_lrouter_in_unsnat_flow(struct hmap *lflows, struct ovn_datapath *od, ds_put_format(actions, "ip%s.dst=%s; next;", is_v6 ? "6" : "4", nat->logical_ip); } else { - ds_put_cstr(actions, "ct_snat;"); + ds_put_cstr(actions, "ct_snat_in_czone;"); } ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_UNSNAT, 100, ds_cstr(match), ds_cstr(actions), &nat->header_); + + if (!stateless) { + ds_clear(match); + ds_clear(actions); + ds_put_format(match, "ip && ip%s.dst == %s && inport == %s && " + "flags.loopback == 1 && flags.use_snat_zone == 1", + is_v6 ? "6" : "4", nat->external_ip, + od->l3dgw_ports[0]->json_key); + if (!distributed && od->n_l3dgw_ports) { + /* Flows for NAT rules that are centralized are only + * programmed on the gateway chassis. */ + ds_put_format(match, " && is_chassis_resident(%s)", + od->l3dgw_ports[0]->cr_port->json_key); + } + ds_put_cstr(actions, "ct_snat;"); + ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_UNSNAT, + 100, ds_cstr(match), ds_cstr(actions), + &nat->header_); + } } } @@ -12364,7 +12388,7 @@ build_lrouter_in_dnat_flow(struct hmap *lflows, struct ovn_datapath *od, ds_put_format(actions, "ip%s.dst=%s; next;", is_v6 ? "6" : "4", nat->logical_ip); } else { - ds_put_format(actions, "ct_dnat(%s", nat->logical_ip); + ds_put_format(actions, "ct_dnat_in_czone(%s", nat->logical_ip); if (nat->external_port_range[0]) { ds_put_format(actions, ",%s", nat->external_port_range); } @@ -12417,7 +12441,8 @@ build_lrouter_out_undnat_flow(struct hmap *lflows, struct ovn_datapath *od, ds_put_format(actions, "ip%s.src=%s; next;", is_v6 ? "6" : "4", nat->external_ip); } else { - ds_put_format(actions, "ct_dnat;"); + ds_put_format(actions, + od->is_gw_router ? "ct_dnat;" : "ct_dnat_in_czone;"); } ovn_lflow_add_with_hint(lflows, od, S_ROUTER_OUT_UNDNAT, 100, @@ -12425,6 +12450,36 @@ build_lrouter_out_undnat_flow(struct hmap *lflows, struct ovn_datapath *od, &nat->header_); } +static void +build_lrouter_out_is_dnat_local(struct hmap *lflows, struct ovn_datapath *od, + const struct nbrec_nat *nat, struct ds *match, + struct ds *actions, bool distributed, + bool is_v6) +{ + /* Note that this only applies for NAT on a distributed router. + */ + if (!od->n_l3dgw_ports) { + return; + } + + ds_clear(match); + ds_put_format(match, "ip && ip%s.dst == %s && ", + is_v6 ? "6" : "4", nat->external_ip); + if (distributed) { + ds_put_format(match, "is_chassis_resident(\"%s\")", nat->logical_port); + } else { + ds_put_format(match, "is_chassis_resident(%s)", + od->l3dgw_ports[0]->cr_port->json_key); + } + + ds_clear(actions); + ds_put_cstr(actions, REGBIT_DST_NAT_IP_LOCAL" = 1; next;"); + + ovn_lflow_add_with_hint(lflows, od, S_ROUTER_OUT_CHECK_DNAT_LOCAL, + 50, ds_cstr(match), ds_cstr(actions), + &nat->header_); +} + static void build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od, const struct nbrec_nat *nat, struct ds *match, @@ -12478,16 +12533,19 @@ build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od, ds_put_format(match, "ip && ip%s.src == %s && outport == %s", is_v6 ? "6" : "4", nat->logical_ip, od->l3dgw_ports[0]->json_key); - if (!distributed && od->n_l3dgw_ports) { - /* Flows for NAT rules that are centralized are only - * programmed on the gateway chassis. */ - priority += 128; - ds_put_format(match, " && is_chassis_resident(%s)", - od->l3dgw_ports[0]->cr_port->json_key); - } else if (distributed) { - priority += 128; - ds_put_format(match, " && is_chassis_resident(\"%s\")", - nat->logical_port); + if (od->n_l3dgw_ports) { + if (distributed) { + ovs_assert(nat->logical_port); + priority += 128; + ds_put_format(match, " && is_chassis_resident(\"%s\")", + nat->logical_port); + } else { + /* Flows for NAT rules that are centralized are only + * programmed on the gateway chassis. */ + priority += 128; + ds_put_format(match, " && is_chassis_resident(%s)", + od->l3dgw_ports[0]->cr_port->json_key); + } } ds_clear(actions); @@ -12505,7 +12563,7 @@ build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od, ds_put_format(actions, "ip%s.src=%s; next;", is_v6 ? "6" : "4", nat->external_ip); } else { - ds_put_format(actions, "ct_snat(%s", + ds_put_format(actions, "ct_snat_in_czone(%s", nat->external_ip); if (nat->external_port_range[0]) { ds_put_format(actions, ",%s", nat->external_port_range); @@ -12519,6 +12577,24 @@ build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od, ovn_lflow_add_with_hint(lflows, od, S_ROUTER_OUT_SNAT, priority, ds_cstr(match), ds_cstr(actions), &nat->header_); + + if (!stateless) { + ds_put_cstr(match, " && "REGBIT_DST_NAT_IP_LOCAL" == 1"); + ds_clear(actions); + if (distributed) { + ds_put_format(actions, "eth.src = "ETH_ADDR_FMT"; ", + ETH_ADDR_ARGS(mac)); + } + ds_put_format(actions, REGBIT_DST_NAT_IP_LOCAL" = 0; ct_snat(%s", + nat->external_ip); + if (nat->external_port_range[0]) { + ds_put_format(actions, ",%s", nat->external_port_range); + } + ds_put_format(actions, ");"); + ovn_lflow_add_with_hint(lflows, od, S_ROUTER_OUT_SNAT, + priority + 1, ds_cstr(match), + ds_cstr(actions), &nat->header_); + } } } @@ -12749,10 +12825,13 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, /* Packets are allowed by default. */ ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG, 0, "1", "next;"); ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 0, "1", "next;"); + ovn_lflow_add(lflows, od, S_ROUTER_OUT_CHECK_DNAT_LOCAL, 0, "1", + REGBIT_DST_NAT_IP_LOCAL" = 0; next;"); ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 0, "1", "next;"); ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 0, "1", "next;"); ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 0, "1", "next;"); ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 0, "1", "next;"); + ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_SNAT, 0, "1", "next;"); ovn_lflow_add(lflows, od, S_ROUTER_OUT_EGR_LOOP, 0, "1", "next;"); ovn_lflow_add(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 0, "1", "next;"); @@ -12765,8 +12844,7 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, * not committed, it would produce ongoing datapath flows with the ct.new * flag set. Some NICs are unable to offload these flows. */ - if ((od->is_gw_router || od->n_l3dgw_ports) && - (od->nbr->n_nat || od->has_lb_vip)) { + if (od->is_gw_router && (od->nbr->n_nat || od->has_lb_vip)) { ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 50, "ip", "flags.loopback = 1; ct_dnat;"); ovn_lflow_add(lflows, od, S_ROUTER_OUT_POST_UNDNAT, 50, @@ -12839,6 +12917,10 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, } } + /* S_ROUTER_OUT_DNAT_LOCAL */ + build_lrouter_out_is_dnat_local(lflows, od, nat, match, actions, + distributed, is_v6); + /* S_ROUTER_OUT_UNDNAT */ build_lrouter_out_undnat_flow(lflows, od, nat, match, actions, distributed, mac, is_v6); @@ -12912,7 +12994,8 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, "clone { ct_clear; " "inport = outport; outport = \"\"; " "eth.dst <-> eth.src; " - "flags = 0; flags.loopback = 1; "); + "flags = 0; flags.loopback = 1; " + "flags.use_snat_zone = "REGBIT_DST_NAT_IP_LOCAL"; "); for (int j = 0; j < MFF_N_LOG_REGS; j++) { ds_put_format(actions, "reg%d = 0; ", j); } diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index 21d83718c..fc9d51ea7 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -2879,23 +2879,65 @@ icmp6 {

For each configuration in the OVN Northbound database, that asks to change the source IP address of a packet from A to - B, a priority-100 flow matches ip && - ip4.dst == B && inport == GW or - ip && - ip6.dst == B && inport == GW - where GW is the logical router gateway port, with an - action ct_snat;. If the NAT rule is of type - dnat_and_snat and has stateless=true in the - options, then the action would be ip4/6.dst= - (B). + B, two priority-100 flows are added.

If the NAT rule cannot be handled in a distributed manner, then - the priority-100 flow above is only programmed on the + the below priority-100 flows are only programmed on the gateway chassis.

+
    +
  • +

    + The first flow matches ip && + ip4.dst == B && inport == GW + && flags.loopback == 0 or + ip && + ip6.dst == B && inport == GW + && flags.loopback == 0 + where GW is the logical router gateway port, with an + action ct_snat_in_czone; to unSNAT in the common + zone. If the NAT rule is of type dnat_and_snat and has + stateless=true in the options, then the action + would be ip4/6.dst=(B). +

    + +

    + If the NAT entry is of type snat, then there is an + additional match is_chassis_resident(cr-GW) + where cr-GW is the chassis resident port of + GW. +

    +
  • + +
  • +

    + The second flow matches ip && + ip4.dst == B && inport == GW + && flags.loopback == 1 && + flags.use_snat_zone == 1 or + ip && + ip6.dst == B && inport == GW + && flags.loopback == 0 && + flags.use_snat_zone == 1 + where GW is the logical router gateway port, with an + action ct_snat; to unSNAT in the snat zone. If the + NAT rule is of type dnat_and_snat and has + stateless=true in the options, then the action + would be ip4/6.dst=(B). +

    + +

    + If the NAT entry is of type snat, then there is an + additional match is_chassis_resident(cr-GW) + where cr-GW is the chassis resident port of + GW. +

    +
  • +
+

A priority-0 logical flow with match 1 has actions next;. @@ -4031,7 +4073,43 @@ nd_ns { -

Egress Table 0: UNDNAT

+

Egress Table 0: Check DNAT local

+ +

+ This table checks if the packet needs to be DNATed in the router ingress + table lr_out_dnat after it is SNATed and looped back + to the ingress pipeline. This check is done only for routers configured + with distributed gateway ports and NAT entries. This check is done + so that SNAT and DNAT is done in different zones instead of a common + zone. +

+ +
    +
  • +

    + For each NAT rule in the OVN Northbound database on a + distributed router, a priority-50 logical flow with match + ip4.dst == E && + is_chassis_resident(P), where E is the + external IP address specified in the NAT rule, GW + is the logical router distributed gateway port. For dnat_and_snat + NAT rule, P is the logical port specified in the NAT rule. + If column of + table is NOT set, then + P is the chassisredirect port of + GW with the actions: + REGBIT_DST_NAT_IP_LOCAL = 1; next; +

    +
  • + +
  • + A priority-0 logical flow with match 1 has actions + REGBIT_DST_NAT_IP_LOCAL = 0; next;. +
  • +
+ +

Egress Table 1: UNDNAT

This is for already established connections' reverse traffic. @@ -4040,6 +4118,23 @@ nd_ns { is unDNATed here.

+
    +
  • + A priority-0 logical flow with match 1 has actions + next;. +
  • +
+ +

Egress Table 1: UNDNAT on Gateway Routers

+ +
    +
  • + For all IP packets, a priority-50 flow with an action + flags.loopback = 1; ct_dnat;. +
  • +
+ +

Egress Table 1: UNDNAT on Distributed Routers

  • @@ -4050,9 +4145,9 @@ nd_ns { gateway chassis that matches ip && ip4.src == B && outport == GW, where GW is the logical - router gateway port with an action ct_dnat;. If the - backend IPv4 address B is also configured with L4 port - PORT of protocol P, then the + router gateway port with an action ct_dnat_in_czone;. + If the backend IPv4 address B is also configured with + L4 port PORT of protocol P, then the match also includes P.src == PORT. These flows are not added for load balancers with IPv6 VIPs.

    @@ -4072,7 +4167,7 @@ nd_ns { matches ip && ip4.src == B && outport == GW, where GW is the logical router gateway port, with an action - ct_dnat;. If the NAT rule is of type + ct_dnat_in_czone;. If the NAT rule is of type dnat_and_snat and has stateless=true in the options, then the action would be ip4/6.src= (B). @@ -4081,7 +4176,7 @@ nd_ns {

    If the NAT rule cannot be handled in a distributed manner, then the priority-100 flow above is only programmed on the - gateway chassis. + gateway chassis with the action ct_dnat_in_czone.

    @@ -4094,26 +4189,17 @@ nd_ns {

  • -
  • - For all IP packets, a priority-50 flow with an action - flags.loopback = 1; ct_dnat;. -
  • - -
  • - A priority-0 logical flow with match 1 has actions - next;. -
-

Egress Table 1: Post UNDNAT

+

Egress Table 2: Post UNDNAT

  • A priority-50 logical flow is added that commits any untracked flows - from the previous table lr_out_undnat. This flow - matches on ct.new && ip with action - ct_commit { } ; next; . + from the previous table lr_out_undnat for Gateway + routers. This flow matches on ct.new && ip + with action ct_commit { } ; next; .
  • @@ -4124,7 +4210,7 @@ nd_ns {

-

Egress Table 2: SNAT

+

Egress Table 3: SNAT

Packets that are configured to be SNATed get their source IP address @@ -4140,7 +4226,7 @@ nd_ns { -

Egress Table 2: SNAT on Gateway Routers

+

Egress Table 3: SNAT on Gateway Routers

  • @@ -4239,7 +4325,7 @@ nd_ns {
-

Egress Table 2: SNAT on Distributed Routers

+

Egress Table 3: SNAT on Distributed Routers

  • @@ -4247,28 +4333,46 @@ nd_ns { For each configuration in the OVN Northbound database, that asks to change the source IP address of a packet from an IP address of A or to change the source IP address of a packet that - belongs to network A to B, a flow matches - ip && ip4.src == A && - outport == GW, where GW is the - logical router gateway port, with an action - ct_snat(B);. The priority of the flow - is calculated based on the mask of A, with matches - having larger masks getting higher priorities. If the NAT rule - is of type dnat_and_snat and has stateless=true - in the options, then the action would be ip4/6.src= - (B). + belongs to network A to B, two flows are + added. The priority of these flows are calculated based on the + mask of A, with matches having larger masks getting + higher priorities.

    If the NAT rule cannot be handled in a distributed manner, then - the flow above is only programmed on the - gateway chassis increasing flow priority by 128 in - order to be run first + the below flows are only programmed on the gateway chassis increasing + flow priority by 128 in order to be run first.

    +
      +
    • + The first flow is added with the match + ip && ip4.src == A && + outport == GW, where GW is the + logical router gateway port, with an action + ct_snat_in_czone(B); to SNATed in the + common zone. If the NAT rule is of type dnat_and_snat and has + stateless=true in the options, then the action + would be ip4/6.src=(B). +
    • + +
    • + The second flow is added with the match + ip && ip4.src == A && + outport == GW && + REGBIT_DST_NAT_IP_LOCAL == 0, where GW is the + logical router gateway port, with an action + ct_snat(B); to SNAT in the snat zone. + If the NAT rule is of type dnat_and_snat and has + stateless=true in the options, then the action would + be ip4/6.src=(B). +
    • +
    +

    If the NAT rule can be handled in a distributed manner, then - there is an additional action + there is an additional action (for both the flows) eth.src = EA;, where EA is the ethernet address associated with the IP address A in the NAT rule. This allows upstream MAC @@ -4299,7 +4403,7 @@ nd_ns {

-

Egress Table 3: Egress Loopback

+

Egress Table 4: Egress Loopback

For distributed logical routers where one of the logical router @@ -4344,6 +4448,7 @@ clone { outport = ""; flags = 0; flags.loopback = 1; + flags.use_snat_zone = REGBIT_DST_NAT_IP_LOCAL; reg0 = 0; reg1 = 0; ... @@ -4368,7 +4473,7 @@ clone { -

Egress Table 4: Delivery

+

Egress Table 5: Delivery

Packets that reach this table are ready for delivery. It contains: diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 85b47a18f..70ec5e2e3 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -877,25 +877,25 @@ check_flow_match_sets() { echo echo "IPv4: stateful" ovn-nbctl --wait=sb lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11 -check_flow_match_sets 2 2 3 0 0 0 0 +check_flow_match_sets 3 4 2 0 0 0 0 ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 echo echo "IPv4: stateless" ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11 -check_flow_match_sets 2 0 1 2 2 0 0 +check_flow_match_sets 2 0 0 2 2 0 0 ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 echo echo "IPv6: stateful" ovn-nbctl --wait=sb lr-nat-add R1 dnat_and_snat fd01::1 fd11::2 -check_flow_match_sets 2 2 3 0 0 0 0 +check_flow_match_sets 3 4 2 0 0 0 0 ovn-nbctl lr-nat-del R1 dnat_and_snat fd01::1 echo echo "IPv6: stateless" ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat fd01::1 fd11::2 -check_flow_match_sets 2 0 1 0 0 2 2 +check_flow_match_sets 2 0 0 0 0 2 2 AT_CLEANUP ]) @@ -924,9 +924,9 @@ echo "CR-LRP UUID is: " $uuid ovn-nbctl --portrange lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11 1-3000 AT_CAPTURE_FILE([sbflows]) -OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows && test 2 = `grep -c lr_in_unsnat sbflows`]) +OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows && test 3 = `grep -c lr_in_unsnat sbflows`]) AT_CHECK([grep -c 'ct_snat.*3000' sbflows && grep -c 'ct_dnat.*3000' sbflows], - [0], [1 + [0], [2 1 ]) @@ -934,9 +934,9 @@ ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 ovn-nbctl --wait=sb --portrange lr-nat-add R1 snat 172.16.1.1 50.0.0.11 1-3000 AT_CAPTURE_FILE([sbflows2]) -OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows2 && test 2 = `grep -c lr_in_unsnat sbflows`]) +OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows2 && test 3 = `grep -c lr_in_unsnat sbflows`]) AT_CHECK([grep -c 'ct_snat.*3000' sbflows2 && grep -c 'ct_dnat.*3000' sbflows2], - [1], [1 + [1], [2 0 ]) @@ -944,7 +944,7 @@ ovn-nbctl lr-nat-del R1 snat 172.16.1.1 ovn-nbctl --wait=sb --portrange --stateless lr-nat-add R1 dnat_and_snat 172.16.1.2 50.0.0.12 1-3000 AT_CAPTURE_FILE([sbflows3]) -OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows3 && test 3 = `grep -c lr_in_unsnat sbflows3`]) +OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows3 && test 4 = `grep -c lr_in_unsnat sbflows3`]) AT_CHECK([grep 'ct_[s]dnat.*172\.16\.1\.2.*3000' sbflows3], [1]) ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 @@ -1008,17 +1008,20 @@ AT_CAPTURE_FILE([drflows]) ovn-sbctl dump-flows CR > crflows AT_CAPTURE_FILE([crflows]) -AT_CHECK([ - grep -c lr_out_snat drflows - grep -c lr_out_snat crflows - grep lr_out_snat drflows | grep "ip4.src == 50.0.0.11" | grep -c "ip4.dst == $allowed_range" - grep lr_out_snat crflows | grep "ip4.src == 50.0.0.11" | grep -c "ip4.dst == $allowed_range"], [0], [dnl -3 -3 -1 -1 +AT_CHECK([grep -e "lr_out_snat" drflows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range), action=(ct_snat_in_czone(172.16.1.1);) + table=??(lr_out_snat ), priority=162 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.16.1.1);) +]) + +AT_CHECK([grep -e "lr_out_snat" crflows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range), action=(ct_snat(172.16.1.1);) ]) + # SNAT with DISALLOWED_IPs check ovn-nbctl lr-nat-del DR snat 50.0.0.11 check ovn-nbctl lr-nat-del CR snat 50.0.0.11 @@ -1036,19 +1039,19 @@ AT_CAPTURE_FILE([drflows2]) ovn-sbctl dump-flows CR > crflows2 AT_CAPTURE_FILE([crflows2]) -AT_CHECK([ - grep -c lr_out_snat drflows2 - grep -c lr_out_snat crflows2 - grep lr_out_snat drflows2 | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $disallowed_range" | grep -c "priority=162" - grep lr_out_snat drflows2 | grep "ip4.src == 50.0.0.11" | grep -c "priority=161" - grep lr_out_snat crflows2 | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $disallowed_range" | grep -c "priority=34" - grep lr_out_snat crflows2 | grep "ip4.src == 50.0.0.11" | grep -c "priority=33"], [0], [dnl -4 -4 -1 -1 -1 -1 +AT_CHECK([grep -e "lr_out_snat" drflows2 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1")), action=(ct_snat_in_czone(172.16.1.1);) + table=??(lr_out_snat ), priority=162 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.16.1.1);) + table=??(lr_out_snat ), priority=163 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $disallowed_range), action=(next;) +]) + +AT_CHECK([grep -e "lr_out_snat" crflows2 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11), action=(ct_snat(172.16.1.1);) + table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) ]) # Stateful FIP with ALLOWED_IPs @@ -1059,25 +1062,24 @@ check ovn-nbctl lr-nat-add DR dnat_and_snat 172.16.1.2 50.0.0.11 check ovn-nbctl lr-nat-add CR dnat_and_snat 172.16.1.2 50.0.0.11 check ovn-nbctl lr-nat-update-ext-ip DR dnat_and_snat 172.16.1.2 allowed_range -check ovn-nbctl lr-nat-update-ext-ip CR dnat_and_snat 172.16.1.2 allowed_range +check ovn-nbctl --wait=sb lr-nat-update-ext-ip CR dnat_and_snat 172.16.1.2 allowed_range -ovn-nbctl show DR -ovn-sbctl dump-flows DR -ovn-nbctl show CR -ovn-sbctl dump-flows CR - -OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows DR | grep lr_out_snat | \ -wc -l`]) -OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows CR | grep lr_out_snat | \ -wc -l`]) +ovn-sbctl dump-flows DR > drflows3 +AT_CAPTURE_FILE([drflows2]) +ovn-sbctl dump-flows CR > crflows3 +AT_CAPTURE_FILE([crflows2]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $allowed_range" | wc -l], [0], [1 +AT_CHECK([grep -e "lr_out_snat" drflows3 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range), action=(ct_snat_in_czone(172.16.1.2);) + table=??(lr_out_snat ), priority=162 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.16.1.2);) ]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $allowed_range" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1 + +AT_CHECK([grep -e "lr_out_snat" crflows3 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range), action=(ct_snat(172.16.1.2);) ]) # Stateful FIP with DISALLOWED_IPs @@ -1088,26 +1090,26 @@ ovn-nbctl lr-nat-add DR dnat_and_snat 172.16.1.2 50.0.0.11 ovn-nbctl lr-nat-add CR dnat_and_snat 172.16.1.2 50.0.0.11 ovn-nbctl --is-exempted lr-nat-update-ext-ip DR dnat_and_snat 172.16.1.2 disallowed_range -ovn-nbctl --is-exempted lr-nat-update-ext-ip CR dnat_and_snat 172.16.1.2 disallowed_range +check ovn-nbctl --wait=sb --is-exempted lr-nat-update-ext-ip CR dnat_and_snat 172.16.1.2 disallowed_range -ovn-nbctl show DR -ovn-sbctl dump-flows DR -ovn-nbctl show CR -ovn-sbctl dump-flows CR - -OVS_WAIT_UNTIL([test 4 = `ovn-sbctl dump-flows DR | grep lr_out_snat | \ -wc -l`]) -OVS_WAIT_UNTIL([test 4 = `ovn-sbctl dump-flows CR | grep lr_out_snat | \ -wc -l`]) +ovn-sbctl dump-flows DR > drflows4 +AT_CAPTURE_FILE([drflows2]) +ovn-sbctl dump-flows CR > crflows4 +AT_CAPTURE_FILE([crflows2]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $disallowed_range" | grep "priority=162" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $disallowed_range" | grep "priority=101" | wc -l], [0], [1 +AT_CHECK([grep -e "lr_out_snat" drflows4 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1")), action=(ct_snat_in_czone(172.16.1.2);) + table=??(lr_out_snat ), priority=162 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.16.1.2);) + table=??(lr_out_snat ), priority=163 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $disallowed_range), action=(next;) ]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $disallowed_range" | grep "priority=34" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $disallowed_range" | grep "priority=101" | wc -l], [0], [1 +AT_CHECK([grep -e "lr_out_snat" crflows4 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11), action=(ct_snat(172.16.1.2);) + table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) ]) # Stateless FIP with DISALLOWED_IPs @@ -1120,24 +1122,21 @@ ovn-nbctl --stateless lr-nat-add CR dnat_and_snat 172.16.1.2 50.0.0.11 ovn-nbctl lr-nat-update-ext-ip DR dnat_and_snat 172.16.1.2 allowed_range ovn-nbctl lr-nat-update-ext-ip CR dnat_and_snat 172.16.1.2 allowed_range -ovn-nbctl show DR -ovn-sbctl dump-flows DR - -ovn-nbctl show CR -ovn-sbctl dump-flows CR - -OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows DR | grep lr_out_snat | \ -wc -l`]) -OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows CR | grep lr_out_snat | \ -wc -l`]) +ovn-sbctl dump-flows DR > drflows5 +AT_CAPTURE_FILE([drflows2]) +ovn-sbctl dump-flows CR > crflows5 +AT_CAPTURE_FILE([crflows2]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $allowed_range" | wc -l], [0], [1 +AT_CHECK([grep -e "lr_out_snat" drflows5 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $allowed_range), action=(ip4.src=172.16.1.2; next;) ]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $allowed_range" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1 + +AT_CHECK([grep -e "lr_out_snat" crflows5 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range), action=(ip4.src=172.16.1.2; next;) ]) # Stateful FIP with DISALLOWED_IPs @@ -1150,23 +1149,25 @@ ovn-nbctl --stateless lr-nat-add CR dnat_and_snat 172.16.1.2 50.0.0.11 ovn-nbctl --is-exempted lr-nat-update-ext-ip DR dnat_and_snat 172.16.1.2 disallowed_range ovn-nbctl --is-exempted lr-nat-update-ext-ip CR dnat_and_snat 172.16.1.2 disallowed_range -ovn-nbctl show DR -ovn-sbctl dump-flows DR -ovn-nbctl show CR -ovn-sbctl dump-flows CR +ovn-nbctl --wait=sb sync -OVS_WAIT_UNTIL([test 4 = `ovn-sbctl dump-flows DR | grep lr_out_snat | \ -wc -l`]) -OVS_WAIT_UNTIL([test 4 = `ovn-sbctl dump-flows CR | grep lr_out_snat | \ -wc -l`]) +ovn-sbctl dump-flows DR > drflows6 +AT_CAPTURE_FILE([drflows2]) +ovn-sbctl dump-flows CR > crflows6 +AT_CAPTURE_FILE([crflows2]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $disallowed_range" | grep "priority=162" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows DR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $disallowed_range" | grep "priority=101" | wc -l], [0], [1 +AT_CHECK([grep -e "lr_out_snat" drflows6 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=161 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1")), action=(ip4.src=172.16.1.2; next;) + table=??(lr_out_snat ), priority=163 , match=(ip && ip4.src == 50.0.0.11 && outport == "DR-S1" && is_chassis_resident("cr-DR-S1") && ip4.dst == $disallowed_range), action=(next;) ]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $disallowed_range" | grep "priority=34" | wc -l], [0], [1 -]) -AT_CHECK([ovn-sbctl dump-flows CR | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $disallowed_range" | grep "priority=101" | wc -l], [0], [1 + +AT_CHECK([grep -e "lr_out_snat" crflows6 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) + table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11), action=(ip4.src=172.16.1.2; next;) + table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) ]) AT_CLEANUP @@ -3475,14 +3476,14 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(ct_lb(backends=10.0.0.40:8080);) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="20.0.0.4 aef0::4" @@ -3511,21 +3512,21 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip4), action=(ct_snat(20.0.0.4);) - table=2 (lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip6), action=(ct_snat(aef0::4);) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip4), action=(ct_snat(20.0.0.4);) + table=? (lr_out_snat ), priority=100 , match=(flags.force_snat_for_lb == 1 && ip6), action=(ct_snat(aef0::4);) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="router_ip" @@ -3557,22 +3558,22 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) check ovn-nbctl --wait=sb remove logical_router lr0 options chassis @@ -3584,9 +3585,9 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl table=4 (lr_in_unsnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) check ovn-nbctl set logical_router lr0 options:chassis=ch1 @@ -3617,23 +3618,23 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-sw1"), action=(ct_snat(bef0::1);) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.100);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw1"), action=(ct_snat(20.0.0.1);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-sw1"), action=(ct_snat(bef0::1);) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) check ovn-nbctl --wait=sb lb-add lb2 10.0.0.20:80 10.0.0.40:8080 @@ -3661,18 +3662,18 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | grep skip_snat_for_lb | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80), action=(flags.skip_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | grep skip_snat_for_lb | sort], [0], [dnl - table=2 (lr_out_snat ), priority=120 , match=(flags.skip_snat_for_lb == 1 && ip), action=(next;) +AT_CHECK([grep "lr_out_snat" lr0flows | grep skip_snat_for_lb | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=120 , match=(flags.skip_snat_for_lb == 1 && ip), action=(next;) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) AT_CLEANUP @@ -4176,6 +4177,8 @@ check ovn-nbctl lsp-set-options lrp1-attachment router-port=lrp1 check ovn-nbctl lr-nat-add lr0 dnat 42.42.42.42 192.168.0.2 check ovn-nbctl --wait=sb sync +ovn-trace --minimal 'inport == "sw1-port1" && eth.src == 50:54:00:00:00:03 && eth.dst == 00:00:00:00:ff:02 && ip4.dst == 42.42.42.42 && ip4.src == 11.0.0.2 && ip.ttl == 64' + AT_CHECK([ovn-trace --minimal 'inport == "sw1-port1" && eth.src == 50:54:00:00:00:03 && eth.dst == 00:00:00:00:ff:02 && ip4.dst == 42.42.42.42 && ip4.src == 11.0.0.2 && ip.ttl == 64' | grep "output(\"sw0-port1\")"], [0], [ignore]) dnl If we remove the DNAT entry we will be unable to trace to the DNAT address @@ -4761,17 +4764,17 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) # Create few dnat_and_snat entries @@ -4797,17 +4800,21 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) +]) + +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) ovn-sbctl chassis-add gw1 geneve 127.0.0.1 @@ -4828,9 +4835,12 @@ AT_CAPTURE_FILE([lr0flows]) AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl table=4 (lr_in_unsnat ), priority=0 , match=(1), action=(next;) - table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) - table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) - table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.30 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && inport == "lr0-public" && flags.loopback == 0 && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && inport == "lr0-public" && flags.loopback == 1 && flags.use_snat_zone == 1 && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && flags.loopback == 0 && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && flags.loopback == 1 && flags.use_snat_zone == 1 && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.30 && inport == "lr0-public" && flags.loopback == 0 && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.30 && inport == "lr0-public" && flags.loopback == 1 && flags.use_snat_zone == 1 && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) ]) AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl @@ -4839,26 +4849,34 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) - table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat(10.0.0.3);) + table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);) +]) + +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) + table=? (lr_out_chk_dnat_local), priority=50 , match=(ip && ip4.dst == 172.168.0.10 && is_chassis_resident("cr-lr0-public")), action=(reg9[[4]] = 1; next;) + table=? (lr_out_chk_dnat_local), priority=50 , match=(ip && ip4.dst == 172.168.0.20 && is_chassis_resident("cr-lr0-public")), action=(reg9[[4]] = 1; next;) + table=? (lr_out_chk_dnat_local), priority=50 , match=(ip && ip4.dst == 172.168.0.30 && is_chassis_resident("cr-lr0-public")), action=(reg9[[4]] = 1; next;) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=100 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=100 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=2 (lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat(172.168.0.30);) - table=2 (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat(172.168.0.20);) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=? (lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone(172.168.0.10);) + table=? (lr_out_snat ), priority=154 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone(172.168.0.30);) + table=? (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone(172.168.0.20);) + table=? (lr_out_snat ), priority=162 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.30);) + table=? (lr_out_snat ), priority=162 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.20);) ]) # Associate load balancer to lr0 @@ -4879,9 +4897,12 @@ AT_CAPTURE_FILE([lr0flows]) AT_CHECK([grep "lr_in_unsnat" lr0flows | sort], [0], [dnl table=4 (lr_in_unsnat ), priority=0 , match=(1), action=(next;) - table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) - table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) - table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.30 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && inport == "lr0-public" && flags.loopback == 0 && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.10 && inport == "lr0-public" && flags.loopback == 1 && flags.use_snat_zone == 1 && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && flags.loopback == 0 && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && flags.loopback == 1 && flags.use_snat_zone == 1 && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.30 && inport == "lr0-public" && flags.loopback == 0 && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone;) + table=4 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.30 && inport == "lr0-public" && flags.loopback == 1 && flags.use_snat_zone == 1 && is_chassis_resident("cr-lr0-public")), action=(ct_snat;) ]) AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl @@ -4894,7 +4915,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) - table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat(10.0.0.3);) + table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);) table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_label.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.80,10.0.0.81);) table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) @@ -4905,27 +4926,35 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=100 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;) - table=0 (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.4 && tcp.src == 8080)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;) - table=0 (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.50 && tcp.src == 82) || (ip4.src == 10.0.0.60 && tcp.src == 82)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;) - table=0 (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.50 && udp.src == 6062) || (ip4.src == 10.0.0.60 && udp.src == 6062)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;) - table=0 (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.80) || (ip4.src == 10.0.0.81)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) + table=? (lr_out_chk_dnat_local), priority=50 , match=(ip && ip4.dst == 172.168.0.10 && is_chassis_resident("cr-lr0-public")), action=(reg9[[4]] = 1; next;) + table=? (lr_out_chk_dnat_local), priority=50 , match=(ip && ip4.dst == 172.168.0.20 && is_chassis_resident("cr-lr0-public")), action=(reg9[[4]] = 1; next;) + table=? (lr_out_chk_dnat_local), priority=50 , match=(ip && ip4.dst == 172.168.0.30 && is_chassis_resident("cr-lr0-public")), action=(reg9[[4]] = 1; next;) +]) + +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=100 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone;) + table=? (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.4 && tcp.src == 8080)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone;) + table=? (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.50 && tcp.src == 82) || (ip4.src == 10.0.0.60 && tcp.src == 82)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone;) + table=? (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.50 && udp.src == 6062) || (ip4.src == 10.0.0.60 && udp.src == 6062)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone;) + table=? (lr_out_undnat ), priority=120 , match=(ip4 && ((ip4.src == 10.0.0.80) || (ip4.src == 10.0.0.81)) && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=2 (lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat(172.168.0.30);) - table=2 (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat(172.168.0.20);) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=? (lr_out_snat ), priority=153 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone(172.168.0.10);) + table=? (lr_out_snat ), priority=154 , match=(ip && ip4.src == 10.0.0.0/24 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone(172.168.0.30);) + table=? (lr_out_snat ), priority=161 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_snat_in_czone(172.168.0.20);) + table=? (lr_out_snat ), priority=162 , match=(ip && ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.30);) + table=? (lr_out_snat ), priority=162 , match=(ip && ip4.src == 10.0.0.3 && outport == "lr0-public" && is_chassis_resident("cr-lr0-public") && reg9[[4]] == 1), action=(reg9[[4]] = 0; ct_snat(172.168.0.20);) ]) # Make the logical router as Gateway router @@ -4965,22 +4994,26 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=2 (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +]) + +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) ]) # Set lb force snat logical router. @@ -5020,24 +5053,28 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) +]) + +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=2 (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) ]) # Add a LB VIP same as router ip. @@ -5081,24 +5118,28 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=2 (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +]) + +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) ]) # Add IPv6 router port and LB. @@ -5155,26 +5196,30 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000), action=(flags.force_snat_for_lb = 1; ct_lb(backends=[[aef0::2]]:80,[[aef0::3]]:80);) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) +]) + +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-public"), action=(ct_snat(def0::10);) - table=2 (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-sw0"), action=(ct_snat(aef0::1);) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) - table=2 (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) - table=2 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-public"), action=(ct_snat(def0::10);) + table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-sw0"), action=(ct_snat(aef0::1);) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) ]) check ovn-nbctl lrp-del lr0-sw0 @@ -5209,19 +5254,23 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) ]) -AT_CHECK([grep "lr_out_undnat" lr0flows | sort], [0], [dnl - table=0 (lr_out_undnat ), priority=0 , match=(1), action=(next;) - table=0 (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) +AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_chk_dnat_local), priority=0 , match=(1), action=(reg9[[4]] = 0; next;) +]) + +AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_undnat ), priority=50 , match=(ip), action=(flags.loopback = 1; ct_dnat;) ]) -AT_CHECK([grep "lr_out_post_undnat" lr0flows | sort], [0], [dnl - table=1 (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) - table=1 (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) +AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_post_undnat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_post_undnat ), priority=50 , match=(ip && ct.new), action=(ct_commit { } ; next; ) ]) -AT_CHECK([grep "lr_out_snat" lr0flows | sort], [0], [dnl - table=2 (lr_out_snat ), priority=0 , match=(1), action=(next;) - table=2 (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) +AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl + table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) + table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) ]) AT_CLEANUP diff --git a/tests/ovn.at b/tests/ovn.at index 0d606b42f..ae5744407 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -21604,7 +21604,7 @@ AT_CAPTURE_FILE([sbflows]) AT_CHECK([for regex in ct_snat ct_dnat ip4.dst= ip4.src=; do grep -c "$regex" sbflows; done], [0], [0 -1 +0 2 2 ]) diff --git a/tests/system-ovn.at b/tests/system-ovn.at index c9f5771c9..7f6cb32dc 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -2224,7 +2224,7 @@ ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:80,192.16 ovn-nbctl list load_balancer ovn-sbctl dump-flows R2 -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=42 | \ +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=43 | \ grep 'nat(src=20.0.0.2)']) dnl Test load-balancing that includes L4 ports in NAT. @@ -2262,7 +2262,7 @@ ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:80,192.16 ovn-nbctl list load_balancer ovn-sbctl dump-flows R2 -OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=42 | \ +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=43 | \ grep 'nat(src=20.0.0.2)']) rm -f wget*.log @@ -3711,17 +3711,24 @@ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl icmpv6,orig=(src=fd20::2,dst=fd20::3,id=,type=128,code=0),reply=(src=fd11::2,dst=fd20::2,id=,type=129,code=0),zone= ]) +AT_CHECK([ovs-appctl dpctl/flush-conntrack]) + # South-North SNAT: 'foo2' pings 'alice1'. But 'alice1' receives traffic -# from 172.16.1.4 +# from fd20::4 NS_CHECK_EXEC([foo2], [ping6 -q -c 3 -i 0.3 -w 2 fd20::2 | FORMAT_PING], \ [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that SNAT indeed happened via 'dump-conntrack' command. +ovs-appctl dpctl/dump-conntrack | grep icmpv6 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd11::3) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmpv6,orig=(src=fd11::3,dst=fd20::2,id=,type=128,code=0),reply=(src=fd20::2,dst=fd11::3,id=,type=129,code=0),zone= +]) + +# We verify that SNAT indeed happened via 'dump-conntrack' command. +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd20::4) | \ +sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl +icmpv6,orig=(src=fd11::3,dst=fd20::2,id=,type=128,code=0),reply=(src=fd20::2,dst=fd20::4,id=,type=129,code=0),zone= ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3861,11 +3868,9 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \ 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that the connection is tracked but not NATted. This is due to the -# unDNAT table in the egress router pipeline -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ +# We verify that the connection is not tracked. +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmp,orig=(src=192.168.1.2,dst=192.168.2.2,id=,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.2,id=,type=0,code=0),zone= ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3875,11 +3880,9 @@ NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \ 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that the connection is tracked but not NATted. This is due to the -# unDNAT table in the egress router pipeline -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ +# We verify that the connection is not tracked. +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmp,orig=(src=192.168.1.3,dst=192.168.2.2,id=,type=8,code=0),reply=(src=192.168.2.2,dst=192.168.1.3,id=,type=0,code=0),zone= ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3889,14 +3892,13 @@ NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.3 | FORMAT_PING], \ 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that the connection is tracked but not NATted. This is due to the -# unDNAT table in the egress router pipeline -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \ +# We verify that the connection is not tracked. +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(192.168.2.2) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmp,orig=(src=192.168.2.2,dst=192.168.1.3,id=,type=8,code=0),reply=(src=192.168.1.3,dst=192.168.2.2,id=,type=0,code=0),zone= ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) + # East-West NAT: 'foo1' pings 'bar1' using 172.16.1.4. NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \ [0], [dnl @@ -3905,11 +3907,10 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \ # Check conntrack entries. First SNAT of 'foo1' address happens. # Then DNAT of 'bar1' address happens (listed first below). -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.4) | \ +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(172.16.1.4) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl icmp,orig=(src=172.16.1.3,dst=172.16.1.4,id=,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.3,id=,type=0,code=0),zone= icmp,orig=(src=192.168.1.2,dst=172.16.1.4,id=,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.3,id=,type=0,code=0),zone= -icmp,orig=(src=192.168.1.2,dst=172.16.1.4,id=,type=8,code=0),reply=(src=172.16.1.4,dst=192.168.1.2,id=,type=0,code=0),zone= ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) @@ -3922,7 +3923,7 @@ NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \ # Check conntrack entries. First SNAT of 'foo2' address happens. # Then DNAT of 'bar1' address happens (listed first below). -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.1) | \ +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep icmp | FORMAT_CT(172.16.1.1) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl icmp,orig=(src=172.16.1.1,dst=172.16.1.4,id=,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.1,id=,type=0,code=0),zone= icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.1,id=,type=0,code=0),zone= @@ -4055,13 +4056,6 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 fd12::2 | FORMAT_PING], \ 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that the connection is tracked but not NATted. This is due to the -# unDNAT table in the egress router pipeline -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd12::2) | \ -sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmpv6,orig=(src=fd11::2,dst=fd12::2,id=,type=128,code=0),reply=(src=fd12::2,dst=fd11::2,id=,type=129,code=0),zone= -]) - AT_CHECK([ovs-appctl dpctl/flush-conntrack]) # East-West No NAT: 'foo2' pings 'bar1' using fd12::2. NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 fd12::2 | FORMAT_PING], \ @@ -4069,13 +4063,6 @@ NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 fd12::2 | FORMAT_PING], \ 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that the connection is tracked but not NATted. This is due to the -# unDNAT table in the egress router pipeline -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd12::2) | \ -sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmpv6,orig=(src=fd11::3,dst=fd12::2,id=,type=128,code=0),reply=(src=fd12::2,dst=fd11::3,id=,type=129,code=0),zone= -]) - AT_CHECK([ovs-appctl dpctl/flush-conntrack]) # East-West No NAT: 'bar1' pings 'foo2' using fd11::3. NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 fd11::3 | FORMAT_PING], \ @@ -4083,13 +4070,6 @@ NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 fd11::3 | FORMAT_PING], \ 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) -# We verify that the connection is tracked but not NATted. This is due to the -# unDNAT table in the egress router pipeline -AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd12::2) | \ -sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmpv6,orig=(src=fd12::2,dst=fd11::3,id=,type=128,code=0),reply=(src=fd11::3,dst=fd12::2,id=,type=129,code=0),zone= -]) - AT_CHECK([ovs-appctl dpctl/flush-conntrack]) # East-West NAT: 'foo1' pings 'bar1' using fd20::4. NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 fd20::4 | FORMAT_PING], \ @@ -4101,7 +4081,6 @@ NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 fd20::4 | FORMAT_PING], \ # Then DNAT of 'bar1' address happens (listed first below). AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd20::4) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl -icmpv6,orig=(src=fd11::2,dst=fd20::4,id=,type=128,code=0),reply=(src=fd20::4,dst=fd11::2,id=,type=129,code=0),zone= icmpv6,orig=(src=fd11::2,dst=fd20::4,id=,type=128,code=0),reply=(src=fd20::4,dst=fd20::3,id=,type=129,code=0),zone= icmpv6,orig=(src=fd20::3,dst=fd20::4,id=,type=128,code=0),reply=(src=fd12::2,dst=fd20::3,id=,type=129,code=0),zone= ]) @@ -6037,7 +6016,6 @@ NS_CHECK_EXEC([sw01-x], [ping -q -c 3 -i 0.3 -w 2 172.16.1.100 | FORMAT_PING], \ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.100) | \ sed -e 's/zone=[[0-9]]*/zone=/'], [0], [dnl icmp,orig=(src=192.168.1.2,dst=172.16.1.100,id=,type=8,code=0),reply=(src=172.16.1.100,dst=172.16.1.20,id=,type=0,code=0),zone= -icmp,orig=(src=192.168.1.2,dst=172.16.1.100,id=,type=8,code=0),reply=(src=172.16.1.100,dst=192.168.1.2,id=,type=0,code=0),zone= ]) OVS_APP_EXIT_AND_WAIT([ovn-controller])