[ovs-dev] [PATCH v7 1/7] ovn: specify addresses of type "router" lsps as "router"

Mickey Spiegel mickeys.dev at gmail.com
Fri Jan 6 20:00:28 UTC 2017


Currently in OVN, when a logical switch port of type "router" is
created, the MAC and optionally IP addresses of the peer logical
router port must be specified again as the addresses of the logical
switch port.

This patch allows the logical switch port's addresses to be
specified as the string "router", rather than explicitly copying the
logical router port's MAC and optionally IP addresses.  The router
addresses are used to populate the logical switch's destination
lookup, and to populate op->lsp_addrs in ovn-northd.c, which in turn
is used to generate logical switch ARP and ND replies.  Since ipam
already looks at logical router ports, the only ipam modification
necessary is to skip logical switch ports with addresses "router".

Signed-off-by: Mickey Spiegel <mickeys.dev at gmail.com>
Acked-by: Ben Pfaff <blp at ovn.org>
---
 ovn/northd/ovn-northd.c       | 31 +++++++++++++++++++++++++++++--
 ovn/ovn-nb.xml                | 22 ++++++++++++++++++++++
 ovn/utilities/ovn-nbctl.8.xml |  9 +++++++++
 ovn/utilities/ovn-nbctl.c     |  1 +
 tests/ovn.at                  |  3 ++-
 5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index a28327b..5ad544d 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -815,7 +815,7 @@ ipam_insert_lsp_addresses(struct ovn_datapath *od, struct ovn_port *op,
                           char *address)
 {
     if (!od || !op || !address || !strcmp(address, "unknown")
-        || is_dynamic_lsp_address(address)) {
+        || !strcmp(address, "router") || is_dynamic_lsp_address(address)) {
         return;
     }
 
@@ -1205,7 +1205,8 @@ join_logical_ports(struct northd_context *ctx,
                 op->lsp_addrs
                     = xmalloc(sizeof *op->lsp_addrs * nbsp->n_addresses);
                 for (size_t j = 0; j < nbsp->n_addresses; j++) {
-                    if (!strcmp(nbsp->addresses[j], "unknown")) {
+                    if (!strcmp(nbsp->addresses[j], "unknown")
+                        || !strcmp(nbsp->addresses[j], "router")) {
                         continue;
                     }
                     if (is_dynamic_lsp_address(nbsp->addresses[j])) {
@@ -1323,6 +1324,18 @@ join_logical_ports(struct northd_context *ctx,
                 op->od->router_ports,
                 sizeof *op->od->router_ports * (op->od->n_router_ports + 1));
             op->od->router_ports[op->od->n_router_ports++] = op;
+
+            /* Fill op->lsp_addrs for op->nbsp->addresses[] with
+             * contents "router", which was skipped in the loop above. */
+            for (size_t j = 0; j < op->nbsp->n_addresses; j++) {
+                if (!strcmp(op->nbsp->addresses[j], "router")) {
+                    if (extract_lrp_networks(peer->nbrp,
+                                            &op->lsp_addrs[op->n_lsp_addrs])) {
+                        op->n_lsp_addrs++;
+                    }
+                    break;
+                }
+            }
         } else if (op->nbrp && op->nbrp->peer) {
             struct ovn_port *peer = ovn_port_find(ports, op->nbrp->peer);
             if (peer) {
@@ -3123,6 +3136,20 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
                 ds_put_format(&actions, "outport = %s; output;", op->json_key);
                 ovn_lflow_add(lflows, op->od, S_SWITCH_IN_L2_LKUP, 50,
                               ds_cstr(&match), ds_cstr(&actions));
+            } else if (!strcmp(op->nbsp->addresses[i], "router")) {
+                if (!op->peer || !op->peer->nbrp
+                    || !ovs_scan(op->peer->nbrp->mac,
+                            ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))) {
+                    continue;
+                }
+                ds_clear(&match);
+                ds_put_format(&match, "eth.dst == "ETH_ADDR_FMT,
+                              ETH_ADDR_ARGS(mac));
+
+                ds_clear(&actions);
+                ds_put_format(&actions, "outport = %s; output;", op->json_key);
+                ovn_lflow_add(lflows, op->od, S_SWITCH_IN_L2_LKUP, 50,
+                              ds_cstr(&match), ds_cstr(&actions));
             } else {
                 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
 
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index a3dc916..e52b29e 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -519,6 +519,28 @@
             </dl>
           </dd>
 
+          <dt><code>router</code></dt>
+          <dd>
+            <p>
+              Accepted only when <ref column="type"/> is <code>router</code>.
+              This indicates that the Ethernet, IPv4, and IPv6 addresses for
+              this logical switch port should be obtained from the connected
+              logical router port, as specified by <code>router-port</code> in
+              <ref column="options"/>.
+            </p>
+
+            <p>
+              The resulting addresses are used to populate the logical
+              switch's destination lookup, and also for the logical switch
+              to generate ARP and ND replies.
+            </p>
+
+            <p>
+              Supported only in OVN 2.7 and later.  Earlier versions required
+              router addresses to be manually synchronized.
+            </p>
+          </dd>
+
         </dl>
       </column>
 
diff --git a/ovn/utilities/ovn-nbctl.8.xml b/ovn/utilities/ovn-nbctl.8.xml
index 66fd199..4911c6a 100644
--- a/ovn/utilities/ovn-nbctl.8.xml
+++ b/ovn/utilities/ovn-nbctl.8.xml
@@ -197,6 +197,15 @@
             the logical port's subnet and store them in the port's
             <code>dynamic_addresses</code> column.
           </dd>
+
+          <dt><code>router</code></dt>
+          <dd>
+            Accepted only when the <code>type</code> of the logical switch
+            port is <code>router</code>.  This indicates that the Ethernet,
+            IPv4, and IPv6 addresses for this logical switch port should be
+            obtained from the connected logical router port, as specified by
+            <code>router-port</code> in <code>lsp-set-options</code>.
+          </dd>
         </dl>
 
         <p>
diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c
index 2322045..15641f6 100644
--- a/ovn/utilities/ovn-nbctl.c
+++ b/ovn/utilities/ovn-nbctl.c
@@ -987,6 +987,7 @@ nbctl_lsp_set_addresses(struct ctl_context *ctx)
         struct eth_addr ea;
 
         if (strcmp(ctx->argv[i], "unknown") && strcmp(ctx->argv[i], "dynamic")
+            && strcmp(ctx->argv[i], "router")
             && !ovs_scan(ctx->argv[i], ETH_ADDR_SCAN_FMT,
                          ETH_ADDR_SCAN_ARGS(ea))) {
             ctl_fatal("%s: Invalid address format. See ovn-nb(5). "
diff --git a/tests/ovn.at b/tests/ovn.at
index 65f9776..12393dc 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -4804,7 +4804,8 @@ ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2
 # Connect foo to R1
 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
-          options:router-port=foo addresses=\"00:00:00:01:02:03\"
+          options:router-port=foo \
+          -- lsp-set-addresses rp-foo router
 
 # Connect alice to R1
 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
-- 
1.9.1



More information about the dev mailing list