From patchwork Fri Nov 1 01:27:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Sharma X-Patchwork-Id: 1187724 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.169.12; helo=mail.linuxfoundation.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.b="V3sbU+Qt"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4744Lt24HHz9sPT for ; Fri, 1 Nov 2019 12:27:49 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 46CE7109A; Fri, 1 Nov 2019 01:27:45 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 41634E8C for ; Fri, 1 Nov 2019 01:27:44 +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 smtp1.linuxfoundation.org (Postfix) with ESMTPS id 4D4DA14D for ; Fri, 1 Nov 2019 01:27:43 +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 xA11PfSM009999 for ; Thu, 31 Oct 2019 18:27:42 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=proofpoint20171006; bh=G/SQqJOB3jWvJjibvZh3Fd0jtskpuAtvNISKfkC8EAo=; b=V3sbU+QtBbIKpxRjm2TByFwuS6mbZWtqT74WS0sdepX2dRjAWHbUC8VCIiWelnX1zWFa 2WF9HesAckRHU7npJhezOMl6ihEHW8ven3V0JXXYKTf3lKjEmMgjIPTUVVL0ks79jf6u v1C2BBBMSpw9qMQ2vSr5JwwCRKXHHKvJhG49u2TFwBziudN13KYnqAotqRJI44AVkxts nG2xToPMcTIIL7i28zazdEomxtyrIgzKhIxzSDc14O7AGAcJVX2GjguOtjs+FQgHrK/s UBENtpOMdZq5iIUbdz5sdFjD7De1Y5bwxrEexlyOuzicrfcW83TnajFtrMDfZgFELyv4 5Q== Received: from nam02-cy1-obe.outbound.protection.outlook.com (mail-cys01nam02lp2056.outbound.protection.outlook.com [104.47.37.56]) by mx0a-002c1b01.pphosted.com with ESMTP id 2vykkw2u0h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 31 Oct 2019 18:27:42 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=P2AjLoZZQMvwQSxd0OBU35Xd7+axOO7p4eEgzHO07mdUELAdgRN7eYXVf4Rm6wdE+9BGl8jrgAO0hOEMqwglZzT+99bPSr5XXuS2tOE2kMq3HiNZxNaEuR4hYnc6YwRd6O1tl+iY0s2PSYHA39B57yR1bsJWX5xhiqk6idsONlbug7p9bUeuMaSCqCYj15VFEuJ3iLb1GnML4AeWspbym7aLnZWWwHYFkqMMWalREnQWMW4iNNdoYD0pHKSfWruRfjIaKgl5SZVoQ06tRrX6swD0eZsl5LbM8ZG9un0dU6etOM24pSkoduzg5ZRVa/bX3k6YrPxlytlEaz0gcjeyuw== 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=G/SQqJOB3jWvJjibvZh3Fd0jtskpuAtvNISKfkC8EAo=; b=fIzu1p8xe6PCi7j5btIihutkPxf/5OpbliS1p/hE+0n7cjxqKscu74qTC0z4GEc3c5Oi8UwqXszx0zAK/UX3hXLlF78vQVLkBqJQ2k5+Cfq0enKo3yvg7O1Y4b2Hfo+0sjBKFP1+HZ+DlwjcaTiukFMiYSXZdFOfLVkH3Qz9NnO4Ng92h9v/fgtC44ppvRZtg3pXPy9k8bzARPKfqVTILihWkpmL8pS9izPY9TpX5cEkVWj1i0DR4obmYc9eI3c00bpJ9DcdYn3WoYjN2HPxIU6wr7DHBVB0+8ajq1u0NvUsVoVcja1hwaKCiQ4fpCunly+gVZclk0sNhrO1vgfOkA== 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 Received: from MW2PR02MB3899.namprd02.prod.outlook.com (52.132.177.158) by MW2PR02MB3721.namprd02.prod.outlook.com (52.132.177.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2387.24; Fri, 1 Nov 2019 01:27:37 +0000 Received: from MW2PR02MB3899.namprd02.prod.outlook.com ([fe80::296f:4dd1:f115:ffe4]) by MW2PR02MB3899.namprd02.prod.outlook.com ([fe80::296f:4dd1:f115:ffe4%7]) with mapi id 15.20.2387.028; Fri, 1 Nov 2019 01:27:37 +0000 From: Ankur Sharma To: "ovs-dev@openvswitch.org" Thread-Topic: [PATCH v4 1/2 ovn] OVN: ADD nbctl cli to mark a dnat_and_snat rule as stateless Thread-Index: AQHVkFOL++zCAwigMk+Yx0Get6aQYw== Date: Fri, 1 Nov 2019 01:27:36 +0000 Message-ID: <1572571718-83139-2-git-send-email-ankur.sharma@nutanix.com> References: <1572571718-83139-1-git-send-email-ankur.sharma@nutanix.com> In-Reply-To: <1572571718-83139-1-git-send-email-ankur.sharma@nutanix.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR21CA0029.namprd21.prod.outlook.com (2603:10b6:a03:114::39) To MW2PR02MB3899.namprd02.prod.outlook.com (2603:10b6:907:3::30) x-ms-exchange-messagesentrepresentingtype: 1 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: 1f21c3e8-cb68-4e11-19af-08d75e6aad8e x-ms-traffictypediagnostic: MW2PR02MB3721: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-proofpoint-crosstenant: true x-ms-oob-tlc-oobclassifiers: OLM:561; x-forefront-prvs: 020877E0CB x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(136003)(376002)(396003)(366004)(346002)(39860400002)(189003)(199004)(25786009)(446003)(256004)(316002)(6916009)(476003)(66574012)(11346002)(2616005)(486006)(14444005)(44832011)(2351001)(102836004)(107886003)(6486002)(6436002)(5640700003)(8936002)(99286004)(36756003)(52116002)(50226002)(7736002)(6506007)(386003)(81166006)(76176011)(66556008)(64756008)(305945005)(66476007)(2501003)(4326008)(6116002)(478600001)(66946007)(66446008)(6512007)(4720700003)(186003)(81156014)(3846002)(8676002)(26005)(2906002)(86362001)(5660300002)(66066001)(71200400001)(71190400001)(14454004)(64030200001); DIR:OUT; SFP:1102; SCL:1; SRVR:MW2PR02MB3721; H:MW2PR02MB3899.namprd02.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nutanix.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: w4FUYp3QS+QYqt5uoQEgiK9modSrhYdEWBA1UxUFeKfysihdKdYhtCf93SqvzTKzdAOf1Kug6Ksr7nOgeZ4Uj4vtet9HrWm03nJFOKmQTBCV2dW/YmttLH4K0UvHW3zV87aY2/TemZd5pgJov2FhvaUOljCCpgY4KH6AMx2mDdN5EQhY3OHUxYtsZCf9PA2nM19BS2o68j/KJulRhfGWWga9VplL1cifRMk758wg5l+PgwAJS/2ZQd2/tzDI+fAWUV+s4jqdXZRolB76KZ5Qda4gLYcbGN51L+LDz95tBsGx3o2coIxzbG03Z+l8zgWmSyfsyj6aH3Pxoctn8puu5R49UVg5B07gVTFgV80KSH99SCcvF47OHZiKDjgDw9gLHtQIQj/DUUUIfvxC0O4FzeJ82vRrgOBBzzuRQWWL8uvNCCoxLeJFnqiza8xpUv2H MIME-Version: 1.0 X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1f21c3e8-cb68-4e11-19af-08d75e6aad8e X-MS-Exchange-CrossTenant-originalarrivaltime: 01 Nov 2019 01:27:36.9198 (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: ZxQ94IhQ6165LnIQJ90yNsVDViO+SrbhCgF5wbslEqTfoHCLU+TLRKppiTX11WWDlEJw0kxa2H2f+EQ/TfM53k3cnR7cExON42nF9JpVfK8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW2PR02MB3721 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.95,1.0.8 definitions=2019-10-31_08:2019-10-30,2019-10-31 signatures=0 X-Proofpoint-Spam-Reason: safe X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 1/2 ovn] OVN: ADD nbctl cli to mark a dnat_and_snat rule as stateless X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Adding ovn-nbctl to mark a dnat_and_snat rule as stateless. This configuration will added to "options" column of NAT table. Signed-off-by: Ankur Sharma --- ovn-nb.ovsschema | 6 ++++-- ovn-nb.xml | 5 +++++ tests/ovn-nbctl.at | 37 +++++++++++++++++++++++++++++++++++++ utilities/ovn-nbctl.8.xml | 12 +++++++++++- utilities/ovn-nbctl.c | 30 +++++++++++++++++++++++++++++- 5 files changed, 86 insertions(+), 4 deletions(-) diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema index 2c87cbb..084305b 100644 --- a/ovn-nb.ovsschema +++ b/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", - "version": "5.16.0", - "cksum": "923459061 23095", + "version": "5.17.0", + "cksum": "1128988054 23237", "tables": { "NB_Global": { "columns": { @@ -345,6 +345,8 @@ "snat", "dnat_and_snat" ]]}}}, + "options": {"type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}, "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, diff --git a/ovn-nb.xml b/ovn-nb.xml index 8990894..d8f3237 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -2297,6 +2297,11 @@

