[ovs-dev,1/2] ovn-northd: Allow static routes with nexthop in different subnet.
diff mbox

Message ID 1489131998-28461-1-git-send-email-guru@ovn.org
State Accepted
Delegated to: Ben Pfaff
Headers show

Commit Message

Gurucharan Shetty March 10, 2017, 7:46 a.m. UTC
There are cases where the default gateway of a interface is in
a different subnet than its IP address. Linux allows such
configuration. For e.g, one could set the IP address of
a Linux interface as 172.16.1.2/32 and then give it a default
gateway of 172.16.1.1.  This can be done for e.g. by running the
following commands.

ifconfig eth0 172.16.1.2 netmask 255.255.255.255 broadcast 172.16.1.2
route add 172.16.1.1 dev eth0
route add default gw 172.16.1.1

The above configuration is what google cloud uses for its VMs.

In OVN static routes, we currently have the ability to specify the
router port via which the packet needs to be pushed out to reach a
next hop.  But when support for IPv6 was added, we only allowed
nexthops to be in the same subnet as one of the router's IP addresses.

This commit relaxes that restriction. When a outport is specified in
static routes and when a nexthop is in a different subnet than any
of the router IP addresses, we will assume that it is reachable from
the first IP address of the router.  Since this is a corner case,
we just go with the first IP address.  If it turns out that there
are more cases, we can let users choose the IP address via which
the destination is reachable.

Signed-off-by: Gurucharan Shetty <guru@ovn.org>
---
Patch2 of the series includes a unit test that also covers this
case.
---
 ovn/northd/ovn-northd.c | 17 +++++++++++++++++
 ovn/ovn-nb.xml          |  5 ++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

Comments

Ben Pfaff April 21, 2017, 5:41 p.m. UTC | #1
On Thu, Mar 09, 2017 at 11:46:37PM -0800, Gurucharan Shetty wrote:
> There are cases where the default gateway of a interface is in
> a different subnet than its IP address. Linux allows such
> configuration. For e.g, one could set the IP address of
> a Linux interface as 172.16.1.2/32 and then give it a default
> gateway of 172.16.1.1.  This can be done for e.g. by running the
> following commands.
> 
> ifconfig eth0 172.16.1.2 netmask 255.255.255.255 broadcast 172.16.1.2
> route add 172.16.1.1 dev eth0
> route add default gw 172.16.1.1
> 
> The above configuration is what google cloud uses for its VMs.
> 
> In OVN static routes, we currently have the ability to specify the
> router port via which the packet needs to be pushed out to reach a
> next hop.  But when support for IPv6 was added, we only allowed
> nexthops to be in the same subnet as one of the router's IP addresses.
> 
> This commit relaxes that restriction. When a outport is specified in
> static routes and when a nexthop is in a different subnet than any
> of the router IP addresses, we will assume that it is reachable from
> the first IP address of the router.  Since this is a corner case,
> we just go with the first IP address.  If it turns out that there
> are more cases, we can let users choose the IP address via which
> the destination is reachable.
> 
> Signed-off-by: Gurucharan Shetty <guru@ovn.org>
> ---
> Patch2 of the series includes a unit test that also covers this
> case.

Acked-by: Ben Pfaff <blp@ovn.org>

Patch
diff mbox

diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index cc9b934..59ebc05 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -3697,6 +3697,23 @@  build_static_route_flow(struct hmap *lflows, struct ovn_datapath *od,
             goto free_prefix_s;
         }
         lrp_addr_s = find_lrp_member_ip(out_port, route->nexthop);
+        if (!lrp_addr_s) {
+            /* There are no IP networks configured on the router's port via
+             * which 'route->nexthop' is theoretically reachable.  But since
+             * 'out_port' has been specified, we honor it by trying to reach
+             * 'route->nexthop' via the first IP address of 'out_port'.
+             * (There are cases, e.g in GCE, where each VM gets a /32 IP
+             * address and the default gateway is still reachable from it.) */
+            if (is_ipv4) {
+                if (out_port->lrp_networks.n_ipv4_addrs) {
+                    lrp_addr_s = out_port->lrp_networks.ipv4_addrs[0].addr_s;
+                }
+            } else {
+                if (out_port->lrp_networks.n_ipv6_addrs) {
+                    lrp_addr_s = out_port->lrp_networks.ipv6_addrs[0].addr_s;
+                }
+            }
+        }
     } else {
         /* output_port is not specified, find the
          * router port matching the next hop. */
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index 88a6082..c1f4e1f 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -1264,7 +1264,10 @@ 
         The name of the <ref table="Logical_Router_Port"/> via which the packet
         needs to be sent out.  This is optional and when not specified,
         OVN will automatically figure this out based on the
-        <ref column="nexthop"/>.
+        <ref column="nexthop"/>.  When this is specified and there are
+        multiple IP addresses on the router port and none of them are in the
+        same subnet of <ref column="nexthop"/>, OVN chooses the first IP
+        address as the one via which the <ref column="nexthop"/> is reachable.
       </p>
     </column>
   </table>