[ovs-dev] [PATCH ovn 3/6] ovn-nbctl: Allow IPv6 NAT rules to be added

Russell Bryant russell at ovn.org
Wed Oct 30 01:31:35 UTC 2019


Signed-off-by: Russell Bryant <russell at ovn.org>
---
 tests/ovn-nbctl.at    | 41 ++++++++++++++++++++++++++++--------
 utilities/ovn-nbctl.c | 48 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 68 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..3b5b7c042 100644
--- a/utilities/ovn-nbctl.c
+++ b/utilities/ovn-nbctl.c
@@ -3867,26 +3867,50 @@ nbctl_lr_nat_add(struct ctl_context *ctx)
 
     ovs_be32 ipv4 = 0;
     unsigned int plen;
+    struct in6_addr ipv6 = {0, };
+    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;
-- 
2.21.0



More information about the dev mailing list