This patch add static route to logical router which are required in many
scenarios, such as VPNaas service, l3 gateway.
For VPNaas, OVN logical router SHOULD be able to route the VPN remote
subnet to the
VPN VM, static route is the best choice.

This patach will add a new pointer array in "Logical_Router" table, the
pointers will point to a new table "Logical_Router_Static_Route" to record
the static routes.

Current logical router already has default route. This patach will add
static route will ovn northd update the router logical flow. Static route
will add before the default router.

ovn/northd/ovn-northd.c     Add static route logical flow
ovn/ovn-nb.ovsschema        Add staic route table
ovn/utilities/ovn-nbctl.c   Add static route to ovn-nbctl command

Test case updates:
Add static route test in case: 3 HVs, 3 LS, 3 lports/LS, 1 LR

Signed-off-by: Steve Ruan <rua...@cn.ibm.com>,
Reported-by: Na Zhu <na...@cn.ibm.com>
Reported-by: Dustin Lundquist <dlundqu...@linux.vnet.ibm.com>

Reported-at:
https://bugs.launchpad.net/networking-ovn/+bug/1545140
https://bugs.launchpad.net/networking-ovn/+bug/1539347

 ovn/northd/ovn-northd.8.xml   |  2 +-
 ovn/northd/ovn-northd.c       | 70 +++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++
 ovn/ovn-nb.ovsschema          | 13 ++++++++++++-
 ovn/ovn-nb.xml                | 35 +++++++++++++++++++++++++++++++++++
 ovn/utilities/ovn-nbctl.8.xml |  5 +++++
 ovn/utilities/ovn-nbctl.c     |  5 +++++
 tests/ovn.at                  | 10 ++++++++++
 7 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
index 743c939..7eb75df 100644
--- a/ovn/northd/ovn-northd.8.xml
+++ b/ovn/northd/ovn-northd.8.xml
@@ -680,7 +680,7 @@ next;
         </p>

         <p>
-          If the route has a gateway, <var>G</var> is the gateway IP
address,
+          If the route has a nexthop, <var>G</var> is the nexthop address,
           otherwise it is <code>ip4.dst</code>.
         </p>
       </li>
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 0c869f4..bd25c49 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -1780,6 +1780,68 @@ add_route(struct hmap *lflows, const struct ovn_port
*op,
 }

 static void
+build_static_route_flow(struct hmap *lflows, struct ovn_datapath *od,
struct hmap *ports,
+        const struct nbrec_logical_router_static_route *route)
+{
+    struct ovn_port *out_port, *op;
+    ovs_be32 prefix, nexthop, mask;
+    int len;
+    bool enabled;
+
+    /* verify nexthop */
+    char *error = ip_parse_masked(route->nexthop, &nexthop, &mask);
+    if (error || mask != OVS_BE32_MAX) {
+        static struct vlog_rate_limit rl
+                        = VLOG_RATE_LIMIT_INIT(5, 10);
+        VLOG_WARN_RL(&rl, "bad 'nexthop' %s error %s", route->nexthop,
error);
+        free(error);
+        return;
+    }
+
+    /* verify prefix */
+    error = ip_parse_masked(route->prefix, &prefix, &mask);
+    if (error || !ip_is_cidr(mask)) {
+        static struct vlog_rate_limit rl
+                        = VLOG_RATE_LIMIT_INIT(5, 10);
+        VLOG_WARN_RL(&rl, "bad 'prefix' %s error %s", route->prefix,
error);
+        free(error);
+        return;
+    }
+
+    /* find the outgoing port */
+    out_port = NULL;
+    len = 0;
+    for (int i = 0; i < od->nbr->n_ports; i++){
+
+        struct nbrec_logical_router_port *lrp = od->nbr->ports[i];
+        op = ovn_port_find(ports, lrp->name);
+        if (!op){  /* this should not happen */
+            continue;
+        }
+
+        if (op->network && !((op->network ^ nexthop) & op->mask)){
+            if (ip_count_cidr_bits(op->mask) > len){
+                len = ip_count_cidr_bits(op->mask);
+                out_port = op;
+            }
+        }
+    }
+
+    if (!out_port){
+        /*set route invalid flag*/
+        enabled = false;
+        nbrec_logical_router_static_route_set_valid(route, &enabled, 1);
+        return;
+    }
+
+    /* set valid flag */
+    enabled = true;
+    nbrec_logical_router_static_route_set_valid(route, &enabled, 1);
+
+    add_route(lflows, out_port, prefix, mask, nexthop);
+}
+
+static void
 build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
                     struct hmap *lflows)
 {
@@ -1948,6 +2010,14 @@ build_lrouter_flows(struct hmap *datapaths, struct
hmap *ports,
             continue;
         }

+        /* convert the routing table to flow */
+        for (int i = 0; i < od->nbr->n_routes; i++){
+            const struct nbrec_logical_router_static_route *route;
+
+            route = od->nbr->routes[i];
+            build_static_route_flow(lflows, od, ports, route);
+        }
+
         if (od->gateway && od->gateway_port) {
             add_route(lflows, od->gateway_port, 0, 0, od->gateway);
         }
diff --git a/ovn/ovn-nb.ovsschema b/ovn/ovn-nb.ovsschema
index 9fb8cd1..f1894b1 100644
--- a/ovn/ovn-nb.ovsschema
+++ b/ovn/ovn-nb.ovsschema
@@ -1,7 +1,7 @@
 {
     "name": "OVN_Northbound",
     "version": "2.0.1",
-    "cksum": "660370796 4618",
+    "cksum": "3768071525 5196",
     "tables": {
         "Logical_Switch": {
             "columns": {
@@ -72,6 +72,11 @@
                                    "min": 0,
                                    "max": "unlimited"}},
                 "default_gw": {"type": {"key": "string", "min": 0, "max":
1}},
+                "routes": {"type": {"key": {"type": "uuid",
+                                           "refTable":
"Logical_Router_Static_Route",
+                                           "refType": "strong"},
+                                   "min": 0,
+                                   "max": "unlimited"}},
                 "external_ids": {
                     "type": {"key": "string", "value": "string",
                              "min": 0, "max": "unlimited"}}},
@@ -90,6 +95,12 @@
                     "type": {"key": "string", "value": "string",
                              "min": 0, "max": "unlimited"}}},
             "indexes": [["name"]],