+ + Indicates if a dnat_and_snat rule should lead to connection + tracking state or not. + + See External IDs at the beginning of this document. diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index 43a980b..2679f1f 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -533,6 +533,39 @@ snat 30.0.0.1 192.168.1.0/24 snat fd01::1 fd11::/64 ]) +AT_CHECK([ovn-nbctl --bare --columns=options list nat | grep stateless=true| wc -l], [0], +[0 +]) +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat_and_snat 40.0.0.2 192.168.1.4]) +AT_CHECK([ovn-nbctl --bare --columns=options list nat | grep stateless=true| wc -l], [0], +[1 +]) + +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat_and_snat fd21::1 fd11::2]) +AT_CHECK([ovn-nbctl --bare --columns=options list nat | grep stateless=true| wc -l], [0], +[2 +]) + +AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat fd21::1]) + +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat 40.0.0.2 192.168.1.4], [1], [], +[ovn-nbctl: stateless is not applicable to dnat or snat types +]) +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 snat 40.0.0.2 192.168.1.4], [1], [], +[ovn-nbctl: stateless is not applicable to dnat or snat types +]) +AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 40.0.0.2 192.168.1.5], [1], [], +[ovn-nbctl: 40.0.0.2, 192.168.1.5: External ip cannot be shared across stateless and stateful NATs +]) +AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 40.0.0.2 192.168.1.5], [1], [], +[ovn-nbctl: 40.0.0.2, 192.168.1.5: External ip cannot be shared across stateless and stateful NATs +]) + +AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 40.0.0.3 192.168.1.6]) +AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat_and_snat 40.0.0.3 192.168.1.7], [1], [], +[ovn-nbctl: 40.0.0.3, 192.168.1.7: External ip cannot be shared across stateless and stateful NATs +]) + dnl Deletes the NATs AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat 30.0.0.3], [1], [], [ovn-nbctl: no matching NAT with the type (dnat_and_snat) and external_ip (30.0.0.3) @@ -552,8 +585,10 @@ TYPE EXTERNAL_IP LOGICAL_IP EXTERNAL_MAC L dnat 30.0.0.1 192.168.1.2 dnat fd01::1 fd11::2 dnat_and_snat 30.0.0.2 192.168.1.3 +dnat_and_snat 40.0.0.2 192.168.1.4 dnat_and_snat fd01::2 fd11::3 snat 30.0.0.1 192.168.1.0/24 +snat 40.0.0.3 192.168.1.6 snat fd01::1 fd11::/64 ]) @@ -561,8 +596,10 @@ AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl TYPE EXTERNAL_IP LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT dnat_and_snat 30.0.0.2 192.168.1.3 +dnat_and_snat 40.0.0.2 192.168.1.4 dnat_and_snat fd01::2 fd11::3 snat 30.0.0.1 192.168.1.0/24 +snat 40.0.0.3 192.168.1.6 snat fd01::1 fd11::/64 ]) diff --git a/utilities/ovn-nbctl.8.xml b/utilities/ovn-nbctl.8.xml index b207dac..88ebd13 100644 --- a/utilities/ovn-nbctl.8.xml +++ b/utilities/ovn-nbctl.8.xml @@ -665,7 +665,7 @@

