[ovs-dev] [PATCH 2/3] ovn: Ability to skip some IP addresses for SNAT.

Manoj Sharma manoj.sharma at nutanix.com
Tue Jun 20 06:17:58 UTC 2017


The use case is if someone wants to access a VM from on-prem then it is an l3vpn and we should not do SNAT for it. Both sides should be using their logical IPs.
However the match for “nosnat” should be on destination IP.

I will rebase it to current master and run the tests.

Regards
- Manoj

From: Guru Shetty <guru at ovn.org<mailto:guru at ovn.org>>
Date: Monday, June 19, 2017 at 1:04 PM
To: Manoj Sharma <manoj.sharma at nutanix.com<mailto:manoj.sharma at nutanix.com>>
Cc: "dev at openvswitch.org<mailto:dev at openvswitch.org>" <dev at openvswitch.org<mailto:dev at openvswitch.org>>
Subject: Re: [ovs-dev] [PATCH 2/3] ovn: Ability to skip some IP addresses for SNAT.



On 19 June 2017 at 12:16, Manoj Sharma <manoj.sharma at nutanix.com<mailto:manoj.sharma at nutanix.com>> wrote:
Hi Guru,

It looked very useful patch. Do you plan to commit it into main?
Was there any reason to not merge it so far?

Is there a use case for which you want to use it? What is the use case? This is an old patch and if you think it is useful, please consider spending some time rebasing it to the current master and running all the system tests to make sure that it does not introduce any regression.



Regards
- Manoj


On 11/3/16, 3:46 AM, "dev on behalf of Gurucharan Shetty" <dev-bounces at openvswitch.org<mailto:dev-bounces at openvswitch.org> on behalf of guru at ovn.org<mailto:guru at ovn.org>> wrote:

