[ovs-dev] [PATCH v3 06/10] ovn: Add patch ports for ovn bridge mappings.

Russell Bryant rbryant at redhat.com
Tue Jul 21 16:59:16 UTC 2015


While parsing the OVN bridge mapping configuration, ensure that patch
ports exist between the OVN integration bridge and the physical
network bridge.  If they do not exist, create them automatically.

Signed-off-by: Russell Bryant <rbryant at redhat.com>
---
 ovn/controller/ovn-controller.c | 114 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 16b6a8c..64d46da 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -87,6 +87,113 @@ get_bridge(struct controller_ctx *ctx, const char *name)
     return NULL;
 }
 
+/*
+ * Return true if the port is a patch port to a given bridge
+ */
+static bool
+match_patch_port(const struct ovsrec_port *port, const struct ovsrec_bridge *to_br)
+{
+    struct ovsrec_interface *iface;
+    size_t i;
+
+    for (i = 0; i < port->n_interfaces; i++) {
+        const char *peer;
+        iface = port->interfaces[i];
+        if (strcmp(iface->type, "patch")) {
+            continue;
+        }
+        peer = smap_get(&iface->options, "peer");
+        if (peer && !strcmp(peer, to_br->name)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static int
+create_patch_port(struct controller_ctx *ctx, const struct ovsrec_bridge *b1,
+        const struct ovsrec_bridge *b2)
+{
+    struct ovsdb_idl_txn *ovs_txn;
+    struct ovsrec_interface *iface;
+    struct ovsrec_port *port, **ports;
+    struct smap options = SMAP_INITIALIZER(&options);
+    size_t i;
+    int retval, res = 0;
+    char *port_name;
+
+    port_name = xasprintf("patch-%s-to-%s", b1->name, b2->name);
+
+    ovs_txn = ovsdb_idl_txn_create(ctx->ovs_idl);
+    ovsdb_idl_txn_add_comment(ovs_txn,
+            "ovn-controller: creating patch port '%s' from '%s' to '%s'",
+            port_name, b1->name, b2->name);
+
+    iface = ovsrec_interface_insert(ovs_txn);
+    ovsrec_interface_set_name(iface, port_name);
+    ovsrec_interface_set_type(iface, "patch");
+    smap_add(&options, "peer", b2->name);
+    ovsrec_interface_set_options(iface, &options);
+    smap_destroy(&options);
+
+    port = ovsrec_port_insert(ovs_txn);
+    ovsrec_port_set_name(port, port_name);
+    ovsrec_port_set_interfaces(port, &iface, 1);
+
+    ports = xmalloc(sizeof *port * (b1->n_ports + 1));
+    for (i = 0; i < b1->n_ports; i++) {
+        ports[i] = b1->ports[i];
+    }
+    ports[i] = port;
+    ovsrec_bridge_verify_ports(b1);
+    ovsrec_bridge_set_ports(b1, ports, b1->n_ports + 1);
+
+    retval = ovsdb_idl_txn_commit_block(ovs_txn);
+    if (retval != TXN_SUCCESS && retval != TXN_UNCHANGED) {
+        VLOG_INFO("Problem adding patch port: %s",
+                  ovsdb_idl_txn_status_to_string(retval));
+        poll_immediate_wake();
+        res = -1;
+    }
+
+    ovsdb_idl_txn_destroy(ovs_txn);
+    free(ports);
+    free(port_name);
+
+    return res;
+}
+
+static int
+create_patch_ports(struct controller_ctx *ctx, const struct ovsrec_bridge *bridge)
+{
+    size_t i;
+
+    for (i = 0; i < ctx->br_int->n_ports; i++) {
+        if (match_patch_port(ctx->br_int->ports[i], bridge)) {
+            /* Patch port already exists on br_int */
+            break;
+        }
+    }
+    if (i == ctx->br_int->n_ports &&
+            create_patch_port(ctx, ctx->br_int, bridge)) {
+        return -1;
+    }
+
+    for (i = 0; i < bridge->n_ports; i++) {
+        if (match_patch_port(bridge->ports[i], ctx->br_int)) {
+            /* Patch port already exists on bridge */
+            break;
+        }
+    }
+    if (i == bridge->n_ports &&
+            create_patch_port(ctx, bridge, ctx->br_int)) {
+        return -1;
+    }
+
+    return 0;
+}
+
 static int
 parse_bridge_mappings(struct controller_ctx *ctx, const char *bridge_mappings_)
 {
@@ -115,6 +222,13 @@ parse_bridge_mappings(struct controller_ctx *ctx, const char *bridge_mappings_)
             break;
         }
 
+        if (create_patch_ports(ctx, ovs_bridge)) {
+            VLOG_WARN("Failed to create patch ports between '%s' and '%s'",
+                    ctx->br_int_name, bridge);
+            res = -1;
+            break;
+        }
+
         smap_add(&ctx->localnet_mappings, network, bridge);
         smap_add(&ctx->bridge_mappings, bridge, network);
     }
-- 
2.4.3




More information about the dev mailing list