NAT Commands

-
[--may-exist] lr-nat-add router type external_ip logical_ip [logical_port external_mac]
+
[--may-exist] [--stateless]lr-nat-add router type external_ip logical_ip [logical_port external_mac]

Adds the specified NAT to router. @@ -681,8 +681,18 @@ The logical_port is the name of an existing logical switch port where the logical_ip resides. The external_mac is an Ethernet address. + The --stateless

+ When --stateless is specified then it implies that + we will be not use connection tracker, i.e internal ip and external + ip are 1:1 mapped. This implies that --stateless is + applicable only to dnat_and_snat type NAT rules. + An external ip with --stateless NAT cannot be shared + with any other NAT rule. +

+ +

When type is dnat, the externally visible IP address external_ip is DNATted to the IP address logical_ip in the logical space. diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index 9225f17..8188948 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -694,6 +694,7 @@ Policy commands:\n\ lr-policy-list ROUTER print policies for ROUTER\n\ \n\ NAT commands:\n\ + [--stateless]\n\ lr-nat-add ROUTER TYPE EXTERNAL_IP LOGICAL_IP [LOGICAL_PORT EXTERNAL_MAC]\n\ add a NAT to ROUTER\n\ lr-nat-del ROUTER [TYPE [IP]]\n\ @@ -3954,6 +3955,13 @@ nbctl_lr_nat_add(struct ctl_context *ctx) } bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; + bool stateless = shash_find(&ctx->options, "--stateless") != NULL; + + if (strcmp(nat_type, "dnat_and_snat") && stateless) { + ctl_error(ctx, "stateless is not applicable to dnat or snat types"); + return; + } + int is_snat = !strcmp("snat", nat_type); for (size_t i = 0; i < lr->n_nat; i++) { const struct nbrec_nat *nat = lr->nat[i]; @@ -3985,10 +3993,25 @@ nbctl_lr_nat_add(struct ctl_context *ctx) return; } } + + } + if (!strcmp(nat_type, "dnat_and_snat") || + !strcmp(nat->type, "dnat_and_snat")) { + + if (!strcmp(nat->external_ip, external_ip)) { + struct smap nat_options = SMAP_INITIALIZER(&nat_options); + if (!strcmp(smap_get(&nat->options, "stateless"), + "true") || stateless) { + ctl_error(ctx, "%s, %s: External ip cannot be shared " + "across stateless and stateful NATs", + external_ip, new_logical_ip); + } + } } } /* Create the NAT. */ + struct smap nat_options = SMAP_INITIALIZER(&nat_options); struct nbrec_nat *nat = nbrec_nat_insert(ctx->txn); nbrec_nat_set_type(nat, nat_type); nbrec_nat_set_external_ip(nat, external_ip); @@ -3997,7 +4020,12 @@ nbctl_lr_nat_add(struct ctl_context *ctx) nbrec_nat_set_logical_port(nat, logical_port); nbrec_nat_set_external_mac(nat, external_mac); } + + smap_add(&nat_options, "stateless", stateless ? "true":"false"); + nbrec_nat_set_options(nat, &nat_options); + free(new_logical_ip); + smap_destroy(&nat_options); /* Insert the NAT into the logical router. */ nbrec_logical_router_verify_nat(lr); @@ -5717,7 +5745,7 @@ static const struct ctl_command_syntax nbctl_commands[] = { /* NAT commands. */ { "lr-nat-add", 4, 6, "ROUTER TYPE EXTERNAL_IP LOGICAL_IP [LOGICAL_PORT EXTERNAL_MAC]", NULL, - nbctl_lr_nat_add, NULL, "--may-exist", RW }, + nbctl_lr_nat_add, NULL, "--may-exist,--stateless", RW }, { "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 }, From patchwork Fri Nov 1 01:27:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Sharma X-Patchwork-Id: 1187726 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.169.12; helo=mail.linuxfoundation.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.b="nsU1zkIm"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4744Mz129fz9sPF for ; Fri, 1 Nov 2019 12:28:47 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id BED3C10B7; Fri, 1 Nov 2019 01:27:52 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 2B48F10B6 for ; Fri, 1 Nov 2019 01:27:52 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3D09DA3 for ; Fri, 1 Nov 2019 01:27:43 +0000 (UTC) Received: from pps.filterd (m0127844.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id xA11PIHr031603 for ; Thu, 31 Oct 2019 18:27:42 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=proofpoint20171006; bh=8WSyVyxBQbOGX/znKH3gVk7ks5KF5layq7cTb2t20PE=; b=nsU1zkIm8OsxAjiP0zlv+EPzdbj2xyljtTEZKYv+Wv09vNL1G0KhUOh5hEvJr20xfKbS +5N5V0KkVbv8TLOq0Ue0BcndMx0zfGA1NjCbLwfknrNAuq2D8xwk54y6tBT7f4MzjE7x vHM7O61Ga/YyN5ep5Evi8fXsqW6oAFbXL49abA6+Ei30CGQtjZaZsEGT2Fbrm8EsnQfy h9thiHAkuMi3h3Q7E7wTA9DSNJo6jU/txvSDtMx8H+QtvrR6SJUspuqKMLRnUtBDvkmm 5paw76KDwJuvK6yrg4d5ZkN/K35/sdunwUrswPZLC7kPpbbh+tjVHKjbDjEkah+dj7Fw hA== Received: from nam01-sn1-obe.outbound.protection.outlook.com (mail-sn1nam01lp2053.outbound.protection.outlook.com [104.47.32.53]) by mx0b-002c1b01.pphosted.com with ESMTP id 2vykku2u4n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 31 Oct 2019 18:27:41 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=M8NnT4wADl3ZEAjaEbdl7TTDNPmLa3tYDgE+SrqmWBZ0h4Jl/82EL2kxAK90HSMKK7zdnVwzx3WZzTbmCzaPbxe8gnSbB21tvoE3oAkE9dbZQaOnAoTCleNSdUY+WwMvi/Z5uxrHzz36LujEDS/vQhAKzLoA6QZsgsBQLbpcfhFFWkC5HH8q34vJnscGLFQsrnMxHTuphQAfUkYRJ59oWAdtCd88lC66Rcw2YtkgmLIALH5hJJ5CkvqU0C9HO8kT+6GLTnozjGKofli2q0a8e+lp9B/pPh4CPotTvZhzqHs+dAEEWpC0yHQvaJnMW7ePoGhifZVtgDYhnMiGSyIDPg== 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=8WSyVyxBQbOGX/znKH3gVk7ks5KF5layq7cTb2t20PE=; b=DwBWEGTprNVy4GSNbCniNr+vrkmgMS98EkZFfmLSYBnuZkB9F7EYg+tfaVtQsKdtnHLdvRd2aYvIn18OQDLRb6e5KT4Y331GPDxQrdSqKL/X1HVFhBHxdqHsoVDzDQO1aZUbXX5XRn4uiNpVcmxtQ+klCa0S8lBcCZ6Eb86Bq0cF4v+AgUF2x6Gw1hn9DnR+DcFVmuUHA+Yb74rx9/bcsic1KRaSvZTQBJdS8JL5b2ygL881gET3warlHNyhAFB8svRj0Gq7QfbTJpVHeTGcOHx80Ll/Zud2gUvMPj0zYtSA2BvcOr3/C4xDy5aVAljYWD7PnX08l3l5e7JitBkLBA== 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 Received: from MW2PR02MB3899.namprd02.prod.outlook.com (52.132.177.158) by MW2PR02MB3706.namprd02.prod.outlook.com (52.132.177.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2387.24; Fri, 1 Nov 2019 01:27:40 +0000 Received: from MW2PR02MB3899.namprd02.prod.outlook.com ([fe80::296f:4dd1:f115:ffe4]) by MW2PR02MB3899.namprd02.prod.outlook.com ([fe80::296f:4dd1:f115:ffe4%7]) with mapi id 15.20.2387.028; Fri, 1 Nov 2019 01:27:40 +0000 From: Ankur Sharma To: "ovs-dev@openvswitch.org" Thread-Topic: [PATCH v4 2/2 ovn] OVN: Use ip4.src and ip4.dst actions for NAT rules Thread-Index: AQHVkFOM6RprKK12NUO/gdq+eyzOYA== Date: Fri, 1 Nov 2019 01:27:39 +0000 Message-ID: <1572571718-83139-3-git-send-email-ankur.sharma@nutanix.com> References: <1572571718-83139-1-git-send-email-ankur.sharma@nutanix.com> In-Reply-To: <1572571718-83139-1-git-send-email-ankur.sharma@nutanix.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR21CA0029.namprd21.prod.outlook.com (2603:10b6:a03:114::39) To MW2PR02MB3899.namprd02.prod.outlook.com (2603:10b6:907:3::30) x-ms-exchange-messagesentrepresentingtype: 1 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: af64daee-004f-4e92-73ee-08d75e6aaeed x-ms-traffictypediagnostic: MW2PR02MB3706: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-proofpoint-crosstenant: true x-ms-oob-tlc-oobclassifiers: OLM:326; x-forefront-prvs: 020877E0CB x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(396003)(366004)(39860400002)(376002)(346002)(136003)(189003)(199004)(52116002)(5024004)(107886003)(4720700003)(4326008)(25786009)(8936002)(316002)(14444005)(256004)(102836004)(8676002)(2501003)(6916009)(30864003)(7736002)(305945005)(99286004)(2906002)(6512007)(6486002)(26005)(81156014)(50226002)(81166006)(76176011)(66574012)(86362001)(3846002)(386003)(6116002)(66066001)(446003)(5640700003)(5660300002)(478600001)(486006)(11346002)(2351001)(64756008)(66446008)(476003)(36756003)(2616005)(66476007)(66556008)(71200400001)(66946007)(71190400001)(6436002)(44832011)(14454004)(186003)(6506007)(64030200001)(579004)(559001); DIR:OUT; SFP:1102; SCL:1; SRVR:MW2PR02MB3706; H:MW2PR02MB3899.namprd02.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nutanix.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: NlmGaYPUZPIUEu3B6QEALaq2rnYpGWSLL46Bx1VoLjkWa55N4u/8FNuKnFPjP85pik2yFuaZatRO6G3Mxasvva9Nav4kXGTSC/GNc48V+EPuawpKSjRNBJayj1BPXSH/T6++b8xX5QswYbvq4CnMoTnxaOCZ6VmglttfPrpFDj7KxfPhMfrGpb5dljhS70f/3C2xsktq8A+/Kj7U03ttoUG9/BgRy4Mr+75SfJl6Co/j+fGvN20+4Y621lWa14RWXTwZjXQPPWwfaHx9dKsg1ix3HwGaHohDcHZySIQJpWFRs4bYu+6AzzMihzt3Vb19w73Fw39hPov9u5bXI2Bp6Z2oekwEPhp/QCMbJ2+TrajoyCsZ/WPrkhZMr2d2HfS6Ge3Vjau46Yw/arsOWbVmcnjNwH8ChLU3DuuTSmJYpPJqkn8GeaaPloe4hd7RvQSo MIME-Version: 1.0 X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: af64daee-004f-4e92-73ee-08d75e6aaeed X-MS-Exchange-CrossTenant-originalarrivaltime: 01 Nov 2019 01:27:39.2045 (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: +Z1PH80rs1+yo29abolQuqZM0LVLpLvyhhR+DCmQwdyovi1dONGr6LF8bLpHvtx4sw/FLdWb4PvzaNvh7ruT6M4GCGbZY2EZDcXEcsD9MVY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW2PR02MB3706 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.95,1.0.8 definitions=2019-10-31_08:2019-10-30,2019-10-31 signatures=0 X-Proofpoint-Spam-Reason: safe X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4 2/2 ovn] OVN: Use ip4.src and ip4.dst actions for NAT rules X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org For dnat_and_snat rules which are meant to be stateless instead of using ct_snat/dnat OVN actions, we will use ip4.src/ip4.dst. This actions will do 1:1 mapping to inner ip to external ip, while recalculating the checksums. Signed-off-by: Ankur Sharma --- northd/ovn-northd.8.xml | 33 ++++- northd/ovn-northd.c | 84 +++++++++++-- tests/ovn-northd.at | 95 +++++++++++++++ tests/ovn.at | 311 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 508 insertions(+), 15 deletions(-) diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index f6cafbd..0a33dcd 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -1826,7 +1826,10 @@ icmp6 { B, a priority-90 flow matches ip && ip4.dst == B or ip && ip6.dst == B - with an action ct_snat; . + 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).

@@ -1848,7 +1851,10 @@ icmp6 { ip && ip6.dst == B && inport == GW where GW is the logical router gateway port, with an - action ct_snat;. + 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).

@@ -1976,7 +1982,10 @@ icmp6 { Gateway router is configured to force SNAT any DNATed packet, the above action will be replaced by flags.force_snat_for_dnat = 1; flags.loopback = 1; - ct_dnat(B);. + ct_dnat(B);. 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).

  • @@ -2010,6 +2019,9 @@ icmp6 { where GW is the logical router gateway port, with an action ct_dnat(B);. The match will include ip6.dst == B in the IPv6 case. + 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).

    @@ -2684,7 +2696,10 @@ nd_ns { matches ip && ip4.src == B && outport == GW, where GW is the logical router gateway port, with an action - ct_dnat;. + ct_dnat;. 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).

    @@ -2742,7 +2757,10 @@ nd_ns { ip && ip4.src == A 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. + 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).

    A priority-0 logical flow with match 1 has actions @@ -2765,7 +2783,10 @@ nd_ns { 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. + 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).

    diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 71ee0b6..c23c270 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -6567,6 +6567,18 @@ copy_ra_to_sb(struct ovn_port *op, const char *address_mode) smap_destroy(&options); } +static inline bool +lrouter_nat_is_stateless(const struct nbrec_nat *nat) +{ + const char *stateless = smap_get(&nat->options, "stateless"); + + if (stateless && !strcmp(stateless, "true")) { + return true; + } + + return false; +} + static void build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, struct hmap *lflows, struct shash *meter_groups) @@ -7414,6 +7426,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ovs_be32 ip, mask; struct in6_addr ipv6, mask_v6, v6_exact = IN6ADDR_EXACT_INIT; bool is_v6 = false; + bool stateless = lrouter_nat_is_stateless(nat); char *error = ip_parse_masked(nat->external_ip, &ip, &mask); if (error || mask != OVS_BE32_MAX) { @@ -7497,16 +7510,25 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, if (!od->l3dgw_port) { /* Gateway router. */ ds_clear(&match); + ds_clear(&actions); ds_put_format(&match, "ip && ip%s.dst == %s", is_v6 ? "6" : "4", nat->external_ip); + if (!strcmp(nat->type, "dnat_and_snat") && stateless) { + ds_put_format(&actions, "ip%s.dst=%s; next;", + is_v6 ? "6" : "4", nat->logical_ip); + } else { + ds_put_cstr(&actions, "ct_snat;"); + } + ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 90, - ds_cstr(&match), "ct_snat;"); + ds_cstr(&match), ds_cstr(&actions)); } else { /* Distributed router. */ /* 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", @@ -7518,8 +7540,16 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_put_format(&match, " && is_chassis_resident(%s)", od->l3redirect_port->json_key); } + + if (!strcmp(nat->type, "dnat_and_snat") && stateless) { + ds_put_format(&actions, "ip%s.dst=%s; next;", + is_v6 ? "6" : "4", nat->logical_ip); + } else { + ds_put_cstr(&actions, "ct_snat;"); + } + ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 100, - ds_cstr(&match), "ct_snat;"); + ds_cstr(&match), ds_cstr(&actions)); /* Traffic received on other router ports must be * redirected to the central instance of the l3dgw_port @@ -7556,8 +7586,16 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_put_format(&actions, "flags.force_snat_for_dnat = 1; "); } - ds_put_format(&actions, "flags.loopback = 1; ct_dnat(%s);", - nat->logical_ip); + + if (!strcmp(nat->type, "dnat_and_snat") && stateless) { + ds_put_format(&actions, "flags.loopback = 1; " + "ip%s.dst=%s; next;", + is_v6 ? "6" : "4", nat->logical_ip); + } else { + ds_put_format(&actions, "flags.loopback = 1; " + "ct_dnat(%s);", nat->logical_ip); + } + ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 100, ds_cstr(&match), ds_cstr(&actions)); } else { @@ -7577,8 +7615,15 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, od->l3redirect_port->json_key); } ds_clear(&actions); - ds_put_format(&actions, "ct_dnat(%s);", - nat->logical_ip); + + if (!strcmp(nat->type, "dnat_and_snat") && stateless) { + 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); + } + ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 100, ds_cstr(&match), ds_cstr(&actions)); @@ -7622,7 +7667,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_put_format(&actions, "eth.src = "ETH_ADDR_FMT"; ", ETH_ADDR_ARGS(mac)); } - ds_put_format(&actions, "ct_dnat;"); + + if (!strcmp(nat->type, "dnat_and_snat") && stateless) { + ds_put_format(&actions, "ip%s.src=%s; next;", + is_v6 ? "6" : "4", nat->external_ip); + } else { + ds_put_format(&actions, "ct_dnat;"); + } + ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 100, ds_cstr(&match), ds_cstr(&actions)); } @@ -7639,7 +7691,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, is_v6 ? "6" : "4", nat->logical_ip); ds_clear(&actions); - ds_put_format(&actions, "ct_snat(%s);", nat->external_ip); + + if (!strcmp(nat->type, "dnat_and_snat") && stateless) { + ds_put_format(&actions, "ip%s.src=%s; next;", + is_v6 ? "6" : "4", nat->external_ip); + } else { + ds_put_format(&actions, "ct_snat(%s);", + nat->external_ip); + } /* The priority here is calculated such that the * nat->logical_ip with the longest mask gets a higher @@ -7669,7 +7728,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_put_format(&actions, "eth.src = "ETH_ADDR_FMT"; ", ETH_ADDR_ARGS(mac)); } - ds_put_format(&actions, "ct_snat(%s);", nat->external_ip); + + if (!strcmp(nat->type, "dnat_and_snat") && stateless) { + ds_put_format(&actions, "ip%s.src=%s; next;", + is_v6 ? "6" : "4", nat->external_ip); + } else { + ds_put_format(&actions, "ct_snat(%s);", + nat->external_ip); + } /* The priority here is calculated such that the * nat->logical_ip with the longest mask gets a higher diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 42033d5..989ed4f 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -966,3 +966,98 @@ OVS_WAIT_UNTIL([ovn-sbctl get Port_Binding ${uuid} options:redirect-type], [0], ]) AT_CLEANUP + +AT_SETUP([ovn -- check stateless dnat_and_snat rule]) +AT_SKIP_IF([test $HAVE_PYTHON = no]) +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 + +# IPV4 +ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11 + +OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \ +wc -l`]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [2 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [2 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.dst=| wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.src=| wc -l], [0], [0 +]) + +ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 + +ovn-nbctl --stateless lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11 +OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \ +wc -l`]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.dst=| wc -l], [0], [2 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.src=| wc -l], [0], [2 +]) +ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 + +# IPV6 +ovn-nbctl lr-nat-add R1 dnat_and_snat fd01::1 fd11::2 + +OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \ +wc -l`]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [2 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [2 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.dst=| wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.src=| wc -l], [0], [0 +]) + +ovn-nbctl lr-nat-del R1 dnat_and_snat fd01::1 +ovn-nbctl --stateless lr-nat-add R1 dnat_and_snat fd01::1 fd11::2 + +OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \ +wc -l`]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.dst=| wc -l], [0], [2 +]) + +AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.src=| wc -l], [0], [2 +]) + +AT_CLEANUP diff --git a/tests/ovn.at b/tests/ovn.at index d78689d..410f4b5 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -16365,3 +16365,314 @@ grep 101 | wc -l`]) OVN_CLEANUP([hv1]) AT_CLEANUP + +AT_SETUP([ovn -- Stateless Floating IP]) +ovn_start + +# In this test cases we create 3 switches, all connected to same +# physical network (through br-phys on each HV). LS1 and LS2 have +# 1 VIF each. Each HV has 1 VIF port. The first digit +# of VIF port name indicates the hypervisor it is bound to, e.g. +# lp23 means VIF 3 on hv2. +# +# All the switches are connected to a logical router "router". +# +# There is an external logical switch, ls-north. +# This test validates the stateless floating ip implementation. +# +# Each switch's VLAN tag and their logical switch ports are: +# - ls1: +# - tagged with VLAN 101 +# - ports: lp11 +# - ls2: +# - tagged with VLAN 201 +# - ports: lp22 +# - ls-north: +# - tagged with VLAN 1000 +# Note: a localnet port is created for each switch to connect to +# physical network. + +for i in 1 2; do + ls_name=ls$i + ovn-nbctl ls-add $ls_name + ln_port_name=ln$i + if test $i -eq 1; then + ovn-nbctl lsp-add $ls_name $ln_port_name "" 101 + elif test $i -eq 2; then + ovn-nbctl lsp-add $ls_name $ln_port_name "" 201 + fi + ovn-nbctl lsp-set-addresses $ln_port_name unknown + ovn-nbctl lsp-set-type $ln_port_name localnet + ovn-nbctl lsp-set-options $ln_port_name network_name=phys +done + +# lsp_to_ls LSP +# +# Prints the name of the logical switch that contains LSP. +lsp_to_ls () { + case $1 in dnl ( + lp?[[11]]) echo ls1 ;; dnl ( + lp?[[12]]) echo ls2 ;; dnl ( + *) AT_FAIL_IF([:]) ;; + esac +} + +vif_to_hv () { + case $1 in dnl ( + vif[[1]]?) echo hv1 ;; dnl ( + vif[[2]]?) echo hv2 ;; dnl ( + vif?[[north]]?) echo hv4 ;; dnl ( + *) AT_FAIL_IF([:]) ;; + esac +} + +ip_to_hex() { + printf "%02x%02x%02x%02x" "$@" +} + +net_add n1 +for i in 1 2; do + sim_add hv$i + as hv$i + ovs-vsctl add-br br-phys + ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys + ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i" + ovn_attach n1 br-phys 192.168.0.$i + + ovs-vsctl add-port br-int vif$i$i -- \ + set Interface vif$i$i external-ids:iface-id=lp$i$i \ + options:tx_pcap=hv$i/vif$i$i-tx.pcap \ + options:rxq_pcap=hv$i/vif$i$i-rx.pcap \ + ofport-request=$i$i + + lsp_name=lp$i$i + ls_name=$(lsp_to_ls $lsp_name) + + ovn-nbctl lsp-add $ls_name $lsp_name + ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i" + ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i + + OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup]) + +done + +ovn-nbctl ls-add ls-underlay +ovn-nbctl lsp-add ls-underlay ln3 "" 1000 +ovn-nbctl lsp-set-addresses ln3 unknown +ovn-nbctl lsp-set-type ln3 localnet +ovn-nbctl lsp-set-options ln3 network_name=phys + +ovn-nbctl ls-add ls-north +ovn-nbctl lsp-add ls-north ln4 "" 1000 +ovn-nbctl lsp-set-addresses ln4 unknown +ovn-nbctl lsp-set-type ln4 localnet +ovn-nbctl lsp-set-options ln4 network_name=phys + +# Add a VM on ls-north +ovn-nbctl lsp-add ls-north lp-north +ovn-nbctl lsp-set-addresses lp-north "f0:f0:00:00:00:11 172.31.0.10" +ovn-nbctl lsp-set-port-security lp-north f0:f0:00:00:00:11 + +# Add 3rd hypervisor +sim_add hv3 +as hv3 ovs-vsctl add-br br-phys +as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys +as hv3 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:33" +as hv3 ovn_attach n1 br-phys 192.168.0.3 + +# Add 4th hypervisor +sim_add hv4 +as hv4 ovs-vsctl add-br br-phys +as hv4 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys +as hv4 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:44" +as hv4 ovn_attach n1 br-phys 192.168.0.4 + +as hv4 ovs-vsctl add-port br-int vif-north -- \ + set Interface vif-north external-ids:iface-id=lp-north \ + options:tx_pcap=hv4/vif-north-tx.pcap \ + options:rxq_pcap=hv4/vif-north-rx.pcap \ + ofport-request=44 + +ovn-nbctl lr-add router +ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24 +ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24 +ovn-nbctl lrp-add router router-to-underlay 00:00:01:01:02:07 172.31.0.1/24 + +ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router \ + options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router +ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router \ + options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router +ovn-nbctl lsp-add ls-underlay underlay-to-router -- set Logical_Switch_Port \ + underlay-to-router type=router \ + options:router-port=router-to-underlay \ + -- lsp-set-addresses underlay-to-router router + +ovn-nbctl lrp-set-gateway-chassis router-to-underlay hv3 +ovn-nbctl --stateless lr-nat-add router dnat_and_snat 172.31.0.100 192.168.1.1 +ovn-nbctl lrp-set-redirect-type router-to-underlay bridged + +ovn-nbctl --wait=sb sync + + +OVN_POPULATE_ARP + +# lsp_to_ls LSP +# +# Prints the name of the logical switch that contains LSP. +lsp_to_ls () { + case $1 in dnl ( + lp?[[11]]) echo ls1 ;; dnl ( + lp?[[12]]) echo ls2 ;; dnl ( + *) AT_FAIL_IF([:]) ;; + esac +} + +vif_to_ls () { + case $1 in dnl ( + vif?[[11]]) echo ls1 ;; dnl ( + vif?[[12]]) echo ls2 ;; dnl ( + vif-north) echo ls-north ;; dnl ( + *) AT_FAIL_IF([:]) ;; + esac +} + +hv_to_num () { + case $1 in dnl ( + hv1) echo 1 ;; dnl ( + hv2) echo 2 ;; dnl ( + hv3) echo 3 ;; dnl ( + hv4) echo 4 ;; dnl ( + *) AT_FAIL_IF([:]) ;; + esac +} + +vif_to_num () { + case $1 in dnl ( + vif22) echo 22 ;; dnl ( + vif21) echo 21 ;; dnl ( + vif11) echo 11 ;; dnl ( + *) AT_FAIL_IF([:]) ;; + esac +} + +vif_to_hv () { + case $1 in dnl ( + vif[[1]]?) echo hv1 ;; dnl ( + vif[[2]]?) echo hv2 ;; dnl ( + vif-north) echo hv4 ;; dnl ( + *) AT_FAIL_IF([:]) ;; + esac +} + +vif_to_lrp () { + echo router-to-`vif_to_ls $1` +} + +ip_to_hex() { + printf "%02x%02x%02x%02x" "$@" +} + + +test_ip() { + # This packet has bad checksums but logical L3 routing doesn't check. + local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 outport=$6 + local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000 + shift; shift; shift; shift; shift + hv=`vif_to_hv $inport` + as $hv ovs-appctl netdev-dummy/receive $inport $packet + in_ls=`vif_to_ls $inport` + for outport; do + out_ls=`vif_to_ls $outport` + if test $in_ls = $out_ls; then + # Ports on the same logical switch receive exactly the same packet. + echo $packet + else + # Routing decrements TTL and updates source and dest MAC + # (and checksum). + out_lrp=`vif_to_lrp $outport` + # For North-South, packet will come via gateway chassis, i.e hv3 + if test $inport = vif-north; then + echo f0000000001100000101020308004500001c000000003f110100${src_ip}${dst_ip}0035111100080000 >> $outport.expected + fi + if test $outport = vif-north; then + echo f0f00000001100000101020708004500001c000000003e111726ac1f0064${dst_ip}0035111100080000 >> $outport.expected + fi + fi >> $outport.expected + done +} + +# Dump a bunch of info helpful for debugging if there's a failure. + +echo "------ OVN dump ------" +ovn-nbctl show +ovn-nbctl lr-nat-list router +ovn-sbctl show +ovn-sbctl list port_binding +ovn-sbctl list mac_binding +ovn-sbctl dump-flows + +echo "------ hv1 dump ------" +as hv1 ovs-vsctl show +as hv1 ovs-vsctl list Open_Vswitch + +echo "------ hv2 dump ------" +as hv2 ovs-vsctl show +as hv2 ovs-vsctl list Open_Vswitch + +echo "------ hv3 dump ------" +as hv3 ovs-vsctl show +as hv3 ovs-vsctl list Open_Vswitch + +echo "------ hv4 dump ------" +as hv4 ovs-vsctl show +as hv4 ovs-vsctl list Open_Vswitch + +echo "Send traffic South to Nouth" +sip=`ip_to_hex 192 168 1 1` +dip=`ip_to_hex 172 31 0 10` +test_ip vif11 f00000000011 000001010203 $sip $dip vif-north + +# Confirm that South to North traffic works fine. +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected]) + +# Confirm that NATing happened without connection tracker + +AT_CHECK([ovn-sbctl dump-flows router | grep ct_snat | wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows router | grep ct_dnat | wc -l], [0], [0 +]) + +AT_CHECK([ovn-sbctl dump-flows router | grep ip4.dst=| wc -l], [0], [2 +]) + +AT_CHECK([ovn-sbctl dump-flows router | grep ip4.src=| wc -l], [0], [2 +]) + +echo "----------- Post Traffic hv1 dump -----------" +as hv1 ovs-ofctl dump-flows br-int +as hv1 ovs-ofctl show br-phys +as hv1 ovs-appctl fdb/show br-phys +as hv1 ovs-dpctl dump-flows + +echo "----------- Post Traffic hv2 dump -----------" +as hv2 ovs-ofctl dump-flows br-int +as hv2 ovs-ofctl show br-phys +as hv2 ovs-appctl fdb/show br-phys + +echo "----------- Post Traffic hv3 dump -----------" +as hv3 ovs-ofctl dump-flows br-int +as hv3 ovs-ofctl show br-phys +as hv3 ovs-appctl dpctl/dump-conntrack +as hv3 ovs-appctl fdb/show br-phys +as hv3 ovs-dpctl dump-flows +as hv3 ovs-ofctl dump-flows br-int + +echo "----------- Post Traffic hv4 dump -----------" +as hv4 ovs-ofctl dump-flows br-int +as hv4 ovs-ofctl show br-phys +as hv4 ovs-appctl fdb/show br-phys + +OVN_CLEANUP([hv1],[hv2],[hv3],[hv4]) + +AT_CLEANUP