From patchwork Thu Jul 9 00:24:50 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Ankur Sharma
X-Patchwork-Id: 1325642
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.136; helo=silver.osuosl.org;
envelope-from=ovs-dev-bounces@openvswitch.org; receiver=)
Authentication-Results: ozlabs.org;
dmarc=fail (p=none dis=none) header.from=nutanix.com
Authentication-Results: ozlabs.org;
dkim=fail reason="signature verification failed" (2048-bit key;
unprotected) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256
header.s=proofpoint20171006 header.b=ECbBzPJr;
dkim-atps=neutral
Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(No client certificate requested)
by ozlabs.org (Postfix) with ESMTPS id 4B2H4k1gpkz9s1x
for ; Thu, 9 Jul 2020 10:25:09 +1000 (AEST)
Received: from localhost (localhost [127.0.0.1])
by silver.osuosl.org (Postfix) with ESMTP id 3D93122CC6;
Thu, 9 Jul 2020 00:25:08 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
Received: from silver.osuosl.org ([127.0.0.1])
by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id QdPuBLCZG5dT; Thu, 9 Jul 2020 00:25:02 +0000 (UTC)
Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])
by silver.osuosl.org (Postfix) with ESMTP id 8A28621FA9;
Thu, 9 Jul 2020 00:25:02 +0000 (UTC)
Received: from lf-lists.osuosl.org (localhost [127.0.0.1])
by lists.linuxfoundation.org (Postfix) with ESMTP id 7BD55C077B;
Thu, 9 Jul 2020 00:25:02 +0000 (UTC)
X-Original-To: ovs-dev@openvswitch.org
Delivered-To: ovs-dev@lists.linuxfoundation.org
Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])
by lists.linuxfoundation.org (Postfix) with ESMTP id 0645CC016F
for ; Thu, 9 Jul 2020 00:25:01 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
by hemlock.osuosl.org (Postfix) with ESMTP id EE7EE89786
for ; Thu, 9 Jul 2020 00:25:00 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
Received: from hemlock.osuosl.org ([127.0.0.1])
by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id QoxwasyU-zLC for ;
Thu, 9 Jul 2020 00:24:57 +0000 (UTC)
X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6
Received: from mx0a-002c1b01.pphosted.com (mx0a-002c1b01.pphosted.com
[148.163.151.68])
by hemlock.osuosl.org (Postfix) with ESMTPS id D580189758
for ; Thu, 9 Jul 2020 00:24:57 +0000 (UTC)
Received: from pps.filterd (m0127839.ppops.net [127.0.0.1])
by mx0a-002c1b01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id
0690F5FS014739
for ; Wed, 8 Jul 2020 17:24:57 -0700
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com;
h=from : to : cc :
subject : date : message-id : in-reply-to : references : content-type :
mime-version; s=proofpoint20171006;
bh=xmmPRlU2+AQ9PT3lyJSvocnLBaYCJOpd3QYmb2pPdPE=;
b=ECbBzPJr2H/9Kd+0WJtF7wMSgwlJCAVXXi+wYvZriEDvvifi3eo8VjAEjSGuK8ZVACo8
e5WyuXzEovQWswHRlEBe3xdsoLmCWg+kZ4vw21j2xOpAqEzeD6y60aspD50ttajLLGnL
aIYHD6LQd8b7s7gGbcAOMd19cuOufAxXH5otMhhF3eQ4ZrufM5ftIdz/r2V8bO45UROA
iw1OmQDR/V0MnJlqIJNTGZdYbwPmaLk/KT62aaH2fTyDi7duXicBnc3cEOdW4qloGqpE
ttMWJ5dKmsnpr2fXCpMYlqEZSbjv661v+tV6RrutoF0JDdQS2Ml4Gqu/z84E62l8/2EO Og==
Received: from nam10-dm6-obe.outbound.protection.outlook.com
(mail-dm6nam10lp2104.outbound.protection.outlook.com [104.47.58.104])
by mx0a-002c1b01.pphosted.com with ESMTP id 325k1b8nbt-1
(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
for ; Wed, 08 Jul 2020 17:24:57 -0700
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
b=Anx5F8JRS/uaHYxmvA4dAGabbMFh2jo4YkaSY5EEmqyJo/xbhokfi3HLZ0xlfDtEoSQplzSqCq/4vd0wYx6WK0tY38nKtxP/Fdva01pPCTHeGgK7ulu+ZaaiCxXPdBra2dJkQSQI4gHiHILBk1UZztjbNmM47hTa36Skjy4Y8mJnhp28u7RSzys8RnSOEp/1qkmaRKR3q54DlR1RVVGkfq7htIb7QwcRCjtvCu0SXEVMb3TkHvTjW/uYUem0k+8QZCcrmst0xECq8H/9TG78mfkH3Aio0ZlKiIKDR9obKnPnwH1eDqSnheC5Tlq8dmcm8ou1qziCZ2HKxoO5WhIbwA==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;
s=arcselector9901;
h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
bh=xmmPRlU2+AQ9PT3lyJSvocnLBaYCJOpd3QYmb2pPdPE=;
b=PgOYaC3kf4PR1tTBFtnkuhxzWIa0Rs00RpZdaYxRIZjj/5XmeViNNwvvqh/X10hy8YTNuGgThB8R6RDZYkJ2+9yy6sgunm0D+Dvo15zlnYicDuvGi8AgYNO37CPUQBCA6vxpWd6RVqC9eCWPOXirkdq++TVO4mXfp49vOV7U/PivvWZBxGkEFNrVSMyRZoSVoA/lkzTbV6LnQ8vVZndRCfSUdRQET+VoLhV2Dkbc9GYGifACMO2HtzVDyFmIKBRVrNUBsHgHsxll+hOjtqiVLFYZRdHBp2CUWcPIVMqiggnt6ahGZCGl/GI6tA/Npa4PYL8JggO1yJGs8KoJSQXZRg==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
smtp.mailfrom=nutanix.com; dmarc=pass action=none header.from=nutanix.com;
dkim=pass header.d=nutanix.com; arc=none
Authentication-Results: openvswitch.org; dkim=none (message not signed)
header.d=none;openvswitch.org; dmarc=none action=none
header.from=nutanix.com;
Received: from BL0PR02MB3714.namprd02.prod.outlook.com (2603:10b6:207:44::16)
by MN2PR02MB7086.namprd02.prod.outlook.com (2603:10b6:208:20c::17)
with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3153.22; Thu, 9 Jul
2020 00:24:55 +0000
Received: from BL0PR02MB3714.namprd02.prod.outlook.com
([fe80::445e:7f74:952e:2ccb]) by BL0PR02MB3714.namprd02.prod.outlook.com
([fe80::445e:7f74:952e:2ccb%5]) with mapi id 15.20.3174.020; Thu, 9 Jul 2020
00:24:55 +0000
From: Ankur Sharma
To: ovs-dev@openvswitch.org
Date: Wed, 8 Jul 2020 17:24:50 -0700
Message-Id: <1594254291-90069-2-git-send-email-svc.mail.git@nutanix.com>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1594254291-90069-1-git-send-email-svc.mail.git@nutanix.com>
References: <1594254291-90069-1-git-send-email-svc.mail.git@nutanix.com>
X-ClientProxiedBy: BYAPR01CA0001.prod.exchangelabs.com (2603:10b6:a02:80::14)
To BL0PR02MB3714.namprd02.prod.outlook.com
(2603:10b6:207:44::16)
MIME-Version: 1.0
X-MS-Exchange-MessageSentRepresentingType: 1
Received: from northd.localdomain (192.146.154.98) by
BYAPR01CA0001.prod.exchangelabs.com (2603:10b6:a02:80::14) with Microsoft
SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
15.20.3174.20 via Frontend Transport; Thu, 9 Jul 2020 00:24:55 +0000
X-Mailer: git-send-email 1.8.3.1
X-Originating-IP: [192.146.154.98]
X-MS-PublicTrafficType: Email
X-MS-Office365-Filtering-Correlation-Id: f546c386-096a-4d9d-c5c8-08d8239e8173
X-MS-TrafficTypeDiagnostic: MN2PR02MB7086:
X-MS-Exchange-Transport-Forked: True
X-Microsoft-Antispam-PRVS:
x-proofpoint-crosstenant: true
X-MS-Oob-TLC-OOBClassifiers: OLM:497;
X-Forefront-PRVS: 04599F3534
X-MS-Exchange-SenderADCheck: 1
X-Microsoft-Antispam: BCL:0;
X-Microsoft-Antispam-Message-Info:
oksoUOo18vQ18dMc5u1QWvLiFCJuqKO5aBYzN/fZ5OD1+eqqbmyTR0dy2WCqgUfXIqo+eDCzP/4ZxdOWfWwcCPG3FALmTBlRvLJbY98Nn7HRZCIq70lBPmCQxGDYN4MLkQoGbushXLMnDo5mfHIbGGwKonnrK1xg2LXWCYxBOEPhBQmvWGXsEBVhTqfGU7nr7f8315TSBZZvajFNggviyMgSpjoxuqvF5jCLcuFizSwTkOQfVTfpEBx4NNedLHXu12q8KTZmPdTiDi5/iEx6nD+bFYhp6diA5vYKVCXrh8JPbNq5TX9+UulxfbY1kNkQC+XQkhJ15H/wBC6ODNg+1Q==
X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
IPV:NLI; SFV:NSPM; H:BL0PR02MB3714.namprd02.prod.outlook.com; PTR:; CAT:NONE;
SFTY:;
SFS:(4636009)(136003)(396003)(366004)(39860400002)(376002)(346002)(956004)(36756003)(4326008)(6506007)(66574015)(107886003)(478600001)(52116002)(83380400001)(6916009)(16526019)(186003)(5660300002)(316002)(6512007)(26005)(66946007)(6486002)(8676002)(6666004)(86362001)(66556008)(8936002)(2906002)(66476007)(2616005);
DIR:OUT; SFP:1102;
X-MS-Exchange-AntiSpam-MessageData:
nngyK1ZY+DrF0CoPm8P8wdX5d2EnPx2SqQklfMRNCyXC3vz9WNIgkjdDCwz9LqG1T9HCQrp1N3fJWGPWZmmwiXai+pebnHUjycxDWZiGPnHtw9WXDlBj0SulLDzx4Cx8GMlX2egz/RmjZCCEG3fImu5Mdsy9z0inIaFKGuqMupVm4eyT1xbtZHJ2hABXUr4ewi/IomDifaNkom44JfB0B874DLrTjxze86AfJuo9SKJtSxs+eCY5U29TrLp19Lj2+9ST1v0a/Y8Wt/IqbsCG8d/HwQWnIj9CKESkWl7to5GoxXFI4kvFz3xmM99l+1qVnAjihrobpzidwtXQU02N0qWUkw0C7tdOgMg4xQfLz3tDku9zqZ2Ip6h0Zq+BJhjq6KxDxLW90Dt1mDX54+4jx3fBgvVbSylzekH9UsEnKS8LDAFDEki7YM+36bEPs2FoUb/LsR8S/2HwwVYpKxv8uilfw8syKfVaQPlEUACw06E=
X-OriginatorOrg: nutanix.com
X-MS-Exchange-CrossTenant-Network-Message-Id:
f546c386-096a-4d9d-c5c8-08d8239e8173
X-MS-Exchange-CrossTenant-AuthSource: BL0PR02MB3714.namprd02.prod.outlook.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Jul 2020 00:24:55.8437 (UTC)
X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted
X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043
X-MS-Exchange-CrossTenant-MailboxType: HOSTED
X-MS-Exchange-CrossTenant-UserPrincipalName:
glKcXdEh96xAUFTDFT1zOHTzGKnJIgR+ymIVEdVkZsHyJ05iqMoP8b8IbifNcEsLAbcN3pTDWkKuc6kHWWLm7VIJz4blj/HaVV5irSuqxwY=
X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR02MB7086
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687
definitions=2020-07-08_18:2020-07-08,
2020-07-08 signatures=0
X-Proofpoint-Spam-Reason: safe
Subject: [ovs-dev] [PATCH v3 1/2 ovn] External IP based NAT: Add Columns and
CLI
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: Ankur Sharma
This patch adds following columns to NAT table.
a. applied_ext_ips:
Represents Address Set of External IPs for which
a NAT rule is applicable.
b. exempted_ext_ips:
Represents Address Set of External IPs for which
a NAT rule is NOT applicable.
Additionally, patch adds nbctl cli to set these column values.
ovn-nbctl [--is-applied] lr-nat-update-ext-ip
Signed-off-by: Ankur Sharma
---
ovn-nb.ovsschema | 14 +++++-
ovn-nb.xml | 35 +++++++++++++++
tests/ovn-nbctl.at | 44 ++++++++++++++++++-
utilities/ovn-nbctl.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 205 insertions(+), 4 deletions(-)
diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema
index da9af71..ab8b81c 100644
--- a/ovn-nb.ovsschema
+++ b/ovn-nb.ovsschema
@@ -1,7 +1,7 @@
{
"name": "OVN_Northbound",
- "version": "5.24.0",
- "cksum": "1092394564 25961",
+ "version": "5.24.1",
+ "cksum": "2778723960 26420",
"tables": {
"NB_Global": {
"columns": {
@@ -400,6 +400,16 @@
"snat",
"dnat_and_snat"
]]}}},
+ "applied_ext_ips": {"type": {
+ "key": {"type": "uuid", "refTable": "Address_Set",
+ "refType": "strong"},
+ "min": 0,
+ "max": 1}},
+ "exempted_ext_ips": {"type": {
+ "key": {"type": "uuid", "refTable": "Address_Set",
+ "refType": "strong"},
+ "min": 0,
+ "max": 1}},
"options": {"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}},
"external_ids": {
diff --git a/ovn-nb.xml b/ovn-nb.xml
index db5908c..9cce375 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -2658,6 +2658,41 @@
+
+ It represents Address Set of external ips that NAT rule is applicable to.
+ For SNAT type NAT rules, this refers to destination addresses.
+ For DNAT type NAT rules, this refers to source addresses.
+
+
+ This configuration overrides the default NAT behavior of applying a
+ rule solely based on internal IP. Without this configuration, NAT
+ happens without considering the external IP (i.e dest/source for
+ snat/dnat type rule). With this configuration NAT rule is applied
+ ONLY if external ip is in the input Address Set.
+
+
+
+
+ It represents Address Set of external ips that NAT rule is NOT
+ applicable to.
+ For SNAT type NAT rules, this refers to destination addresses.
+ For DNAT type NAT rules, this refers to source addresses.
+
+
+ This configuration overrides the default NAT behavior of applying a
+ rule solely based on internal IP. Without this configuration, NAT
+ happens without considering the external IP (i.e dest/source for
+ snat/dnat type rule). With this configuration NAT rule is NOT applied
+ if external ip is in the input Address Set.
+
+
+
+ "applied_ext_ips" and "exempted_ext_ips" are mutually
+ exclusive to each other. If both Address Sets are set for a rule,
+ then the NAT rule is not applied.
+
+
+
Indicates if a dnat_and_snat rule should lead to connection
tracking state or not.
diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
index 6d66087..40fc1e5 100644
--- a/tests/ovn-nbctl.at
+++ b/tests/ovn-nbctl.at
@@ -685,7 +685,49 @@ snat 40.0.0.3 21-65535 192.168.1.6
AT_CHECK([ovn-nbctl lr-nat-del lr0])
AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [])
AT_CHECK([ovn-nbctl lr-nat-del lr0])
-AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat])])
+AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat])
+
+AT_CHECK([ovn-nbctl lr-nat-del lr0])
+
+ovn-nbctl create Address_Set name=allowed_range addresses=\"1.1.1.1\"
+ovn-nbctl create Address_Set name=disallowed_range addresses=\"2.2.2.2\"
+AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 40.0.0.3 192.168.1.6])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 snat 192.168.1.6 disallowed_range])
+AT_CHECK([ovn-nbctl --is-applied lr-nat-update-ext-ip lr0 snat 192.168.1.6 allowed_range])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 snat 192.168.1.6 disallowed_range_tmp], [1], [],
+[ovn-nbctl: disallowed_range_tmp: Address Set name not found
+])
+AT_CHECK([ovn-nbctl --is-applied lr-nat-update-ext-ip lr0 snat 192.168.1.6 allowed_range_tmp], [1], [],
+[ovn-nbctl: allowed_range_tmp: Address Set name not found
+])
+
+AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 40.0.0.4 192.168.1.7])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 dnat 40.0.0.4 disallowed_range])
+AT_CHECK([ovn-nbctl --is-applied lr-nat-update-ext-ip lr0 dnat 40.0.0.4 allowed_range])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 dnat 40.0.0.4 disallowed_range_tmp], [1], [],
+[ovn-nbctl: disallowed_range_tmp: Address Set name not found
+])
+AT_CHECK([ovn-nbctl --is-applied lr-nat-update-ext-ip lr0 dnat 40.0.0.4 allowed_range_tmp], [1], [],
+[ovn-nbctl: allowed_range_tmp: Address Set name not found
+])
+
+AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 40.0.0.5 192.168.1.8])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 dnat_and_snat 40.0.0.5 disallowed_range])
+AT_CHECK([ovn-nbctl --is-applied lr-nat-update-ext-ip lr0 dnat 40.0.0.4 allowed_range])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 dnat 40.0.0.4 disallowed_range_tmp], [1], [],
+[ovn-nbctl: disallowed_range_tmp: Address Set name not found
+])
+AT_CHECK([ovn-nbctl --is-applied lr-nat-update-ext-ip lr0 dnat 40.0.0.4 allowed_range_tmp], [1], [],
+[ovn-nbctl: allowed_range_tmp: Address Set name not found
+])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 snat 192.168.1.6], [1], [],
+[ovn-nbctl: 'lr-nat-update-ext-ip' command requires at least 4 arguments
+])
+AT_CHECK([ovn-nbctl lr-nat-update-ext-ip lr0 snat 192.168.16 disallowed_range], [1], [],
+[ovn-nbctl: 192.168.16: Invalid IP address or CIDR
+])
+
+AT_CHECK([ovn-nbctl lr-nat-del lr0])])
dnl ---------------------------------------------------------------------
diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c
index 7578b99..fbdb278 100644
--- a/utilities/ovn-nbctl.c
+++ b/utilities/ovn-nbctl.c
@@ -838,6 +838,46 @@ lr_by_name_or_uuid(struct ctl_context *ctx, const char *id,
return NULL;
}
+/* Find an Address Set given its id. */
+static char * OVS_WARN_UNUSED_RESULT
+address_set_by_name_or_uuid(struct ctl_context *ctx,
+ const char *id, bool must_exist,
+ const struct nbrec_address_set **addr_set_p)
+{
+ const struct nbrec_address_set *addr_set = NULL;
+ bool is_uuid = false;
+ struct uuid addr_set_uuid;
+
+ *addr_set_p = NULL;
+ if (uuid_from_string(&addr_set_uuid, id)) {
+ is_uuid = true;
+ addr_set = nbrec_address_set_get_for_uuid(ctx->idl, &addr_set_uuid);
+ }
+
+ if (!addr_set) {
+ const struct nbrec_address_set *iter;
+
+ NBREC_ADDRESS_SET_FOR_EACH(iter, ctx->idl) {
+ if (strcmp(iter->name, id)) {
+ continue;
+ }
+ if (addr_set) {
+ return xasprintf("Multiple Address Sets named '%s'. "
+ "Use a UUID.", id);
+ }
+ addr_set = iter;
+ }
+ }
+
+ if (!addr_set && must_exist) {
+ return xasprintf("%s: Address Set %s not found",
+ id, is_uuid ? "UUID" : "name");
+ }
+
+ *addr_set_p = addr_set;
+ return NULL;
+}
+
static char * OVS_WARN_UNUSED_RESULT
ls_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist,
const struct nbrec_logical_switch **ls_p)
@@ -4503,6 +4543,79 @@ nbctl_lr_nat_list(struct ctl_context *ctx)
smap_destroy(&lr_nats);
}
+static void
+nbctl_lr_nat_set_ext_ips(struct ctl_context *ctx)
+{
+ const struct nbrec_logical_router *lr = NULL;
+ const struct nbrec_address_set *addr_set = NULL;
+ bool is_applied = shash_find(&ctx->options, "--is-applied");
+ bool nat_found = false;
+
+ if (ctx->argc < 5) {
+ ctl_error(ctx, "Incomplete input, Required arguments are: "
+ "ROUTER TYPE IP ADDRESS_SET");
+ return;
+ }
+
+ char *error = lr_by_name_or_uuid(ctx, ctx->argv[1], true, &lr);
+ if (error) {
+ ctx->error = error;
+ return;
+ }
+
+ const char *nat_type = ctx->argv[2];
+ if (strcmp(nat_type, "dnat") && strcmp(nat_type, "snat")
+ && strcmp(nat_type, "dnat_and_snat")) {
+ ctl_error(ctx, "%s: type must be one of \"dnat\", \"snat\" and "
+ "\"dnat_and_snat\".", nat_type);
+ return;
+ }
+
+ error = address_set_by_name_or_uuid(ctx, ctx->argv[4], true, &addr_set);
+ if (error) {
+ ctx->error = error;
+ return;
+ }
+
+ char *nat_ip = normalize_prefix_str(ctx->argv[3]);
+ if (!nat_ip) {
+ ctl_error(ctx, "%s: Invalid IP address or CIDR", ctx->argv[3]);
+ return;
+ }
+
+ int is_snat = !strcmp("snat", nat_type);
+
+ /* Update the matching NAT. */
+ for (size_t i = 0; i < lr->n_nat; i++) {
+ struct nbrec_nat *nat = lr->nat[i];
+ char *old_ip = normalize_prefix_str(is_snat
+ ? nat->logical_ip
+ : nat->external_ip);
+
+ if (!old_ip) {
+ continue;
+ }
+
+ if (!strcmp(nat_type, nat->type) && !strcmp(nat_ip, old_ip)) {
+ nat_found = true;
+ nbrec_logical_router_verify_nat(lr);
+ if (is_applied) {
+ nbrec_nat_set_applied_ext_ips(nat, addr_set);
+ } else {
+ nbrec_nat_set_exempted_ext_ips(nat, addr_set);
+ }
+ return;
+ }
+ }
+
+ if (!nat_found) {
+ ctl_error(ctx, "%s: Could not locate nat rule for: %s.",
+ nat_type, nat_ip);
+ }
+
+ free(nat_ip);
+}
+
static char * OVS_WARN_UNUSED_RESULT
lrp_by_name_or_uuid(struct ctl_context *ctx, const char *id, bool must_exist,
@@ -6413,7 +6526,8 @@ static const struct ctl_command_syntax nbctl_commands[] = {
{ "lr-nat-del", 1, 3, "ROUTER [TYPE [IP]]", NULL,
nbctl_lr_nat_del, NULL, "--if-exists", RW },
{ "lr-nat-list", 1, 1, "ROUTER", NULL, nbctl_lr_nat_list, NULL, "", RO },
-
+ { "lr-nat-update-ext-ip", 4, 4, "ROUTER TYPE IP ADDRESS_SET", NULL,
+ nbctl_lr_nat_set_ext_ips, NULL, "--is-applied", RW},
/* load balancer commands. */
{ "lb-add", 3, 4, "LB VIP[:PORT] IP[:PORT]... [PROTOCOL]", NULL,
nbctl_lb_add, NULL, "--may-exist,--add-duplicate", RW },
From patchwork Thu Jul 9 00:24:51 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Ankur Sharma
X-Patchwork-Id: 1325643
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.136; helo=silver.osuosl.org;
envelope-from=ovs-dev-bounces@openvswitch.org; receiver=)
Authentication-Results: ozlabs.org;
dmarc=fail (p=none dis=none) header.from=nutanix.com
Authentication-Results: ozlabs.org;
dkim=fail reason="signature verification failed" (2048-bit key;
unprotected) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256
header.s=proofpoint20171006 header.b=Zp1cWxc4;
dkim-atps=neutral
Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(No client certificate requested)
by ozlabs.org (Postfix) with ESMTPS id 4B2H4m72P6z9s1x
for ; Thu, 9 Jul 2020 10:25:12 +1000 (AEST)
Received: from localhost (localhost [127.0.0.1])
by silver.osuosl.org (Postfix) with ESMTP id 6BB2C22026;
Thu, 9 Jul 2020 00:25:11 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
Received: from silver.osuosl.org ([127.0.0.1])
by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id GX10oFedkFdn; Thu, 9 Jul 2020 00:25:04 +0000 (UTC)
Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])
by silver.osuosl.org (Postfix) with ESMTP id B1BC2220DF;
Thu, 9 Jul 2020 00:25:03 +0000 (UTC)
Received: from lf-lists.osuosl.org (localhost [127.0.0.1])
by lists.linuxfoundation.org (Postfix) with ESMTP id 9C032C1797;
Thu, 9 Jul 2020 00:25:03 +0000 (UTC)
X-Original-To: ovs-dev@openvswitch.org
Delivered-To: ovs-dev@lists.linuxfoundation.org
Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])
by lists.linuxfoundation.org (Postfix) with ESMTP id 8E580C016F
for ; Thu, 9 Jul 2020 00:25:01 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
by silver.osuosl.org (Postfix) with ESMTP id 7558E21FA9
for ; Thu, 9 Jul 2020 00:25:01 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
Received: from silver.osuosl.org ([127.0.0.1])
by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id OQUS+0gqsXkg for ;
Thu, 9 Jul 2020 00:24:59 +0000 (UTC)
X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6
Received: from mx0a-002c1b01.pphosted.com (mx0a-002c1b01.pphosted.com
[148.163.151.68])
by silver.osuosl.org (Postfix) with ESMTPS id 74B842050A
for ; Thu, 9 Jul 2020 00:24:59 +0000 (UTC)
Received: from pps.filterd (m0127838.ppops.net [127.0.0.1])
by mx0a-002c1b01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id
0690DRao012175
for ; Wed, 8 Jul 2020 17:24:59 -0700
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com;
h=from : to : cc :
subject : date : message-id : in-reply-to : references : content-type :
mime-version; s=proofpoint20171006;
bh=j1n4PGxzeNTnF9RWZBI3E+q0dN+lFK9GkoSPwyik+Fc=;
b=Zp1cWxc4Upn9fZBMhqKdcUympW9oFONps+a28/4s1MOEM4ekc7RGCKyOQvjvDEKV7TtK
xTUVTiFbede/myOs1OeYRTyG6cl9JrJYpsox8lb5nWXU1z2BJpGqSSi/jiCS/1+WfkIc
j6biclVrLg4V+CsJL17uxNCBGU0qqGy33M0Q+3GUvKnoL4Dh2LX6AsMFNjQNNRRKE1gD
Llu9qr2xEWFEhWbOBQr6VZUCDv33ebPSsR1l/4QzY8fQ1OgmCtQcRgrwJP/FkYfhU6dq
Y/hFOUzCFvWivZK7kHWp2lGkOqxVvd08KdtsjG9DrilER3RgEcK5ig7AnD0LkeJIlh02 Eg==
Received: from nam10-dm6-obe.outbound.protection.outlook.com
(mail-dm6nam10lp2107.outbound.protection.outlook.com [104.47.58.107])
by mx0a-002c1b01.pphosted.com with ESMTP id 325k0srn9k-1
(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT)
for ; Wed, 08 Jul 2020 17:24:58 -0700
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
b=SfX+4fqlVjNlAiUSG4HhLz/hK8N3H6HRYxnqjqnc1t1iBmCM9Cj0hj7u8hMEpfWODLeslr3FHZTcnCyLCsPcC2g2Kg9BC8UymeWuG9/WQBJObQsCJumWV/4s8o6XcRvygxVFwVKYWrn9JewuwMnywtJz2V0opcYw51PDEmwK4jIQCj3949BOEmgdTUPLKj62Z7azK7f+H4Lcm99lqrenrHpLYqM+ZXmvykxQO6pVhT/vkMlej3ua9fMQI+fpP5fraVg7wBGLuU+3InHV34BpaPv6A5Y7d5oHbYISatgU3M/VkL6DMo4esStG9mBXKjSwoemeHRuYsCjL8WwCvVBtJA==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;
s=arcselector9901;
h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
bh=j1n4PGxzeNTnF9RWZBI3E+q0dN+lFK9GkoSPwyik+Fc=;
b=lP6GeJSBMIPNACUV3oJz4IQ5ljozYXRb7Uypk9i5JOtiYLtP/FnKiU/te6ybqjLfhWYnhrQKQz8p4NLB3rXcimkAzRMni1mz4Jvwpy1lDolz22T6pyxVIyhpmyX4Gm+OMkIVGJuadLpGSJCPqblxs6i7w3kAYng90cbgb17KQJ6lpsdNLTVpsfkRpnoTaJgLG+w1wOfANMabbNUpIfz+O8+cMCMTbTw3zQSYzhDLxC/fMrZEYV0lJ9PpdLL6EhANSDkhq9VR3gqwD3UYgCRCU4P8vuxvpmwDzMpoPPJ9+Qn/JvNPEPDf7fgSYZQQrsMIYFDrTjdQAjDz7aUrGU4d4g==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
smtp.mailfrom=nutanix.com; dmarc=pass action=none header.from=nutanix.com;
dkim=pass header.d=nutanix.com; arc=none
Authentication-Results: openvswitch.org; dkim=none (message not signed)
header.d=none;openvswitch.org; dmarc=none action=none
header.from=nutanix.com;
Received: from BL0PR02MB3714.namprd02.prod.outlook.com (2603:10b6:207:44::16)
by MN2PR02MB7086.namprd02.prod.outlook.com (2603:10b6:208:20c::17)
with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3153.22; Thu, 9 Jul
2020 00:24:57 +0000
Received: from BL0PR02MB3714.namprd02.prod.outlook.com
([fe80::445e:7f74:952e:2ccb]) by BL0PR02MB3714.namprd02.prod.outlook.com
([fe80::445e:7f74:952e:2ccb%5]) with mapi id 15.20.3174.020; Thu, 9 Jul 2020
00:24:57 +0000
From: Ankur Sharma
To: ovs-dev@openvswitch.org
Date: Wed, 8 Jul 2020 17:24:51 -0700
Message-Id: <1594254291-90069-3-git-send-email-svc.mail.git@nutanix.com>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1594254291-90069-1-git-send-email-svc.mail.git@nutanix.com>
References: <1594254291-90069-1-git-send-email-svc.mail.git@nutanix.com>
X-ClientProxiedBy: BYAPR01CA0001.prod.exchangelabs.com (2603:10b6:a02:80::14)
To BL0PR02MB3714.namprd02.prod.outlook.com
(2603:10b6:207:44::16)
MIME-Version: 1.0
X-MS-Exchange-MessageSentRepresentingType: 1
Received: from northd.localdomain (192.146.154.98) by
BYAPR01CA0001.prod.exchangelabs.com (2603:10b6:a02:80::14) with Microsoft
SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
15.20.3174.20 via Frontend Transport; Thu, 9 Jul 2020 00:24:56 +0000
X-Mailer: git-send-email 1.8.3.1
X-Originating-IP: [192.146.154.98]
X-MS-PublicTrafficType: Email
X-MS-Office365-Filtering-Correlation-Id: 8c31ae65-7fee-4959-745a-08d8239e8257
X-MS-TrafficTypeDiagnostic: MN2PR02MB7086:
X-MS-Exchange-Transport-Forked: True
X-Microsoft-Antispam-PRVS:
x-proofpoint-crosstenant: true
X-MS-Oob-TLC-OOBClassifiers: OLM:1079;
X-Forefront-PRVS: 04599F3534
X-MS-Exchange-SenderADCheck: 1
X-Microsoft-Antispam: BCL:0;
X-Microsoft-Antispam-Message-Info:
XsdCtfDfo7/V9pOeFW/WVjJ3woKE/mw87qo8EZr3nwrfhUg5ESYlpPSq67QRvf2LH2dAxkJlFoQw6jrtZszRVXRjHcQwziPkQJvloPr2Mf1aTnT3mpTLMAhhgvPTmSscioJ3WIWMeXPRWmisig+zTG8TorEZD175DRMhXfqPx+Yyf2ZQurYQMn90oYUZmf0rKRa8Tw6yeCvBB4dFPODXX1rsmIPvHTir4Y3/vIM9EU8JEGE1ejaXhJvtTugifXmeKtPWYVvfEukqaIasRQonuVSq+1hbRiiTFgqBv0qmSRSxsEJ9vuq0z0vwzrXFpoC1
X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
IPV:NLI; SFV:NSPM; H:BL0PR02MB3714.namprd02.prod.outlook.com; PTR:; CAT:NONE;
SFTY:;
SFS:(4636009)(136003)(396003)(366004)(39860400002)(376002)(346002)(956004)(36756003)(4326008)(6506007)(66574015)(107886003)(478600001)(52116002)(83380400001)(6916009)(16526019)(186003)(5660300002)(316002)(6512007)(30864003)(26005)(66946007)(6486002)(8676002)(6666004)(86362001)(66556008)(8936002)(2906002)(66476007)(2616005);
DIR:OUT; SFP:1102;
X-MS-Exchange-AntiSpam-MessageData:
FTUl3JlAgWQ4v0VgY2PIF609x1FJrLR1t1P30cUPfHK0vixNYF7iCYob110crIFch7BkbEpvN3yJ4eOZKS4z3FI6W9rRVUXxXtdwBlE9+7mSsRpSWpsZoDL+XLA8vvIDxUXABWYuwT9k/tm8Qa0/AxDuDvaP81AlnFELevmNa7g+uV4f9HbwuxgK03qji3kgWJgGQ5giBrVDOYZg2A2vBXHhEXntI7jociOWwSgaab1dO0q1QM9m3B5qlwlYE8K8L9HwmeNd1pTuRsgCJRj3o1k36qvDwUp9tQCSHjEpEwBCaGh54UYFdhskQhup1NgBpJLeXnX5qFuUjT2CQuDanwmoHhD3uXajHNpGY+TtGiWgzkMpoepGjieTf9X6Qa45JwLr+PRRXafIT+0y5ox28NCzaQmnKfxqIU5Ma7eEnlHfkyAXemT5ecuud7VCzyIfoEIJz/vhFlRhb3GPWKZm3thaV8ZnqW/qDv0guGnRCEY=
X-OriginatorOrg: nutanix.com
X-MS-Exchange-CrossTenant-Network-Message-Id:
8c31ae65-7fee-4959-745a-08d8239e8257
X-MS-Exchange-CrossTenant-AuthSource: BL0PR02MB3714.namprd02.prod.outlook.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Jul 2020 00:24:57.3418 (UTC)
X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted
X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043
X-MS-Exchange-CrossTenant-MailboxType: HOSTED
X-MS-Exchange-CrossTenant-UserPrincipalName:
XO8epaxLGdJTk2+Q1de8cb/WVxHT/ZC/VUWOyt4m+tdFC0LcvVpCh/EgtOWtUaeCpXyqYcaeGFXRb3XblrfzDYrs94Kk4J9bBGsqYsOvhSM=
X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR02MB7086
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687
definitions=2020-07-08_18:2020-07-08,
2020-07-08 signatures=0
X-Proofpoint-Spam-Reason: safe
Subject: [ovs-dev] [PATCH v3 2/2] External IP based NAT: NORTHD changes to
use applied/exempted external ip
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: Ankur Sharma
This patch has northd changes which consumes applied/exempted external ip
configuration per NAT rule in logical flow.
Applied/Exempted external ip range adds an additional match criteria in
snat/dnat/unsnat/undant logical flow rules.
For example, if an allowed_external_ip address set ("efgh")
is configured for following NAT rule.
TYPE EXTERNAL_IP LOGICAL_IP
snat 10.15.24.135 50.0.0.10
Then logical flow will look like following:
..(lr_out_snat)...match=(ip && .... && ip4.dst == $efgh), action=(ct_snat(...);)
...(lr_in_unsnat...)match=(ip && ..... && ip4.src == $efgh), action=(ct_snat;)
Signed-off-by: Ankur Sharma
---
northd/ovn-northd.c | 61 +++++++++++++++++++++++++
tests/ovn-northd.at | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 188 insertions(+)
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 203391a..32b14ac 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -8047,6 +8047,23 @@ lrouter_nat_is_stateless(const struct nbrec_nat *nat)
return false;
}
+static inline void
+lrouter_nat_add_ext_ip_match(struct ds *match, const struct nbrec_nat *nat,
+ bool is_v6, bool is_src)
+{
+ struct nbrec_address_set *applied_ext_ips = nat->applied_ext_ips;
+ struct nbrec_address_set *exempted_ext_ips = nat->exempted_ext_ips;
+
+ ds_put_format(match, " && ip%s.%s %s $%s",
+ is_v6 ? "6" : "4",
+ is_src ? "src" : "dst",
+ applied_ext_ips? "==" : "!=",
+ applied_ext_ips?
+ applied_ext_ips->name :
+ exempted_ext_ips->name);
+ return;
+}
+
/* Builds the logical flow that replies to ARP requests for an 'ip_address'
* owned by the router. The flow is inserted in table S_ROUTER_IN_IP_INPUT
* with the given priority.
@@ -8996,6 +9013,18 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
struct in6_addr ipv6, mask_v6, v6_exact = IN6ADDR_EXACT_INIT;
bool is_v6 = false;
bool stateless = lrouter_nat_is_stateless(nat);
+ struct nbrec_address_set *applied_ext_ips =
+ nat->applied_ext_ips;
+ struct nbrec_address_set *exempted_ext_ips =
+ nat->exempted_ext_ips;
+
+ if (applied_ext_ips && exempted_ext_ips) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+ VLOG_WARN_RL(&rl, "NAT rule: "UUID_FMT" not applied, since"
+ "both applied and exempt external ips set",
+ UUID_ARGS(&(nat->header_.uuid)));
+ continue;
+ }
char *error = ip_parse_masked(nat->external_ip, &ip, &mask);
if (error || mask != OVS_BE32_MAX) {
@@ -9083,6 +9112,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, "ip && ip%s.dst == %s",
is_v6 ? "6" : "4",
nat->external_ip);
+ if (applied_ext_ips || exempted_ext_ips) {
+ lrouter_nat_add_ext_ip_match(&match, nat, is_v6, true);
+ }
+
if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
ds_put_format(&actions, "ip%s.dst=%s; next;",
is_v6 ? "6" : "4", nat->logical_ip);
@@ -9112,6 +9145,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
od->l3redirect_port->json_key);
}
+ if (applied_ext_ips || exempted_ext_ips) {
+ lrouter_nat_add_ext_ip_match(&match, nat, is_v6, true);
+ }
+
if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
ds_put_format(&actions, "ip%s.dst=%s; next;",
is_v6 ? "6" : "4", nat->logical_ip);
@@ -9140,6 +9177,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, "ip && ip%s.dst == %s",
is_v6 ? "6" : "4",
nat->external_ip);
+ if (applied_ext_ips || exempted_ext_ips) {
+ lrouter_nat_add_ext_ip_match(&match, nat, is_v6, true);
+ }
+
ds_clear(&actions);
if (dnat_force_snat_ip) {
/* Indicate to the future tables that a DNAT has taken
@@ -9183,6 +9224,11 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, " && is_chassis_resident(%s)",
od->l3redirect_port->json_key);
}
+
+ if (applied_ext_ips || exempted_ext_ips) {
+ lrouter_nat_add_ext_ip_match(&match, nat, is_v6, true);
+ }
+
ds_clear(&actions);
if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
@@ -9264,6 +9310,11 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, " && is_chassis_resident(%s)",
od->l3redirect_port->json_key);
}
+
+ if (applied_ext_ips || exempted_ext_ips) {
+ lrouter_nat_add_ext_ip_match(&match, nat, is_v6, false);
+ }
+
ds_clear(&actions);
if (distributed) {
ds_put_format(&actions, "eth.src = "ETH_ADDR_FMT"; ",
@@ -9293,6 +9344,11 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, "ip && ip%s.src == %s",
is_v6 ? "6" : "4",
nat->logical_ip);
+
+ if (applied_ext_ips || exempted_ext_ips) {
+ lrouter_nat_add_ext_ip_match(&match, nat, is_v6, false);
+ }
+
ds_clear(&actions);
if (!strcmp(nat->type, "dnat_and_snat") && stateless) {
@@ -9333,6 +9389,11 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, " && is_chassis_resident(%s)",
od->l3redirect_port->json_key);
}
+
+ if (applied_ext_ips || exempted_ext_ips) {
+ lrouter_nat_add_ext_ip_match(&match, nat, is_v6, false);
+ }
+
ds_clear(&actions);
if (distributed) {
ds_put_format(&actions, "eth.src = "ETH_ADDR_FMT"; ",
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 1e4d20a..387b2bb 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -1140,6 +1140,133 @@ ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1
AT_CLEANUP
+AT_SETUP([ovn -- check allowed/disallowed external dnat, snat and dnat_and_snat rules])
+ovn_start
+
+ovn-sbctl chassis-add gw1 geneve 127.0.0.1
+
+ovn-nbctl lr-add R1
+ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
+
+ovn-nbctl ls-add S1
+ovn-nbctl lsp-add S1 S1-R1
+ovn-nbctl lsp-set-type S1-R1 router
+ovn-nbctl lsp-set-addresses S1-R1 router
+ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1
+
+ovn-nbctl lrp-set-gateway-chassis R1-S1 gw1
+
+uuid=`ovn-sbctl --columns=_uuid --bare find Port_Binding logical_port=cr-R1-S1`
+echo "CR-LRP UUID is: " $uuid
+
+ovn-nbctl create Address_Set name=allowed_range addresses=\"1.1.1.1\"
+ovn-nbctl create Address_Set name=disallowed_range addresses=\"2.2.2.2\"
+
+# SNAT with ALLOWED_IPs
+ovn-nbctl lr-nat-add R1 snat 172.16.1.1 50.0.0.11
+ovn-nbctl --is-applied lr-nat-update-ext-ip R1 snat 50.0.0.11 allowed_range
+
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_out_snat | wc -l`])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | 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 R1 | grep lr_in_unsnat | grep "ip4.dst == 172.16.1.1" | grep "ip4.src == $allowed_range" | wc -l], [0], [1
+])
+
+# SNAT with DISALLOWED_IPs
+ovn-nbctl lr-nat-del R1 snat 50.0.0.11
+ovn-nbctl lr-nat-add R1 snat 172.16.1.1 50.0.0.11
+ovn-nbctl lr-nat-update-ext-ip R1 snat 50.0.0.11 disallowed_range
+
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_out_snat | \
+wc -l`])
+
+ovn-nbctl show R1
+ovn-sbctl dump-flows R1
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst != $disallowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_in_unsnat | grep "ip4.dst == 172.16.1.1" | grep "ip4.src != $disallowed_range" | wc -l], [0], [1
+])
+
+# Stateful FIP with ALLOWED_IPs
+ovn-nbctl lr-nat-del R1 snat 50.0.0.11
+ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.2 50.0.0.11
+ovn-nbctl --is-applied lr-nat-update-ext-ip R1 dnat_and_snat 172.16.1.2 allowed_range
+ovn-nbctl show R1
+ovn-sbctl dump-flows R1
+
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_out_snat | \
+wc -l`])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | 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 R1 | grep lr_in_unsnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_out_undnat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $allowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1
+])
+
+# Stateful FIP with DISALLOWED_IPs
+ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.2
+ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.2 50.0.0.11
+ovn-nbctl lr-nat-update-ext-ip R1 dnat_and_snat 172.16.1.2 disallowed_range
+ovn-nbctl show R1
+ovn-sbctl dump-flows R1
+
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_out_snat | \
+wc -l`])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst != $disallowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_in_unsnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src != $disallowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_out_undnat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst != $disallowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src != $disallowed_range" | wc -l], [0], [1
+])
+
+# Stateless FIP with DISALLOWED_IPs
+ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.2
+ovn-nbctl --stateless lr-nat-add R1 dnat_and_snat 172.16.1.2 50.0.0.11
+ovn-nbctl --is-applied lr-nat-update-ext-ip R1 dnat_and_snat 172.16.1.2 allowed_range
+ovn-nbctl show R1
+ovn-sbctl dump-flows R1
+
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_out_snat | \
+wc -l`])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | 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 R1 | grep lr_in_unsnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_out_undnat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst == $allowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src == $allowed_range" | wc -l], [0], [1
+])
+
+# Stateful FIP with DISALLOWED_IPs
+ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.2
+ovn-nbctl --stateless lr-nat-add R1 dnat_and_snat 172.16.1.2 50.0.0.11
+ovn-nbctl lr-nat-update-ext-ip R1 dnat_and_snat 172.16.1.2 disallowed_range
+ovn-nbctl show R1
+ovn-sbctl dump-flows R1
+
+OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_out_snat | \
+wc -l`])
+
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_out_snat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst != $disallowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_in_unsnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src != $disallowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_out_undnat | grep "ip4.src == 50.0.0.11" | grep "ip4.dst != $disallowed_range" | wc -l], [0], [1
+])
+AT_CHECK([ovn-sbctl dump-flows R1 | grep lr_in_dnat | grep "ip4.dst == 172.16.1.2" | grep "ip4.src != $disallowed_range" | wc -l], [0], [1
+])
+
+AT_CLEANUP
+
AT_SETUP([ovn -- check Load balancer health check and Service Monitor sync])
AT_SKIP_IF([test $HAVE_PYTHON = no])
ovn_start