ovn: Allow IP packets destined to router ip for SNAT
authorChandra S Vejendla <csvejend@us.ibm.com>
Wed, 22 Jun 2016 01:36:43 +0000 (18:36 -0700)
committerGurucharan Shetty <guru@ovn.org>
Wed, 22 Jun 2016 17:19:25 +0000 (10:19 -0700)
By default all the ip traffic destined to router ip is dropped in
lr_in_ip_input stage. When the router ip is used as snat ip, allow
reverse snat traffic destined to the router ip.

Signed-off-by: Chandra Sekhar Vejendla <csvejend@us.ibm.com>
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
AUTHORS
ovn/northd/ovn-northd.8.xml
ovn/northd/ovn-northd.c

diff --git a/AUTHORS b/AUTHORS
index e2ac267..c39fdd3 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -39,6 +39,7 @@ Bruce Davie             bsd@nicira.com
 Bryan Phillippe         bp@toroki.com
 Carlo Andreotti         c.andreotti@m3s.it
 Casey Barker            crbarker@google.com
+Chandra Sekhar Vejendla csvejend@us.ibm.com
 Christoph Jaeger        cj@linux.com
 Chris Wright            chrisw@sous-sol.org
 Chuck Short             zulcss@ubuntu.com
index 22edba9..6d52f7e 100644 (file)
@@ -631,7 +631,10 @@ output;
         handled by one of the flows above, which amounts to ICMP (other than
         echo requests) and fragments with nonzero offsets.  For each IP address
         <var>A</var> owned by the router, a priority-60 flow matches
-        <code>ip4.dst == <var>A</var></code> and drops the traffic.
+        <code>ip4.dst == <var>A</var></code> and drops the traffic.  An
+        exception is made and the above flow is not added if the router
+        port's own IP address is used to SNAT packets passing through that
+        router.
       </li>
     </ul>
 
index 17713ec..1599e18 100644 (file)
@@ -2046,11 +2046,37 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
             free(actions);
         }
 
-        /* Drop IP traffic to this router. */
-        match = xasprintf("ip4.dst == "IP_FMT, IP_ARGS(op->ip));
-        ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 60,
-                      match, "drop;");
-        free(match);
+        /* Drop IP traffic to this router, unless the router ip is used as
+         * SNAT ip. */
+        bool snat_ip_is_router_ip = false;
+        for (int i = 0; i < op->od->nbr->n_nat; i++) {
+            const struct nbrec_nat *nat;
+            ovs_be32 ip;
+
+            nat = op->od->nbr->nat[i];
+            if (strcmp(nat->type, "snat")) {
+                continue;
+            }
+
+            if (!ip_parse(nat->external_ip, &ip) || !ip) {
+                static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+                VLOG_WARN_RL(&rl, "bad ip address %s in snat configuration "
+                         "for router %s", nat->external_ip, op->key);
+                continue;
+            }
+
+            if (ip == op->ip) {
+                snat_ip_is_router_ip = true;
+                break;
+            }
+        }
+
+        if (!snat_ip_is_router_ip) {
+            match = xasprintf("ip4.dst == "IP_FMT, IP_ARGS(op->ip));
+            ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 60, match,
+                          "drop;");
+            free(match);
+        }
     }
 
     /* NAT in Gateway routers. */