>We currently have the ability to add a large network to
>match on the source IP address of a packet and then SNAT
>it to a external_ip.  For e.g. one could add a SNAT rule
>that SNATs all packets with source IP address of
>"0.0.0.0/0<http://0.0.0.0/0>" to 10.1.1.10.
>
>It is useful to make a small subnet to pass-through without
>any SNAT done on it. For e.g a subnet that is routable in
>the external network. This commit adds a "nosnat" option
>to the NAT table.
>
>Signed-off-by: Gurucharan Shetty <guru at ovn.org<mailto:guru at ovn.org>>
>---
> ovn/northd/ovn-northd.8.xml |  8 ++++++++
> ovn/northd/ovn-northd.c     | 38 ++++++++++++++++++++++++++++----------
> ovn/ovn-nb.ovsschema        |  5 +++--
> ovn/ovn-nb.xml              |  7 +++++++
> tests/system-ovn.at<http://system-ovn.at>         | 17 +++++++++++++++++
> 5 files changed, 63 insertions(+), 12 deletions(-)
>
>diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
>index df53d4c..b406db6 100644
>--- a/ovn/northd/ovn-northd.8.xml
>+++ b/ovn/northd/ovn-northd.8.xml
>@@ -1434,6 +1434,14 @@ arp {
>       <li>
>         <p>
>           For each configuration in the OVN Northbound database, that asks
>+          NOT to change the source IP address of a packet with address
>+          <var>A</var> or NOT to change the source IP address of a packet that
>+          belongs to network <var>A</var>, a priority-100 flow with a match of
>+          <code>ip && ip4.src == <var>A</var></code> and an action of
>+          <code>next;</code>.
>+        </p>
>+        <p>
>+          For each configuration in the OVN Northbound database, that asks
>           to change the source IP address of a packet from an IP address of
>           <var>A</var> or to change the source IP address of a packet that
>           belongs to network <var>A</var> to <var>B</var>, a flow matches
>diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
>index 07c7b2d..86504aa 100644
>--- a/ovn/northd/ovn-northd.c
>+++ b/ovn/northd/ovn-northd.c
>@@ -3680,6 +3680,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
>
>             nat = op->od->nbr->nat[i];
>
>+            if (!strcmp(nat->type, "nosnat")) {
>+                continue;
>+            }
>+
>             ovs_be32 ip;
>             if (!ip_parse(nat->external_ip, &ip) || !ip) {
>                 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
>@@ -3920,19 +3924,24 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
>
>             ovs_be32 ip, mask;
>
>-            char *error = ip_parse_masked(nat->external_ip, &ip, &mask);
>-            if (error || mask != OVS_BE32_MAX) {
>-                static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
>-                VLOG_WARN_RL(&rl, "bad external ip %s for nat",
>-                             nat->external_ip);
>-                free(error);
>-                continue;
>+            if (strcmp(nat->type, "nosnat")) {
>+                /* "nosnat" cases do not have a 'external_ip'.  Every other
>+                 * case should have a valid 'external_ip'. */
>+                char *error = ip_parse_masked(nat->external_ip, &ip, &mask);
>+                if (error || mask != OVS_BE32_MAX) {
>+                    static struct vlog_rate_limit rl
>+                            = VLOG_RATE_LIMIT_INIT(5, 1);
>+                    VLOG_WARN_RL(&rl, "bad external ip %s for nat",
>+                                 nat->external_ip);
>+                    free(error);
>+                    continue;
>+                }
>             }
>
>             /* Check the validity of nat->logical_ip. 'logical_ip' can
>-             * be a subnet when the type is "snat". */
>-            error = ip_parse_masked(nat->logical_ip, &ip, &mask);
>-            if (!strcmp(nat->type, "snat")) {
>+             * be a subnet when the type is "snat" or "nosnat". */
>+            char *error = ip_parse_masked(nat->logical_ip, &ip, &mask);
>+            if (!strcmp(nat->type, "snat") || !strcmp(nat->type, "nosnat")) {
>                 if (error) {
>                     static struct vlog_rate_limit rl =
>                         VLOG_RATE_LIMIT_INIT(5, 1);
>@@ -3987,6 +3996,15 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
>                               ds_cstr(&match), ds_cstr(&actions));
>             }
>
>+            /* Egress SNAT table: Skip packets that have a specific 'nosnat'
>+             * rule. */
>+            if (!strcmp(nat->type, "nosnat")) {
>+                ds_clear(&match);
>+                ds_put_format(&match, "ip && ip4.src == %s", nat->logical_ip);
>+                ovn_lflow_add(lflows, od, S_ROUTER_OUT_SNAT, 100,
>+                              ds_cstr(&match), "next;");
>+            }
>+
>             /* Egress SNAT table: Packets enter the egress pipeline with
>              * source ip address that needs to be SNATted to a external ip
>              * address. */
>diff --git a/ovn/ovn-nb.ovsschema b/ovn/ovn-nb.ovsschema
>index 65f2d7c..8cfc8a6 100644
>--- a/ovn/ovn-nb.ovsschema
>+++ b/ovn/ovn-nb.ovsschema
>@@ -1,7 +1,7 @@
> {
>     "name": "OVN_Northbound",
>-    "version": "5.4.1",
>-    "cksum": "3773248894 11490",
>+    "version": "5.4.2",
>+    "cksum": "3390487716 11561",
>     "tables": {
>         "NB_Global": {
>             "columns": {
>@@ -210,6 +210,7 @@
>                 "type": {"type": {"key": {"type": "string",
>                                            "enum": ["set", ["dnat",
>                                                              "snat",
>+                                                             "nosnat",
>                                                              "dnat_and_snat"
>                                                                ]]}}}},
>             "isRoot": false},
>diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
>index 7626551..e16e1c2 100644
>--- a/ovn/ovn-nb.xml
>+++ b/ovn/ovn-nb.xml
>@@ -1155,6 +1155,13 @@
>           <ref column="external_ip"/>.
>         </li>
>         <li>
>+          When <ref column="type"/> is <code>nosnat</code>, IP packets
>+          with their source IP address that either matches the IP address
>+          in <ref column="logical_ip"/> or is in the network provided by
>+          <ref column="logical_ip"/> is not SNATed and is allowed to
>+          pass-through.
>+        </li>
>+        <li>
>           When <ref column="type"/> is <code>dnat_and_snat</code>, the
>           externally visible IP address <ref column="external_ip"/> is
>           DNATted to the IP address <ref column="logical_ip"/> in the
>diff --git a/tests/system-ovn.at<http://system-ovn.at> b/tests/system-ovn.at<http://system-ovn.at>
>index 21226d9..d627f76 100644
>--- a/tests/system-ovn.at<http://system-ovn.at>
>+++ b/tests/system-ovn.at<http://system-ovn.at>
>@@ -263,6 +263,23 @@ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
> icmp,orig=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
> ])
>
>+ovs-appctl dpctl/flush-conntrack
>+
>+# Add a "nosnat" rule.
>+ovn-nbctl -- --id=@nat create nat type="nosnat" logical_ip=192.168.1.0/24<http://192.168.1.0/24> \
>+     -- add logical_router R2 nat @nat
>+
>+# South-North NOSNAT: 'foo1' pings 'alice1'. 'alice1' receives traffic
>+# from 192.168.1.2 (i.e without NAT)
>+NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
>+[0], [dnl
>+3 packets transmitted, 3 received, 0% packet loss, time 0ms
>+])
>+
>+# We verify that SNAT did not happen via 'dump-conntrack' command.
>+AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.1)], [0], [dnl
>+])
>+
> OVS_APP_EXIT_AND_WAIT([ovn-controller])
>
> as ovn-sb
>--
>1.9.1
>
>_______________________________________________
>dev mailing list
>dev at openvswitch.org<mailto:dev at openvswitch.org>
>http://openvswitch.org/mailman/listinfo/dev<http://openvswitch.org/mailman/listinfo/dev>



More information about the dev mailing list