From patchwork Sun Jun 14 02:52:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Sharma X-Patchwork-Id: 1308792 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.133; helo=hemlock.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=yYmGSRkp; dkim-atps=neutral Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49kzWH1DMvz9sQx for ; Sun, 14 Jun 2020 12:51:36 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 6158B88866; Sun, 14 Jun 2020 02:51:34 +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 k2NlklnPbW8z; Sun, 14 Jun 2020 02:51:32 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id 8400188256; Sun, 14 Jun 2020 02:51:32 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6364DC0888; Sun, 14 Jun 2020 02:51:32 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7E71EC016F for ; Sun, 14 Jun 2020 02:51:31 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 733EF86D6E for ; Sun, 14 Jun 2020 02:51:31 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nj86aBruCr00 for ; Sun, 14 Jun 2020 02:51:30 +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 fraxinus.osuosl.org (Postfix) with ESMTPS id 0F53186D65 for ; Sun, 14 Jun 2020 02:51:29 +0000 (UTC) Received: from pps.filterd (m0127837.ppops.net [127.0.0.1]) by mx0a-002c1b01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 05E2n8Y4030996 for ; Sat, 13 Jun 2020 19:51:28 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; h=from : to : cc : subject : date : message-id : content-type : mime-version; s=proofpoint20171006; bh=yVbpg65EMcc61i8SZMuwD4Vx8JghBDuORit9AC8lKog=; b=yYmGSRkpJ/qerv4b/m84a2NkrFAg9VIBpVeWi0pwl3ZF7PuEZ6CVEFRUR0kIxwigRz3i pCXQbIQDsOmNH05ZV0L/bjc4bUTHPurHwBfrP96sdrHebmVV1fuPnI22IG0L0a3nC1ct qlj0E2+EI+4lGpeIP6CdOAg+u2gU+LlQl1EESMS3XSkEXIrUtIQ9dAKYkwhRicLMjQ2/ +sOhkec/S27qo+Z10N/MTIapznfJuW46o9vn3VtbvvGsrp+1gpzNnLm14fnJy5hkX2XI DrKdZQxerzyrcxu1xtg6snMMmZS2WIyeJIj42W6VbojfZmA5JJX1LskW7jkj/reYI4WI Ug== Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2177.outbound.protection.outlook.com [104.47.55.177]) by mx0a-002c1b01.pphosted.com with ESMTP id 31mtqa9455-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Sat, 13 Jun 2020 19:51:28 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ToEQc+XNwenFfzuSigx34iAS8JhEvsmnq9pIC8WjPyrY90LVnPKQzs7ifW11USgGeSxH+K5dv2sH+2JxGSfDZAQc59ajQth36gnexkNB36OXgQ5S1fmUsYxKwfVjsRg3TqaxzfxA1GdsoQQLXQKw/10NiyhKws6jtVWjkuwYEmVEYkDklpcIZ3It2KXU5USRJG5qAuK4gzxpAf2IEc4UyBZX4ZG+2T+Qfh3OTSxnK7rJxPK5avqOXnTMHWvzu4koHKWjiWguxxBch6Sns6dVHJHOrIOIxjBXlJAVyug0BdKo3JxFZgXwZTE14lR2PgrmzJsnkdfJpmc7jm2/19i5sQ== 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=yVbpg65EMcc61i8SZMuwD4Vx8JghBDuORit9AC8lKog=; b=bPuyPDn/sRDAlbT4qCAVPjx1Hlh6ot4M2anfy4KfNB2JTYKWWhkGfZWeQbeYy4GSXmpIW73L25HLXBRnmk+h1e6oLK8xUkUEAvUmwdjrQWiUlt0bk4utMkjChKkHjxkgyvVAB+PMLk51BHh8UU0PzqQWVsnm5C20mAcBAXHKbaH16cceomVBCyetrdiYviF3ZrOsuq8EgB+3aHMGSrXVzorS2rm1SgXtV13UzGQ5IJApUcoV9i5zPjleRonZdONBZgvmtPlM3skInW7KOdkDpi/st0A2tq5x9popgtrg3WC694zVlcofKdRQB+EYNsh4paLpVZPAPem3p5xFiMzGxQ== 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 MN2PR02MB6767.namprd02.prod.outlook.com (2603:10b6:208:1d2::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3088.19; Sun, 14 Jun 2020 02:51:25 +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.3088.026; Sun, 14 Jun 2020 02:51:25 +0000 From: Ankur Sharma To: ovs-dev@openvswitch.org Date: Sat, 13 Jun 2020 19:52:27 -0700 Message-Id: <1592103148-53641-1-git-send-email-svc.mail.git@nutanix.com> X-Mailer: git-send-email 1.8.3.1 X-ClientProxiedBy: BYAPR07CA0048.namprd07.prod.outlook.com (2603:10b6:a03:60::25) 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 BYAPR07CA0048.namprd07.prod.outlook.com (2603:10b6:a03:60::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3088.18 via Frontend Transport; Sun, 14 Jun 2020 02:51:24 +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: 9510c672-2abf-4f5a-cd0c-08d8100dd3c8 X-MS-TrafficTypeDiagnostic: MN2PR02MB6767: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: x-proofpoint-crosstenant: true X-MS-Oob-TLC-OOBClassifiers: OLM:1060; X-Forefront-PRVS: 04347F8039 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ynv+q8hBkHB3JJgQtj6Oa27OXx7s7AQigAmryZ46job9+b5QOwEfG3UpB3PtoHDJMrLwAbHvP/HSM9i1sIpJydEgpfwCBYivo78Z6CSVliitfG8g8Fm/y7r5HU107AsXtNoscWGQRd86RrNSG0f1iRxYKCbZKC8Hrg8PiRjkeP0YnmXo8Fx147D1Ob9v996YstcOaAZvA7bOy+b0M0TZiZiaemqWn8EIXxrbXePixLojYY+iRrS+M+27mWYnsa5KE6cvHFNrrSuAsgRMuH4bkDPFg5+81G6oEPcVnE1TTVvfMt9AgBhwsCDQ9+xw2bP3gvIxiCu3PVmcUzcUzj3g9w== 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:(376002)(346002)(396003)(136003)(366004)(39850400004)(86362001)(186003)(478600001)(16526019)(6506007)(5660300002)(26005)(107886003)(6916009)(6486002)(2906002)(52116002)(4326008)(54906003)(6512007)(30864003)(316002)(66946007)(66556008)(66574014)(66476007)(2616005)(956004)(8936002)(36756003)(83380400001)(8676002); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData: ZSbm39rGW3b445e7NkNeeunLD1xWEjVNZYaS+VkJrDfEL3VFXf0rDoo9mSeibsQewp7AMXJuYde5/cgh4WYaoNa1AiTuJHb6XEp54tuvWWV5wNeKEn2gCpZy/KdMC0VpBJZVzhExk5byXCvNuTTkz9UA/iJfj+9bWvpCQpgvwruUjcgFT3sOgrR/BFrEF4JoPaLjm3thl8i2r/dBZd6AvlqUwn8nSU6thOkYcHHPIHY8C3SfZGYz2YSd0c/jtPaPFdWuIGuujyQ8kDZSIifvY+0dRkFR/NWxAZazDW1xcvOK4LoQbgbPANLExOrBxOXasav5N04Nvw1qoLJqYpf5wqWIr0LjkLFzatDjb1pV8Gu94+qtiZ2WcHlF6adELp0PGjoED5wpYaYsVDxvrH05IM9BD+Y4GcX/QK8sfwvNlB0Cl7fajgNZozdVzknXtIBsUm983xfqkkAZ3o1kfcQetw1LO7CAKmXznxtPQFG8LP0= X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9510c672-2abf-4f5a-cd0c-08d8100dd3c8 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Jun 2020 02:51:24.8715 (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: bNDr/tmRurtJwS+MRhgvYX6HKc38ku9eh+QPVCb2myBgN/gBbNA77SqXZ5mArcyN1cWI42ggICHWcM+oSN4cuYMczZu9CNwwCnteuPWyIh8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR02MB6767 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216, 18.0.687 definitions=2020-06-13_11:2020-06-12, 2020-06-13 signatures=0 X-Proofpoint-Spam-Reason: safe Subject: [ovs-dev] [PATCH v2 1/2 ovn] NAT: Provide port hash in input 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 enhances the NB OVSSCHEMA to add an additional column in NAT table. external_port_hash: Specifies the hashing mechanism if port range is specified. Changes also add corresponding ovn-nbctl cli. Signed-off-by: Ankur Sharma --- ovn-nb.ovsschema | 5 +- ovn-nb.xml | 15 ++++++ tests/ovn-nbctl.at | 136 +++++++++++++++++++++++++++++++------------------- utilities/ovn-nbctl.c | 111 +++++++++++++++++++++++++++++++--------- 4 files changed, 190 insertions(+), 77 deletions(-) diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema index a06972a..b66e843 100644 --- a/ovn-nb.ovsschema +++ b/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", - "version": "5.23.0", - "cksum": "111023208 25806", + "version": "5.24.0", + "cksum": "984780032 25864", "tables": { "NB_Global": { "columns": { @@ -389,6 +389,7 @@ "external_mac": {"type": {"key": "string", "min": 0, "max": 1}}, "external_port_range": {"type": "string"}, + "external_port_hash": {"type": "string"}, "logical_ip": {"type": "string"}, "logical_port": {"type": {"key": "string", "min": 0, "max": 1}}, diff --git a/ovn-nb.xml b/ovn-nb.xml index acf5648..18d587b 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -2628,6 +2628,21 @@ + +

+ Hashing algorithm to hash a packet to specified port range +

+ +

+ Applicable only if port range is also specified. +

+ +

+ Takes one of the 2 values "Random" and "Hash" +

+ +
+ An IPv4 network (e.g 192.168.1.0/24) or an IPv4 address. diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index 14de1a8..32c896e 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -476,15 +476,15 @@ AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat fd01::1 fd11::2]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.3 lp0 00:00:00:01:02:03]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat fd01::2 fd11::3 lp0 00:00:00:01:02:03]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl -TYPE EXTERNAL_IP EXTERNAL_PORT LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT -dnat 30.0.0.1 192.168.1.2 -dnat fd01::1 fd11::2 -dnat_and_snat 30.0.0.1 192.168.1.2 -dnat_and_snat 30.0.0.2 192.168.1.3 00:00:00:01:02:03 lp0 -dnat_and_snat fd01::1 fd11::2 -dnat_and_snat fd01::2 fd11::3 00:00:00:01:02:03 lp0 -snat 30.0.0.1 192.168.1.0/24 -snat fd01::1 fd11::/64 +TYPE EXTERNAL_IP EXTERNAL_PORT EXTERNAL_PORT_HASH LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT +dnat 30.0.0.1 192.168.1.2 +dnat fd01::1 fd11::2 +dnat_and_snat 30.0.0.1 192.168.1.2 +dnat_and_snat 30.0.0.2 192.168.1.3 00:00:00:01:02:03 lp0 +dnat_and_snat fd01::1 fd11::2 +dnat_and_snat fd01::2 fd11::3 00:00:00:01:02:03 lp0 +snat 30.0.0.1 192.168.1.0/24 +snat fd01::1 fd11::/64 ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.1 192.168.1.0/24], [1], [], [ovn-nbctl: 30.0.0.1, 192.168.1.0/24: a NAT with this external_ip and logical_ip already exists @@ -512,28 +512,28 @@ AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.1 192.168.1.3], [1], [], ]) AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.3 lp0 00:00:00:04:05:06]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl -TYPE EXTERNAL_IP EXTERNAL_PORT LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT -dnat 30.0.0.1 192.168.1.2 -dnat fd01::1 fd11::2 -dnat_and_snat 30.0.0.1 192.168.1.2 -dnat_and_snat 30.0.0.2 192.168.1.3 00:00:00:04:05:06 lp0 -dnat_and_snat fd01::1 fd11::2 -dnat_and_snat fd01::2 fd11::3 00:00:00:01:02:03 lp0 -snat 30.0.0.1 192.168.1.0/24 -snat fd01::1 fd11::/64 +TYPE EXTERNAL_IP EXTERNAL_PORT EXTERNAL_PORT_HASH LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT +dnat 30.0.0.1 192.168.1.2 +dnat fd01::1 fd11::2 +dnat_and_snat 30.0.0.1 192.168.1.2 +dnat_and_snat 30.0.0.2 192.168.1.3 00:00:00:04:05:06 lp0 +dnat_and_snat fd01::1 fd11::2 +dnat_and_snat fd01::2 fd11::3 00:00:00:01:02:03 lp0 +snat 30.0.0.1 192.168.1.0/24 +snat fd01::1 fd11::/64 ]) AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.3]) AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat_and_snat fd01::2 fd11::3]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl -TYPE EXTERNAL_IP EXTERNAL_PORT LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT -dnat 30.0.0.1 192.168.1.2 -dnat fd01::1 fd11::2 -dnat_and_snat 30.0.0.1 192.168.1.2 -dnat_and_snat 30.0.0.2 192.168.1.3 -dnat_and_snat fd01::1 fd11::2 -dnat_and_snat fd01::2 fd11::3 -snat 30.0.0.1 192.168.1.0/24 -snat fd01::1 fd11::/64 +TYPE EXTERNAL_IP EXTERNAL_PORT EXTERNAL_PORT_HASH LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT +dnat 30.0.0.1 192.168.1.2 +dnat fd01::1 fd11::2 +dnat_and_snat 30.0.0.1 192.168.1.2 +dnat_and_snat 30.0.0.2 192.168.1.3 +dnat_and_snat fd01::1 fd11::2 +dnat_and_snat fd01::2 fd11::3 +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], @@ -584,26 +584,26 @@ AT_CHECK([ovn-nbctl --if-exists lr-nat-del lr0 snat 192.168.10.0/24]) AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat 30.0.0.1]) AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat fd01::1]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl -TYPE EXTERNAL_IP EXTERNAL_PORT LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT -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 +TYPE EXTERNAL_IP EXTERNAL_PORT EXTERNAL_PORT_HASH LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT +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 ]) AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl -TYPE EXTERNAL_IP EXTERNAL_PORT 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 +TYPE EXTERNAL_IP EXTERNAL_PORT EXTERNAL_PORT_HASH 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 ]) AT_CHECK([ovn-nbctl lr-nat-del lr0]) @@ -613,10 +613,10 @@ AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat 40.0.0.5 192.168.1.10 1]) AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.5 192.168.1.8 1-3000]) AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.6 192.168.1.9 lp0 00:00:00:04:05:06 1-3000]) AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.6 192.168.1.9 lp0 1-3000], [1], [], -[ovn-nbctl: lr-nat-add with logical_port must also specify external_mac. +[ovn-nbctl: invalid port range lp0. ]) AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.6 192.168.1.9 00:00:00:04:05:06 1-3000], [1], [], -[ovn-nbctl: lr-nat-add with logical_port must also specify external_mac. +[ovn-nbctl: invalid port range 00:00:00:04:05:06. ]) AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.7 192.168.1.10 0], [1], [], @@ -674,12 +674,46 @@ AT_CHECK([ovn-nbctl show lr0 | grep -C2 'external port(s): "1"' | uuidfilt], [0] ]) AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl -TYPE EXTERNAL_IP EXTERNAL_PORT LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT -dnat 40.0.0.4 1-3000 192.168.1.7 -dnat 40.0.0.5 1 192.168.1.10 -dnat_and_snat 40.0.0.5 1-3000 192.168.1.8 -dnat_and_snat 40.0.0.6 1-3000 192.168.1.9 00:00:00:04:05:06 lp0 -snat 40.0.0.3 21-65535 192.168.1.6 +TYPE EXTERNAL_IP EXTERNAL_PORT EXTERNAL_PORT_HASH LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT +dnat 40.0.0.4 1-3000 192.168.1.7 +dnat 40.0.0.5 1 192.168.1.10 +dnat_and_snat 40.0.0.5 1-3000 192.168.1.8 +dnat_and_snat 40.0.0.6 1-3000 192.168.1.9 00:00:00:04:05:06 lp0 +snat 40.0.0.3 21-65535 192.168.1.6 +]) + +AT_CHECK([ovn-nbctl lr-nat-del lr0]) +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 snat 40.0.0.3 192.168.1.6 21-65535 hash]) +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat 40.0.0.4 192.168.1.7 1-3000 random]) +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat 40.0.0.5 192.168.1.10 1 hash]) +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.5 192.168.1.8 1-3000]) +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.6 192.168.1.9 lp0 00:00:00:04:05:06 1-3000]) +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.6 192.168.1.9 lp0 1-3000 hash], [1], [], +[ovn-nbctl: invalid mac address 1-3000. +]) +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.6 192.168.1.9 00:00:00:04:05:06 1-3000 hash], [1], [], +[ovn-nbctl: 00:00:00:04:05:06: port name not found +]) + +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.7 192.168.1.10 0 random], [1], [], +[ovn-nbctl: invalid port range 0. +]) + +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.7 192.168.1.10 1-300 abcd], [1], [], +[ovn-nbctl: invalid port hash abcd. +]) + +AT_CHECK([ovn-nbctl --portrange lr-nat-add lr0 dnat_and_snat 40.0.0.7 192.168.1.10 abcd], [1], [], +[ovn-nbctl: invalid port range abcd. +]) + +AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl +TYPE EXTERNAL_IP EXTERNAL_PORT EXTERNAL_PORT_HASH LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT +dnat 40.0.0.4 1-3000 random 192.168.1.7 +dnat 40.0.0.5 1 hash 192.168.1.10 +dnat_and_snat 40.0.0.5 1-3000 192.168.1.8 +dnat_and_snat 40.0.0.6 1-3000 192.168.1.9 00:00:00:04:05:06 lp0 +snat 40.0.0.3 21-65535 hash 192.168.1.6 ]) AT_CHECK([ovn-nbctl lr-nat-del lr0]) diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index 6ccc702..b6fd17c 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -1037,6 +1037,11 @@ print_lr(const struct nbrec_logical_router *lr, struct ds *s) if (nat->external_port_range[0]) { ds_put_cstr(s, " external port(s): "); ds_put_format(s, "\"%s\"\n", nat->external_port_range); + + if (nat->external_port_hash[0]) { + ds_put_cstr(s, " external port_hash: "); + ds_put_format(s, "\"%s\"\n", nat->external_port_hash); + } } ds_put_cstr(s, " logical ip: "); ds_put_format(s, "\"%s\"\n", nat->logical_ip); @@ -4018,6 +4023,16 @@ out: free(nexthop); } +static inline bool +is_valid_port_hash(const char *port_hash) +{ + if (!strcmp(port_hash, "hash") || !strcmp(port_hash, "random")) { + return true; + } + + return false; +} + static bool is_valid_port_range(const char *port_range) { @@ -4148,6 +4163,7 @@ nbctl_lr_nat_add(struct ctl_context *ctx) const char *logical_port = NULL; const char *external_mac = NULL; const char *port_range = NULL; + const char *port_hash = NULL; if (ctx->argc == 6) { if (!is_portrange) { @@ -4163,21 +4179,52 @@ nbctl_lr_nat_add(struct ctl_context *ctx) return; } - } else if (ctx->argc >= 7) { - if (strcmp(nat_type, "dnat_and_snat")) { - ctl_error(ctx, "logical_port and external_mac are only valid when " - "type is \"dnat_and_snat\"."); - free(new_logical_ip); - return; - } + } else if (ctx->argc == 7) { - if (ctx->argc == 7 && is_portrange) { - ctl_error(ctx, "lr-nat-add with logical_port " - "must also specify external_mac."); - free(new_logical_ip); - return; + if (is_portrange) { + port_range = ctx->argv[5]; + if (!is_valid_port_range(port_range)) { + ctl_error(ctx, "invalid port range %s.", port_range); + free(new_logical_ip); + return; + } + + /* No need to validate the hash value, NBDB set will fail, + * If value is not valid */ + port_hash = ctx->argv[6]; + if (!is_valid_port_hash(port_hash)) { + ctl_error(ctx, "invalid port hash %s.", port_hash); + free(new_logical_ip); + return; + } + } else { + if (strcmp(nat_type, "dnat_and_snat")) { + ctl_error(ctx, "logical_port and external_mac are only valid " + "when type is \"dnat_and_snat\"."); + free(new_logical_ip); + return; + } + + logical_port = ctx->argv[5]; + const struct nbrec_logical_switch_port *lsp; + error = lsp_by_name_or_uuid(ctx, logical_port, true, &lsp); + if (error) { + ctx->error = error; + free(new_logical_ip); + return; + } + + external_mac = ctx->argv[6]; + struct eth_addr ea; + if (!eth_addr_from_string(external_mac, &ea)) { + ctl_error(ctx, "invalid mac address %s.", external_mac); + free(new_logical_ip); + return; + } } + } else if (ctx->argc >= 8) { + logical_port = ctx->argv[5]; const struct nbrec_logical_switch_port *lsp; error = lsp_by_name_or_uuid(ctx, logical_port, true, &lsp); @@ -4195,10 +4242,19 @@ nbctl_lr_nat_add(struct ctl_context *ctx) return; } - if (ctx->argc > 7) { - port_range = ctx->argv[7]; - if (!is_valid_port_range(port_range)) { - ctl_error(ctx, "invalid port range %s.", port_range); + port_range = ctx->argv[7]; + if (!is_valid_port_range(port_range)) { + ctl_error(ctx, "invalid port range %s.", port_range); + free(new_logical_ip); + return; + } + + if (ctx->argc > 8) { + /* No need to validate the hash value, NBDB set will fail, + * If value is not valid */ + port_hash = ctx->argv[8]; + if (!is_valid_port_hash(port_hash)) { + ctl_error(ctx, "invalid port hash %s.", port_hash); free(new_logical_ip); return; } @@ -4208,6 +4264,7 @@ nbctl_lr_nat_add(struct ctl_context *ctx) port_range = NULL; logical_port = NULL; external_mac = NULL; + port_hash = NULL; } bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; @@ -4279,6 +4336,9 @@ nbctl_lr_nat_add(struct ctl_context *ctx) if (port_range) { nbrec_nat_set_external_port_range(nat, port_range); + if (port_hash) { + nbrec_nat_set_external_port_hash(nat, port_hash); + } } smap_add(&nat_options, "stateless", stateless ? "true":"false"); @@ -4379,13 +4439,15 @@ nbctl_lr_nat_list(struct ctl_context *ctx) const struct nbrec_nat *nat = lr->nat[i]; char *key = xasprintf("%-17.13s%s", nat->type, nat->external_ip); if (nat->external_mac && nat->logical_port) { - smap_add_format(&lr_nats, key, "%-17.13s%-22.18s%-21.17s%s", - nat->external_port_range, + smap_add_format(&lr_nats, key, "%-17.13s%-22.18s%-" + "22.18s%-21.17s%s",nat->external_port_range, + nat->external_port_hash, nat->logical_ip, nat->external_mac, nat->logical_port); } else { - smap_add_format(&lr_nats, key, "%-17.13s%s", + smap_add_format(&lr_nats, key, "%-17.13s%-22.18s%s", nat->external_port_range, + nat->external_port_hash, nat->logical_ip); } free(key); @@ -4394,9 +4456,9 @@ nbctl_lr_nat_list(struct ctl_context *ctx) const struct smap_node **nodes = smap_sort(&lr_nats); if (nodes) { ds_put_format(&ctx->output, - "%-17.13s%-19.15s%-17.13s%-22.18s%-21.17s%s\n", - "TYPE", "EXTERNAL_IP", "EXTERNAL_PORT", "LOGICAL_IP", - "EXTERNAL_MAC", "LOGICAL_PORT"); + "%-17.13s%-19.15s%-17.13s%-22.18s%-22.18s%-21.17s%s\n", + "TYPE", "EXTERNAL_IP", "EXTERNAL_PORT", "EXTERNAL_PORT_HASH", + "LOGICAL_IP","EXTERNAL_MAC", "LOGICAL_PORT"); for (size_t i = 0; i < smap_count(&lr_nats); i++) { const struct smap_node *node = nodes[i]; ds_put_format(&ctx->output, "%-36.32s%s\n", @@ -6283,8 +6345,9 @@ static const struct ctl_command_syntax nbctl_commands[] = { /* NAT commands. */ { "lr-nat-add", 4, 7, "ROUTER TYPE EXTERNAL_IP LOGICAL_IP" - "[LOGICAL_PORT EXTERNAL_MAC] [EXTERNAL_PORT_RANGE]", NULL, - nbctl_lr_nat_add, NULL, "--may-exist,--stateless,--portrange", RW }, + "[LOGICAL_PORT EXTERNAL_MAC] [EXTERNAL_PORT_RANGE EXTERNAL_PORT_HASH]", + NULL, nbctl_lr_nat_add, NULL, "--may-exist,--stateless,--portrange", + 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 },