+            "isRoot": false},
+        "Logical_Router_Static_Route": {
+            "columns": {
+                "prefix": {"type": "string"},
+                "nexthop": {"type": "string"},
+                "valid": {"type": {"key": "boolean", "min": 0, "max":
1}}},
             "isRoot": false}
     }
 }
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index e65bc3a..cf044d0 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -627,6 +627,10 @@
       IP address to use as default gateway, if any.
     </column>

+    <column name="routes">
+      Routes belonging to this router.
+    </column>
+
     <group title="Common Columns">
       <column name="external_ids">
         See <em>External IDs</em> at the beginning of this document.
@@ -717,4 +721,35 @@
       </column>
     </group>
   </table>
+
+  <table name="Logical_Router_Static_Route" title="L3 logical router
static routes">
+    <p>
+      Each route represents a static route.
+    </p>
+
+    <p>
+      Exactly one <ref table="Logical_Router"/> row must reference a given
+      logical router static routes.
+    </p>
+
+    <column name="prefix">
+      <p>
+        Prefix of this route, example 192.168.100.0/24
+      </p>
+    </column>
+
+    <column name="nexthop">
+      <p>
+        Nexthop of this route, nexthop can be a IP address of neutron
port, or
+        IP address which has been learnt by dynamic ARP
+      </p>
+    </column>
+
+    <column name="valid">
+      <p>
+        It will set to valid when its nexthop can be resolved.
+      </p>
+    </column>
+  </table>
+
 </database>
diff --git a/ovn/utilities/ovn-nbctl.8.xml b/ovn/utilities/ovn-nbctl.8.xml
index 3b337dd..2a0bfd2 100644
--- a/ovn/utilities/ovn-nbctl.8.xml
+++ b/ovn/utilities/ovn-nbctl.8.xml
@@ -231,6 +231,11 @@
         A port within an L3 logical router.  Records may be identified by
name.
       </dd>

+      <dt><code>Logical_Router_Static_Route</code></dt>
+      <dd>
+        A static route belonging to an L3 logical router.
+      </dd>
+
     </dl>

     <xi:include href="lib/db-ctl-base.xml" xmlns:xi="
http://www.w3.org/2003/XInclude"/>
diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c
index bdad368..bb3ce3e 100644
--- a/ovn/utilities/ovn-nbctl.c
+++ b/ovn/utilities/ovn-nbctl.c
@@ -1101,6 +1101,11 @@ static const struct ctl_table_class tables[] = {
        NULL},
       {NULL, NULL, NULL}}},

+    {&nbrec_table_logical_router_static_route,
+     {{&nbrec_table_logical_router_static_route, NULL,
+       NULL},
+      {NULL, NULL, NULL}}},
+
     {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
 };
 ^L
diff --git a/tests/ovn.at b/tests/ovn.at
index f2ceba3..9b5c199 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1385,6 +1385,16 @@ as hv1 ovn-sbctl list datapath_binding
 as hv1 ovn-sbctl dump-flows
 as hv1 ovs-ofctl dump-flows br-int

+### add a static route to router
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route
prefix=172.16.1.0/24 nexthop=192.168.12.1 -- add Logical_Router test_router
routes @lrt
+
+# Allow some time for ovn-northd and ovn-controller to catch up.
+sleep 1
+
+as hv1 ovs-ofctl dump-flows br-int
+as hv2 ovs-ofctl dump-flows br-int
+as hv3 ovs-ofctl dump-flows br-int
+
 # Send IP packets between all pairs of source and destination ports:
 #
 # 1. Unicast IP packets are delivered to exactly one lport (except


Best Regards
Steve Ruan(阮诗新)

Tel: (86-021)60928749,
Address: 5/F, Building 10, 399 Ke Yuan Road, Zhangjiang High-Tech Park,
Shanghai 201203, PRC
上海浦东新区张江高科园区科苑路399号10号楼5楼
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to