From patchwork Wed Oct 30 14:53:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell Bryant X-Patchwork-Id: 1186784 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=none (p=none dis=none) header.from=ovn.org 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 473BNX2C92z9sCJ for ; Thu, 31 Oct 2019 01:56:12 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6D2BCDB2; Wed, 30 Oct 2019 14:53:37 +0000 (UTC) X-Original-To: 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 1E221C90 for ; Wed, 30 Oct 2019 14:53:35 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 2BD3A876 for ; Wed, 30 Oct 2019 14:53:34 +0000 (UTC) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-303-7sTexYhTP8KWH2jKzGgDuQ-1; Wed, 30 Oct 2019 10:53:28 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0948A5E4; Wed, 30 Oct 2019 14:53:28 +0000 (UTC) Received: from t480s.redhat.com (ovpn-126-115.rdu2.redhat.com [10.10.126.115]) by smtp.corp.redhat.com (Postfix) with ESMTP id 978EF52FD; Wed, 30 Oct 2019 14:53:27 +0000 (UTC) From: Russell Bryant To: dev@openvswitch.org Date: Wed, 30 Oct 2019 10:53:21 -0400 Message-Id: <20191030145324.9988-4-russell@ovn.org> In-Reply-To: <20191030145324.9988-1-russell@ovn.org> References: <20191030013138.9390-1-russell@ovn.org> <20191030145324.9988-1-russell@ovn.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-MC-Unique: 7sTexYhTP8KWH2jKzGgDuQ-1 X-Mimecast-Spam-Score: 0 X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED 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 ovn v2 3/6] ovn-nbctl: Allow IPv6 NAT rules to be added 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 Signed-off-by: Russell Bryant --- tests/ovn-nbctl.at | 41 ++++++++++++++++++++++++++++-------- utilities/ovn-nbctl.c | 49 ++++++++++++++++++++++++++++++++----------- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index 01091dd99..43a980bdf 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -407,16 +407,16 @@ AT_CHECK([ovn-nbctl lr-nat-add lr0 snatt 30.0.0.2 192.168.1.2], [1], [], [ovn-nbctl: snatt: type must be one of "dnat", "snat" and "dnat_and_snat". ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2a 192.168.1.2], [1], [], -[ovn-nbctl: 30.0.0.2a: should be an IPv4 address. +[ovn-nbctl: 30.0.0.2a: Not a valid IPv4 or IPv6 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0 192.168.1.2], [1], [], -[ovn-nbctl: 30.0.0: should be an IPv4 address. +[ovn-nbctl: 30.0.0: Not a valid IPv4 or IPv6 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2/24 192.168.1.2], [1], [], -[ovn-nbctl: 30.0.0.2/24: should be an IPv4 address. +[ovn-nbctl: 30.0.0.2/24: Not a valid IPv4 or IPv6 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2:80 192.168.1.2], [1], [], -[ovn-nbctl: 30.0.0.2:80: should be an IPv4 address. +[ovn-nbctl: 30.0.0.2:80: Not a valid IPv4 or IPv6 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.2a], [1], [], [ovn-nbctl: 192.168.1.2a: should be an IPv4 address or network. @@ -431,19 +431,19 @@ AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.2/a], [1], [], [ovn-nbctl: 192.168.1.2/a: should be an IPv4 address or network. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1.2a], [1], [], -[ovn-nbctl: 192.168.1.2a: should be an IPv4 address. +[ovn-nbctl: 192.168.1.2a: Not a valid IPv4 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1], [1], [], -[ovn-nbctl: 192.168.1: should be an IPv4 address. +[ovn-nbctl: 192.168.1: Not a valid IPv4 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1.2:80], [1], [], -[ovn-nbctl: 192.168.1.2:80: should be an IPv4 address. +[ovn-nbctl: 192.168.1.2:80: Not a valid IPv4 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1.2/24], [1], [], -[ovn-nbctl: 192.168.1.2/24: should be an IPv4 address. +[ovn-nbctl: 192.168.1.2/24: Not a valid IPv4 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.2/24], [1], [], -[ovn-nbctl: 192.168.1.2/24: should be an IPv4 address. +[ovn-nbctl: 192.168.1.2/24: Not a valid IPv4 address. ]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.2 lp0], [1], [], [ovn-nbctl: lr-nat-add with logical_port must also specify external_mac. @@ -465,15 +465,23 @@ AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.2 lp0 00:00: dnl Add snat and dnat AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.1 192.168.1.0/24]) +AT_CHECK([ovn-nbctl lr-nat-add lr0 snat fd01::1 fd11::/64]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.1 192.168.1.2]) +AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat fd01::1 fd11::2]) AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.1 192.168.1.2]) +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 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 @@ -503,17 +511,26 @@ AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1. AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl TYPE EXTERNAL_IP 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 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 ]) dnl Deletes the NATs @@ -529,18 +546,24 @@ AT_CHECK([ovn-nbctl lr-nat-del lr0 snat 192.168.10.0/24], [1], [], 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 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 fd01::2 fd11::3 snat 30.0.0.1 192.168.1.0/24 +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 LOGICAL_IP EXTERNAL_MAC LOGICAL_PORT dnat_and_snat 30.0.0.2 192.168.1.3 +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 lr-nat-del lr0]) diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index a89a9cb4d..68ced987a 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -3867,26 +3867,51 @@ nbctl_lr_nat_add(struct ctl_context *ctx) ovs_be32 ipv4 = 0; unsigned int plen; + struct in6_addr ipv6; + bool is_v6 = false; if (!ip_parse(external_ip, &ipv4)) { - ctl_error(ctx, "%s: should be an IPv4 address.", external_ip); - return; + if (ipv6_parse(external_ip, &ipv6)) { + is_v6 = true; + } else { + ctl_error(ctx, "%s: Not a valid IPv4 or IPv6 address.", + external_ip); + return; + } } if (strcmp("snat", nat_type)) { - if (!ip_parse(logical_ip, &ipv4)) { - ctl_error(ctx, "%s: should be an IPv4 address.", logical_ip); - return; + if (is_v6) { + if (!ipv6_parse(logical_ip, &ipv6)) { + ctl_error(ctx, "%s: Not a valid IPv6 address.", logical_ip); + return; + } + } else { + if (!ip_parse(logical_ip, &ipv4)) { + ctl_error(ctx, "%s: Not a valid IPv4 address.", logical_ip); + return; + } } new_logical_ip = xstrdup(logical_ip); } else { - error = ip_parse_cidr(logical_ip, &ipv4, &plen); - if (error) { - free(error); - ctl_error(ctx, "%s: should be an IPv4 address or network.", - logical_ip); - return; + if (is_v6) { + error = ipv6_parse_cidr(logical_ip, &ipv6, &plen); + if (error) { + free(error); + ctl_error(ctx, "%s: should be an IPv6 address or network.", + logical_ip); + return; + } + new_logical_ip = normalize_ipv6_prefix(ipv6, plen); + } else { + error = ip_parse_cidr(logical_ip, &ipv4, &plen); + if (error) { + free(error); + ctl_error(ctx, "%s: should be an IPv4 address or network.", + logical_ip); + return; + } + new_logical_ip = normalize_ipv4_prefix(ipv4, plen); } - new_logical_ip = normalize_ipv4_prefix(ipv4, plen); } const char *logical_port;